void SATAddMapping(ATree *tree, void *map_from, void *map_to) { uchar n1, n2, n3, n4; //ATreeLocker.Lock(); SPLIT_ADDRESS((uint)map_from, n1, n2, n3, n4); tree = follow_tree(&tree->nodes[n1]); tree = follow_tree(&tree->nodes[n2]); tree = follow_tree(&tree->nodes[n3]); tree->answers[n4] = (uint)map_to; //ATreeLocker.Unlock(); }
//---------------------------------------------------------------------- bool jump_pattern_t::match(ea_t ea) { // unfortunately we can not do this in the constructor check[0x00] = &jump_pattern_t::jpi0; check[0x01] = &jump_pattern_t::jpi1; check[0x02] = &jump_pattern_t::jpi2; check[0x03] = &jump_pattern_t::jpi3; check[0x04] = &jump_pattern_t::jpi4; check[0x05] = &jump_pattern_t::jpi5; check[0x06] = &jump_pattern_t::jpi6; check[0x07] = &jump_pattern_t::jpi7; check[0x08] = &jump_pattern_t::jpi8; check[0x09] = &jump_pattern_t::jpi9; check[0x0a] = &jump_pattern_t::jpia; check[0x0b] = &jump_pattern_t::jpib; check[0x0c] = &jump_pattern_t::jpic; check[0x0d] = &jump_pattern_t::jpid; check[0x0e] = &jump_pattern_t::jpie; check[0x0f] = &jump_pattern_t::jpif; memset(skip, 0, sizeof(skip)); memset(eas, -1, sizeof(eas)); memset(r, -1, sizeof(r)); eas[0] = ea; failed = false; func_t *pfn = get_fchunk(ea); if ( pfn == NULL ) pfn = get_prev_fchunk(ea); minea = pfn != NULL ? pfn->startEA : getseg(ea)->startEA; if ( !(this->*check[0])() ) return false; while ( *roots ) { memset(spoiled, 0, sizeof(spoiled)); if ( !follow_tree(eas[0], *roots++) || failed ) return false; } ea_t start = eas[0]; for ( int i=1; i < qnumber(eas); i++ ) start = qmin(start, eas[i]); si.startea = start; return !failed; }
//---------------------------------------------------------------------- bool jump_pattern_t::follow_tree(ea_t ea, int n) { if ( n == 0 ) return true; int rsaved[sizeof(r)]; bool ssaved[sizeof(spoiled)]; memcpy(rsaved, r, sizeof(r)); memcpy(ssaved, spoiled, sizeof(spoiled)); bool success = false; if ( n < 0 ) { success = true; n = -n; } jmsg("follow_tree(%a, %d)\n", ea, n); if ( !skip[n] ) { if ( eas[n] == BADADDR ) { cmd.ea = ea; bool found_insn = false; while ( true ) { if ( cmd.ea < minea ) break; farref = false; ea_t prev = BADADDR; if ( allow_noflows || isFlow(get_flags_novalue(cmd.ea)) ) prev = decode_prev_insn(cmd.ea); if ( prev == BADADDR ) { if ( !allow_farrefs ) break; ea_t cur_addr = cmd.ea; if ( decode_preceding_insn(cmd.ea, &farref) == BADADDR ) break; // skip branches which are used to glue blocks together if ( farref && is_branch_to(cur_addr) ) continue; } if ( handle_mov() ) continue; if ( (this->*check[n])() ) { found_insn = true; break; } if ( failed ) return false; jmsg("%a: can't be %d.", cmd.ea, n); jmsg(" rA=%d%s rB=%d%s rC=%d%s rD=%d%s rE=%d%s\n", r[1], spoiled[1] ? "*" : "", r[2], spoiled[2] ? "*" : "", r[3], spoiled[3] ? "*" : "", r[4], spoiled[4] ? "*" : "", r[5], spoiled[5] ? "*" : ""); check_spoiled(); } if ( !found_insn ) { memcpy(r, rsaved, sizeof(r)); if ( success ) goto SUCC; return false; } eas[n] = cmd.ea; } if ( eas[n] >= ea ) { jmsg("%a: depends on %a\n", ea, eas[n]); return success; } ea = eas[n]; jmsg("%a: found %d\n", cmd.ea, n); } SUCC: if ( depends[n][0] && !follow_tree(ea, depends[n][0]) ) return success; if ( depends[n][1] && !follow_tree(ea, depends[n][1]) ) return success; jmsg("follow_tree(%d) - ok\n", n); memcpy(spoiled, ssaved, sizeof(spoiled)); return true; }