void IA_x86Details::computeTableAddress() { // Extract displacement from table insn Expression::Ptr displacementSrc; if(tableInsn.insn->getCategory() == c_BranchInsn) { Expression::Ptr op = tableInsn.insn->getOperand(0).getValue(); std::vector<Expression::Ptr> tmp; op->getChildren(tmp); if(tmp.empty()) { displacementSrc = op; } else { displacementSrc = tmp[0]; } } else { parsing_printf("\tcracking table instruction %s\n", tableInsn.insn->format().c_str()); std::vector<Expression::Ptr> tmp; Expression::Ptr op = tableInsn.insn->getOperand(1).getValue(); if(!op) { parsing_printf("\ttable insn BAD! (no second operand)\n"); return; } if(tableInsn.insn->getOperation().getID() != e_lea) { op->getChildren(tmp); if(tmp.empty()) { parsing_printf("\ttable insn BAD! (not LEA, second operand not a deref)\n"); return; } displacementSrc = tmp[0]; } else { displacementSrc = op; } } zeroAllGPRegisters z(tableInsn.addrOfInsn + tableInsn.insn->size()); displacementSrc->apply(&z); if(!z.isDefined()) { parsing_printf("\ttable insn: %s, displacement %s, bind of all GPRs FAILED\n", tableInsn.insn->format().c_str(), displacementSrc->format().c_str()); return; } else { tableInsn.addrFromInsn = z.getResult(); } parsing_printf("\ttableInsn.addrFromInsn set to 0x%lx\n",tableInsn.addrFromInsn); }
IA_IAPI::allInsns_t::const_iterator IA_x86Details::findTableInsn() { // Check whether the jump is our table insn! Expression::Ptr cft = currentBlock->curInsn()->getControlFlowTarget(); if(cft) { std::vector<Expression::Ptr> tmp; cft->getChildren(tmp); if(tmp.size() == 1) { Expression::Ptr cftAddr = tmp[0]; zeroAllGPRegisters z(currentBlock->current); cftAddr->apply(&z); parsing_printf("\tChecking indirect jump %s for table insn\n", currentBlock->curInsn()->format().c_str()); if(z.isDefined() && z.getResult()) { parsing_printf("\tAddress in jump\n"); return currentBlock->curInsnIter; } } } IA_IAPI::allInsns_t::const_iterator c = currentBlock->curInsnIter; while(!isTableInsn(c->second) && c != currentBlock->allInsns.begin()) { --c; } if(isTableInsn(c->second)) { return c; } return currentBlock->allInsns.end(); }