From 759beab9d34af8845e606e96e66060cbd970d871 Mon Sep 17 00:00:00 2001 From: Jason Hiser <jdh8d@virginia.edu> Date: Tue, 2 Apr 2019 10:33:23 -0400 Subject: [PATCH] made finding of switch dispatch part more robust against intermediate, unrelated move insns --- irdb-libs/ir_builders/fill_in_indtargs.cpp | 39 +++++++++++++++++----- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/irdb-libs/ir_builders/fill_in_indtargs.cpp b/irdb-libs/ir_builders/fill_in_indtargs.cpp index 4574be27d..70a5f9cf6 100644 --- a/irdb-libs/ir_builders/fill_in_indtargs.cpp +++ b/irdb-libs/ir_builders/fill_in_indtargs.cpp @@ -109,6 +109,16 @@ set<Instruction_t*> already_unpinned; long total_unpins=0; +/* + * Convert a reg id to a lower-case string + */ +string registerToSearchString(const RegisterID_t& reg) +{ + auto str=registerToString(reg); + transform(ALLOF(str), begin(str), ::tolower); + return str; + +} void range(VirtualOffset_t start, VirtualOffset_t end) { pair<VirtualOffset_t,VirtualOffset_t> foo(start,end); @@ -1813,19 +1823,35 @@ Note: Here the operands of the add are reversed, so lookup code was not finding const auto d7=DecodedInstruction_t::factory(I7); // Check if lea instruction is being used as add (scale=1, disp=0) - if(strstr(d7->getMnemonic().c_str(), "lea")) + if(d7->getMnemonic() == "lea") { if(!(d7->getOperand(1)->isMemory() )) return; if(!(d7->getOperand(1)->getScaleValue() == 1 && d7->getOperand(1)->getMemoryDisplacement() == 0)) return; } + + + // calculate the registers we need for the I6 backup. + const auto I7_reg0 = d7->getMnemonic() == "lea" ? d7->getOperand(1)->getBaseRegister() : d7->getOperand(0)->getRegNumber(); + const auto I7_reg0_32_str = registerToSearchString(RegisterID_t(rn_EAX+I7_reg0)); + const auto I7_reg0_64_str = registerToSearchString(RegisterID_t(rn_RAX+I7_reg0)); + const auto I7_reg1 = d7->getMnemonic() == "lea" ? d7->getOperand(1)->getIndexRegister() : d7->getOperand(1)->getRegNumber(); + const auto I7_reg1_32_str = registerToSearchString(RegisterID_t(rn_EAX+I7_reg1)); + const auto I7_reg1_64_str = registerToSearchString(RegisterID_t(rn_RAX+I7_reg1)); + + const auto I6_reg_str = string() + "(" + I7_reg0_32_str + "|" + + I7_reg0_64_str + "|" + + I7_reg1_32_str + "|" + + I7_reg1_64_str + ")"; + + // backup and find the instruction that's an movsxd before I7 /* * This instruction will contain the register names for * the index and the address of the base of the table */ - if(!backup_until("(mov|movsxd)", I6, I7)) + if(!backup_until("(mov|movsxd) "+I6_reg_str+",", I6, I7,string()+"^"+I6_reg_str+"$")) return; string lea_string="lea "; @@ -1918,7 +1944,7 @@ Note: Here the operands of the add are reversed, so lookup code was not finding // instruction address (and include the instruction's size, etc. // but, fix_calls has already removed this oddity so we can relocate // the instruction. - VirtualOffset_t D1=strtol(d5.getOperand(1)->getString().c_str(), nullptr, 0); + auto D1=VirtualOffset_t(strtol(d5.getOperand(1)->getString().c_str(), nullptr, 0)); D1+=I5_cur->getAddress()->getVirtualOffset(); // sometimes the lea only points at the image base, and the displacement field here is used for @@ -2074,13 +2100,10 @@ Note: Here the operands of the add are reversed, so lookup code was not finding // hack approved by an7s to convert a field from the index register to the actual 32-bit register from RegID_t const auto ireg_no = RegisterID_t(rn_EAX + d6_memop->getIndexRegister()); - auto ireg_str = registerToString(ireg_no); - transform(ALLOF(ireg_str), begin(ireg_str), ::tolower); + const auto ireg_str = registerToSearchString(ireg_no); const auto I6_2_opcode_str = string() + "movzx " + ireg_str + ","; - const auto stopif_reg_no = RegisterID_t(rn_RAX + d6_memop->getIndexRegister()); - auto stopif_reg_str = registerToString(stopif_reg_no); - transform(ALLOF(stopif_reg_str), begin(stopif_reg_str), ::tolower); + const auto stopif_reg_str = registerToSearchString(stopif_reg_no); const auto stop_if = string() + "^" + stopif_reg_str + "$"; auto I6_2 = (Instruction_t*)nullptr; -- GitLab