VOID RewriteBases(INS ins, BOOL * live) { for (UINT32 i = 0; i < INS_OperandCount(ins); i++) { if (!INS_OperandIsMemory(ins, i)) continue; if (INS_OperandMemoryIndexReg(ins, i) != REG_INVALID()) { CheckEffectiveAddress(ins); return; } REG baseReg = INS_OperandMemoryBaseReg(ins, i); // If no basereg is used, then it must be an absolute address if (baseReg == REG_INVALID()) continue; // No need to rewrite stack references if (baseReg == REG_ESP) continue; // If we reach this point, we have an instruction that // must be rewritten, but if the memory operand is // implicit, we can't rewrite the base register if (INS_OperandIsImplicit(ins, i)) { CheckEffectiveAddress(ins); return; } REG shadowReg = ShadowReg(baseReg); INS_OperandMemorySetBaseReg(ins, i, shadowReg); // Remember to write the shadow register live[RegIndex(baseReg)] = true; } }
VOID Instruction(INS ins, VOID *v) { INT32 count = INS_OperandCount(ins); for (INT32 i = 0; i < 5; i++) { if (i >= count) { dis << " "; continue; } else if (INS_OperandIsAddressGenerator(ins, i)) dis << "AGN"; else if (INS_OperandIsMemory(ins, i)) { dis << "MEM"; dis << " " << REG_StringShort(INS_OperandMemoryBaseReg(ins, i)); } else if (INS_OperandIsReg(ins, i)) dis << "REG"; else if (INS_OperandIsImmediate(ins, i)) dis << "IMM"; else if (INS_OperandIsDisplacement(ins, i)) dis << "DSP"; else dis << "XXX"; if (INS_OperandIsImplicit(ins, i)) dis << ":IMP "; else dis << " "; } dis << INS_Disassemble(ins) << endl; }
VOID Instruction(INS ins, VOID *v){ /** * INS_InsertCall(INS ins, IPOINT action, AFUNPTR funptr, ...) * * insert a call to 'docount' relative to instruction 'ins' * * ins: instruction to instrument * action: specifies before/after, etc. IPOINT_BEFORE is always valid for all instructions. * funptr: insert a call to funptr. * ...: list of arguments to pass funptr, terminated with IARG_END */ //INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)stat_ins, IARG_END); InsCount ++; //string ins_cat = CATEGORY_StringShort(INS_Category(ins)); int num_ops = INS_OperandCount(ins); //total #operands int memOperands = INS_MemoryOperandCount(ins); //#mem_operands string op_string = ""; //string to record all operands stringstream sstm; //string stream int num_mems = 0; for(int ii=0; ii<num_ops; ii++){ //iterate each operand if(INS_OperandIsImmediate(ins, ii)){ //immediate auto value = INS_OperandImmediate(ins, ii); sstm.str(""); //empty sstm << "$" << value; op_string += " " + sstm.str(); } else if(INS_OperandIsReg(ins, ii)){ //register auto reg = REG_StringShort(INS_OperandReg(ins, ii)); sstm.str(""); sstm << "%" << reg; op_string += " " + sstm.str(); } else if(INS_OperandIsMemory(ins, ii) && memOperands>0){ //memory string mem_type = "memXX"; if(INS_MemoryOperandIsRead(ins, num_mems)) { mem_type = "memR"; } else if(INS_MemoryOperandIsWritten(ins, num_mems)) { mem_type = "memW"; } if(INS_MemoryOperandIsRead(ins, num_mems) && INS_MemoryOperandIsWritten(ins, num_mems)) { mem_type = "memRW"; } ++ num_mems; op_string += " " + mem_type; //true if this operand is a memory reference, //Note: this does not include LEA operands. } else if(INS_OperandIsMemory(ins, ii) && memOperands==0){ //NOP assert(INS_IsNop(ins)); } else { //TRUE if memory operand uses predefined base register and this register can not be changed //Example: movs ds:(esi), es:(edi) There are two fixed operands string other_type = ""; if(INS_OperandIsFixedMemop(ins, ii)) other_type = "FM"; //true if this operand is a displacement (e.g. branch offset) else if(INS_OperandIsBranchDisplacement(ins, ii)) other_type = "BD"; //true if this operand is implied by the opcode (e.g. the stack write in a push instruction) else if(INS_OperandIsImplicit(ins, ii)) other_type = "IM"; else { assert(INS_IsLea(ins)); other_type = "lea"; } op_string += " " + other_type; } } assert(num_mems == memOperands); assert(num_ops <= 6); //record ins INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)record_ins, IARG_THREAD_ID, IARG_UINT32, INS_Opcode(ins), IARG_UINT32, num_ops, IARG_PTR, new string(op_string), IARG_END); if (INS_IsXchg(ins) && INS_OperandReg(ins, 0)==REG_BX && INS_OperandReg(ins, 1)==REG_BX) { //INS_InsertPredictedCall() is used to call analysis functions. //This API function prevents pollution of the memory analysis by calling an analysis function only if a particular //instruction is actualy executed, i.e., only if the instruction is executed. INS_InsertPredicatedCall(ins, IPOINT_BEFORE, (AFUNPTR)handleHook, IARG_THREAD_ID, IARG_REG_VALUE, REG_GAX, #ifdef TARGET_IA32 IARG_REG_VALUE, REG_GDX, #else IARG_REG_VALUE, REG_GBX, #endif IARG_REG_VALUE, REG_GCX, IARG_END); } }