From 940246cacc658c236d9a93f79afc2ffffa09e371 Mon Sep 17 00:00:00 2001 From: comex Date: Tue, 15 Mar 2011 16:15:01 -0400 Subject: [PATCH] minimization --- dmini.c | 124 -------------------------------------------------------- 1 file changed, 124 deletions(-) diff --git a/dmini.c b/dmini.c index 415f693..d137bea 100644 --- a/dmini.c +++ b/dmini.c @@ -25,122 +25,6 @@ static int position_of_nth_one(uint32_t number, int n) { } -// similar to below, but no alignment restriction -// must include r0, lr, and pc, but not r7 - -void find_second_ldm(struct binary *binary, uint32_t valid_conds, int reg, addr_t *addrp, int *num_before_r0, int *num_after_r0) { - //printf("reg=%d\n", reg); - range_t range; - for(int i = 0; (range = b_nth_segment(binary, i)).binary; i++) { - if(!(binary->dyld_mappings[i].sfm_init_prot & PROT_EXEC)) continue; - uint32_t *p = rangeconv(range).start; - for(addr_t addr = range.start; addr + 4 <= range.start + range.size; p++, addr += 4) { - uint32_t val = *p; - uint32_t cond = ((val & 0xf0000000) >> 28); - if(cond == 15 || (1u << (2*cond)) != (valid_conds & (3 << (2*cond)))) { - continue; - } - - int offset; - if((val & 0xfd0c081) == 0x890c001) { - offset = 0; - } else if((val & 0xfd0c081) == 0x990c001) { - offset = 1; - } else { - continue; - } - - uint32_t rn = (val & 0xf0000) >> 16; - if((int) rn != reg) { - continue; - } - - *addrp = addr; - *num_before_r0 = offset; - *num_after_r0 = count_ones(val & 0x3f7e); - return; - } - } - die("didn't find second ldm /anywhere/"); -} - -// ldmi[ab] r[05]!?, ... -// - aligned to 0x1000 -// - includes pc, but not r7 -// - PC is at position 3-5 -// each set of two bits in valid_conds is: -// 0 - known false -// 1 - known true -// 2 - unknown - -void find_kernel_ldm(struct binary *binary, uint32_t valid_conds, addr_t *addrp, uint32_t *condsp, int *regp) { - range_t range; - uint32_t my_valid_conds = valid_conds; - for(int i = 0; (range = b_nth_segment(binary, i)).binary; i++) { - if(!(binary->dyld_mappings[i].sfm_init_prot & PROT_EXEC)) continue; - char *p = rangeconv(range).start; - addr_t addr = (range.start + 0xfff) & ~0xfff; - while(addr + 4 <= range.start + range.size) { - if((addr & 0xfff) == 0) { - my_valid_conds = valid_conds; - } - uint32_t val = *((uint32_t *) (p + addr - range.start)); - uint32_t cond = ((val & 0xf0000000) >> 28); - - if(cond != 15 && 0 == (my_valid_conds & (3 << (2*cond)))) { - goto harmless; - } else if(cond != 15 && !(val & 0xc000000) && (val & 0xe100000) != 0xc100000) { // data processing, but not LDC - uint32_t rd = (val & 0xf000) >> 12; - if(rd != 0 && rd != 13 && rd != 15) { - if(!(val & (1 << 20))) my_valid_conds = 0x1aaaaaaa; // AL known 1, others unknown - goto harmless; - } else if(rd == 0) { - uint32_t op = ((val & 0x1f00000) >> 20); - if(op == 17 || op == 19 || op == 21 || op == 23) { - my_valid_conds = 0x1aaaaaaa; - goto harmless; - } - } - } - - if(cond == 15 || (1u << (2*cond)) != (my_valid_conds & (3 << (2*cond)))) { - goto nope; - } - - - // 0xfdf to be strict about user registers, 0xf9f otherwise - int offset; - if((val & 0xfd08080) == 0x8908000) { - // ldmia - offset = 0; - } else if((val & 0xfd08080) == 0x9908000) { - // ldmib - offset = 1; - } else { - goto nope; - } - - uint32_t rn = (val & 0xf0000) >> 16; - uint32_t reglist = val & 0x7f7f; - int ones = count_ones(reglist) + offset; // ones = offset of PC - - //printf("addr=%x rn=%u ones=%d val=%x\n", addr, rn, ones, val); - if(rn != 0 && rn != 5) goto nope; - - //printf("rn=%u ones=%d\n", rn, ones); - if(ones < 3 || ones > 5) goto nope; - - *addrp = addr; - *condsp = my_valid_conds; - *regp = position_of_nth_one(reglist, 2); - return; - - nope: /*printf("%08x nope\n", addr);*/ addr = (addr + 0x1000) & ~0xfff; continue; - harmless: /*printf("%08x harmless\n", addr);*/ addr += 4; continue; - } - } - die("didn't find ldm /anywhere/"); -} void main_loop() { @@ -165,14 +49,6 @@ void main_loop() { } else if(mode == 3) { b_dyldcache_load_macho(&binary, arg); result = 0; - } else if(mode == 4) { - addr_t first, second; int reg, num_before_r0, num_after_r0; - uint32_t conds = (uint32_t) strtoll(arg, NULL, 16); - find_kernel_ldm(&binary, conds, &first, &conds, ®); - find_second_ldm(&binary, conds, reg, &second, &num_before_r0, &num_after_r0); - printf("+ %x %x %x %x\n", first, second, num_before_r0, num_after_r0); - fflush(stdout); - continue; } else die("mode?"); printf("+ %x\n", result);