VOID Instruction(INS ins, void *v) { if( INS_IsRet(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_return, IARG_BRANCH_TAKEN, IARG_END); } else if( INS_IsSyscall(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_syscall, IARG_BRANCH_TAKEN, IARG_END); } else if (INS_IsDirectBranchOrCall(ins)) { if( INS_IsCall(ins) ) INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_call, IARG_BRANCH_TAKEN, IARG_END); else INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_branch, IARG_BRANCH_TAKEN, IARG_END); } else if( INS_IsIndirectBranchOrCall(ins) ) { if( INS_IsCall(ins) ) INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_call_indirect, IARG_BRANCH_TAKEN, IARG_END); else INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) inc_branch_indirect, IARG_BRANCH_TAKEN, IARG_END); } }
VOID Instruction(INS ins, VOID *v) { if (!init) Commence(); if (INS_IsCall(ins)) { if (INS_IsDirectCall(ins)) { ADDRINT addr = INS_DirectBranchOrCallTargetAddress(ins); FID fid = fn_lookup_by_address(addr); INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_call, IARG_CONST_CONTEXT, IARG_UINT32, fid, IARG_BOOL, false, IARG_END); } else { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_icall, IARG_CONST_CONTEXT, IARG_BRANCH_TARGET_ADDR, IARG_BOOL, false, IARG_END); } } if (INS_IsIndirectBranchOrCall(ins)) { if (!INS_IsCall(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_icall, IARG_CONST_CONTEXT, IARG_BRANCH_TARGET_ADDR, IARG_BOOL, true, IARG_END); } } if (INS_IsRet(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) fn_ret, IARG_CONST_CONTEXT, IARG_END); } return; }
VOID Instruction(INS ins, void *v) { // The subcases of direct branch and indirect branch are // broken into "call" or "not call". Call is for a subroutine // These are left as subcases in case the programmer wants // to extend the statistics to see how sub cases of branches behave if( INS_IsRet(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } else if( INS_IsSyscall(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } else if (INS_IsDirectBranchOrCall(ins)) { if( INS_IsCall(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } else { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } } else if( INS_IsIndirectBranchOrCall(ins) ) { if( INS_IsCall(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } else { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR) br_predict, IARG_INST_PTR, IARG_BRANCH_TAKEN, IARG_END); } } }
VOID Ins( INS ins, VOID *v ) { if (KnobDetach > 0 && scount > KnobDetach) return; if (KnobLog) { void *addr = Addrint2VoidStar(INS_Address(ins)); string disasm = INS_Disassemble(ins); PrintIns(addr, disasm.c_str()); } scount++; // call and return need also stack manipulation (see emu_stack.cpp) // conditional jumps need handling the condition (not supported yet) if (INS_IsCall(ins) || INS_IsRet(ins) || INS_Category(ins) == XED_CATEGORY_COND_BR) return; if (INS_IsIndirectBranchOrCall(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuIndJmp), IARG_BRANCH_TARGET_ADDR, IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg); INS_Delete(ins); } else if (INS_IsDirectBranchOrCall(ins)) { ADDRINT tgt = INS_DirectBranchOrCallTargetAddress(ins); INS_InsertDirectJump(ins, IPOINT_AFTER, tgt); INS_Delete(ins); } }
static void InstrumentIndirects(INS ins, VOID *) { if (INS_IsIndirectBranchOrCall(ins)) { Out << "Instrumenting Indirect branch or call at 0x" << std::hex << INS_Address(ins) << " " << INS_Disassemble(ins) << std::endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(RecordTargetAddrBefore), IARG_BRANCH_TARGET_ADDR, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(CheckPcBefore), IARG_ADDRINT, INS_Address(ins), IARG_CONTEXT, IARG_CONST_CONTEXT, IARG_INST_PTR, IARG_ADDRINT, GetDisassembly(ins), IARG_END); INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(CheckTargetAddrAfter), IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_ADDRINT, GetDisassembly(ins), IARG_END); INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(CheckPcAtBranchTarget), IARG_BRANCH_TARGET_ADDR, // is also expected CONTEXT PC IARG_ADDRINT, INS_Address(ins), // expected INST_PTR PC IARG_CONTEXT, IARG_CONST_CONTEXT, IARG_INST_PTR, IARG_ADDRINT, GetDisassembly(ins), IARG_END); } }
VOID Ins( INS ins, VOID *v ) { if (KnobDetach > 0 && scount > KnobDetach) return; if (KnobLog) { void *addr = Addrint2VoidStar(INS_Address(ins)); string disasm = INS_Disassemble(ins); PrintIns(addr, disasm.c_str()); } scount++; if (INS_Opcode(ins) == XED_ICLASS_PUSH) { if (INS_OperandIsImmediate(ins, 0)) { ADDRINT value = INS_OperandImmediate(ins, 0); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPushValue), IARG_REG_VALUE, REG_STACK_PTR, IARG_ADDRINT, value, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else if(INS_OperandIsReg(ins, 0)) { REG reg = INS_OperandReg(ins, 0); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPushValue), IARG_REG_VALUE, REG_STACK_PTR, IARG_REG_VALUE, reg, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else if(INS_OperandIsMemory(ins, 0)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPushMem), IARG_REG_VALUE, REG_STACK_PTR, IARG_MEMORYREAD_EA, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else { fprintf(stderr, "EmuPush: unsupported operand type (%p:'%s')\n", Addrint2VoidStar(INS_Address(ins)), INS_Disassemble(ins).c_str()); } } else if (INS_Opcode(ins) == XED_ICLASS_POP) { if(INS_OperandIsReg(ins, 0)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPopReg), IARG_REG_VALUE, REG_STACK_PTR, IARG_REG_REFERENCE, INS_OperandReg(ins, 0), IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else if(INS_OperandIsMemory(ins, 0)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuPopMem), IARG_REG_VALUE, REG_STACK_PTR, IARG_MEMORYWRITE_EA, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else { fprintf(stderr, "EmuPop: unsupported operand type (%p:'%s')\n", Addrint2VoidStar(INS_Address(ins)), INS_Disassemble(ins).c_str()); } } else if (INS_Opcode(ins) == XED_ICLASS_LEAVE) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuLeave), IARG_REG_VALUE, REG_STACK_PTR, IARG_REG_REFERENCE, REG_GBP, IARG_RETURN_REGS, REG_STACK_PTR, IARG_END); INS_Delete(ins); } else if (INS_IsCall(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuCall), IARG_ADDRINT, INS_NextAddress(ins), IARG_BRANCH_TARGET_ADDR, IARG_REG_REFERENCE, REG_STACK_PTR, IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg); INS_Delete(ins); } else if (INS_IsRet(ins)) { UINT64 imm = 0; if (INS_OperandCount(ins) > 0 && INS_OperandIsImmediate(ins, 0)) { imm = INS_OperandImmediate(ins, 0); } INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuRet), IARG_CALL_ORDER, CALL_ORDER_FIRST, IARG_REG_REFERENCE, REG_STACK_PTR, IARG_ADDRINT, (ADDRINT)imm, IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg); INS_Delete(ins); } else if (INS_IsIndirectBranchOrCall(ins)) { // This is not a call (it was checked before) so this is indirect jump INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(EmuIndJmp), IARG_BRANCH_TARGET_ADDR, IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_AFTER, scratchReg); INS_Delete(ins); } }