diff --git a/libIRDB/src/core/operand_cs.cpp b/libIRDB/src/core/operand_cs.cpp index c5a863494f171a80be903b57960e19486377d5ae..4e8aed104b81ccc5d2862bf7de4728c98fbcd96a 100644 --- a/libIRDB/src/core/operand_cs.cpp +++ b/libIRDB/src/core/operand_cs.cpp @@ -557,14 +557,49 @@ uint32_t DecodedOperandCapstone_t::getSegmentRegister() const set<string> write_only_operand_mnemonics= { + "seta", + "setae", + "setb", + "setbe", + "setc", "sete", + "setg", + "setge", + "setl", + "setle", + "setna", + "setnae", + "setnb", + "setnbe", + "setnc", "setne", + "setng", + "setnge", + "setnl", + "setnle", + "setno", + "setnp", + "setns", + "setnz", + "seto", + "setp", + "setpe", + "setpo", + "sets", + "setz", "fst", "fstp", "fist", "fistp" }; +set<string> write_first_operand_mnemonics= + { + "movups", + "ror", + "rol" + }; + set<string> read_only_operand_mnemonics= { // specal read-only op cases, rest are some form of compare. @@ -728,21 +763,37 @@ bool DecodedOperandCapstone_t::isWritten() const { const auto d=DecodedInstructionCapstone_t(my_insn); const auto d_mnemonic=d.getMnemonic(); + + // special case check: all operands are reads const auto room_it=read_only_operand_mnemonics.find(d_mnemonic); const auto in_room=(room_it!=end(read_only_operand_mnemonics)); if(in_room) return false; + + // special case check: all operands are writes const auto woom_it=write_only_operand_mnemonics.find(d_mnemonic); const auto in_woom=(woom_it!=end(write_only_operand_mnemonics)); if(in_woom) return true; + // special case check: first operand is writes + if(op_num==0) + { + const auto wfom_it=write_first_operand_mnemonics.find(d_mnemonic); + const auto in_wfom=(wfom_it!=end(write_first_operand_mnemonics)); + if(in_wfom) + return true; + } + + // special case of imul // imul has a 1-argument form which uses all it's operands if(d_mnemonic=="imul" && !d.hasOperand(1)) return false; + + + // default: use capstone's advice. const auto the_insn=static_cast<cs_insn*>(my_insn.get()); const auto &op = (the_insn->detail->x86.operands[op_num]); - return (op.access & CS_AC_WRITE)!=0; /* if(op_num!=0) diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp index e796cb2690325bae0b2527458bc2b1b0bbff7ce2..d4955e8fa130c4581110a92fcb65fee3bed1d517 100644 --- a/libIRDB/test/fill_in_indtargs.cpp +++ b/libIRDB/test/fill_in_indtargs.cpp @@ -655,11 +655,12 @@ I7: 08069391 <_gedit_app_ready+0x91> ret assert(disasm.getOperand(0).isRegister()); const auto I5_reg=disasm.getOperand(0).getString(); auto jmp_reg=string(); + auto add_reg=string(); // has to be a jump to a register now // backup and find the instruction that's an add before I8 - if(!backup_until(string()+"add "+I5_reg, I4, I5, I5_reg)) + if(!backup_until(string()+"add "+I5_reg+"|lea "+I5_reg, I4, I5, I5_reg)) { auto mov_insn=static_cast<Instruction_t*>(nullptr); if(!backup_until(string()+"mov "+I5_reg, mov_insn, I5, I5_reg)) @@ -673,15 +674,53 @@ I7: 08069391 <_gedit_app_ready+0x91> ret jmp_reg=mov_reg; } else - jmp_reg=I5_reg; + { + const auto d4=DecodedInstruction_t(I4); + if(d4.getMnemonic()=="lea") + { + const auto base_reg=d4.getOperand(1).getBaseRegister(); + switch(base_reg) + { + case 0/*REG0*/: jmp_reg="eax"; break; + case 1/*REG1*/: jmp_reg="ecx"; break; + case 2/*REG2*/: jmp_reg="edx"; break; + case 3/*REG3*/: jmp_reg="ebx"; break; + case 4/*REG4*/: jmp_reg="esp"; break; + case 5/*REG5*/: jmp_reg="ebp"; break; + case 6/*REG6*/: jmp_reg="esi"; break; + case 7/*REG7*/: jmp_reg="edi"; break; + default: + // no base register; + return; + } + const auto index_reg=d4.getOperand(1).getBaseRegister(); + switch(index_reg) + { + case 0/*REG0*/: add_reg="eax"; break; + case 1/*REG1*/: add_reg="ecx"; break; + case 2/*REG2*/: add_reg="edx"; break; + case 3/*REG3*/: add_reg="ebx"; break; + case 4/*REG4*/: add_reg="esp"; break; + case 5/*REG5*/: add_reg="ebp"; break; + case 6/*REG6*/: add_reg="esi"; break; + case 7/*REG7*/: add_reg="edi"; break; + default: + // no base register; + return; + } + } + else + { + jmp_reg=I5_reg; + if(!d4.getOperand(1).isRegister()) + return; + add_reg=d4.getOperand(1).getString(); + } + } - assert(jmp_reg!="" && I4!=nullptr); + assert(jmp_reg!="" && add_reg!="" && I4!=nullptr); - const auto d4=DecodedInstruction_t(I4); - if(!d4.getOperand(1).isRegister()) - return; - const auto add_reg=d4.getOperand(1).getString(); // backup and find the instruction that's an movsxd before I7 if(!backup_until(string()+"(mov "+jmp_reg+"|mov "+add_reg+")", I3, I4)) return;