/* * Copyright 2002-2019 Intel Corporation. * * This software is provided to you as Sample Source Code as defined in the accompanying * End User License Agreement for the Intel(R) Software Development Products ("Agreement") * section 1.L. * * This software and the related documents are provided as is, with no express or implied * warranties, other than those that are expressly stated in the License. */ #include #include #include "pin.H" ADDRINT globalIpAtReadBefore=0; ADDRINT globalEaReadBefore=0; ADDRINT globalRegInstPtrAtReadBefore=0; ADDRINT globalIpOfReadRecordedAtInstrumentationTime=0; ADDRINT globalRegInstPtrAtReadAfter = 0; int globalReadInsSize=0; ADDRINT globalIpAtWriteBefore=0; ADDRINT globalEaWriteBefore=0; ADDRINT globalRegInstPtrAtWriteBefore=0; ADDRINT globalIpOfWriteRecordedAtInstrumentationTime=0; ADDRINT globalRegInstPtrAtWriteAfter = 0; int globalWriteInsSize=0; BOOL instrumentedReadFromIpWithNoOffset = FALSE; BOOL instrumentedWriteFromIpWithNoOffset = FALSE; static void IpReadBefore(ADDRINT ip, ADDRINT ea, ADDRINT rip) { globalIpAtReadBefore = ip; globalEaReadBefore = ea; globalRegInstPtrAtReadBefore = rip; } static void IpWriteBefore(ADDRINT ip, ADDRINT ea, ADDRINT rip) { globalIpAtWriteBefore = ip; globalEaWriteBefore = ea; globalRegInstPtrAtWriteBefore = rip; } static void IpReadAfter(ADDRINT rip) { globalRegInstPtrAtReadAfter = rip; } static void IpWriteAfter(ADDRINT rip) { globalRegInstPtrAtWriteAfter = rip; } VOID Instruction(INS ins, VOID *v) { if (INS_IsMemoryRead(ins) && !instrumentedReadFromIpWithNoOffset) { BOOL readsFromIpWithNoOffset = FALSE; for (UINT32 i = 0; i < INS_OperandCount(ins); i++) { if (!INS_OperandIsMemory(ins, i)) continue; if (INS_OperandMemoryBaseReg(ins, i) == REG_INST_PTR && INS_OperandMemoryDisplacement(ins, i)==0) { readsFromIpWithNoOffset = TRUE; break; } } if (!readsFromIpWithNoOffset) { return; } instrumentedReadFromIpWithNoOffset = TRUE; // only instrument one of these printf ("Instrumenting [ip] read %p %s\n", INS_Address(ins), INS_Disassemble(ins).c_str()); fflush (stdout); globalIpOfReadRecordedAtInstrumentationTime = INS_Address(ins); globalReadInsSize = INS_Size(ins); INS_InsertCall(ins,IPOINT_BEFORE, (AFUNPTR)IpReadBefore, IARG_INST_PTR, IARG_MEMORYREAD_EA, IARG_REG_VALUE, REG_INST_PTR, IARG_END); INS_InsertCall(ins,IPOINT_AFTER, (AFUNPTR)IpReadAfter, IARG_REG_VALUE, REG_INST_PTR, IARG_END); } else if (INS_IsMemoryWrite(ins) && !instrumentedWriteFromIpWithNoOffset) { /* const xed_decoded_inst_t* xedd = INS_XedDec(ins); xed_reg_enum_t breg1 = xed_decoded_inst_get_base_reg(xedd,0); if (breg1== XED_REG_RIP) { readsFromIpWithNoOffset = TRUE; } */ BOOL writesFromIpWithNoOffset = FALSE; for (UINT32 i = 0; i < INS_OperandCount(ins); i++) { if (!INS_OperandIsMemory(ins, i)) continue; if (INS_OperandMemoryBaseReg(ins, i) == REG_INST_PTR && INS_OperandMemoryDisplacement(ins, i)==0) { writesFromIpWithNoOffset = TRUE; break; } } if (!writesFromIpWithNoOffset) { return; } instrumentedReadFromIpWithNoOffset = TRUE; // only instrument one of these printf ("Instrumenting [ip] write %p %s\n", INS_Address(ins), INS_Disassemble(ins).c_str()); fflush (stdout); globalIpOfWriteRecordedAtInstrumentationTime = INS_Address(ins); globalWriteInsSize = INS_Size(ins); INS_InsertCall(ins,IPOINT_BEFORE, (AFUNPTR)IpWriteBefore, IARG_INST_PTR, IARG_MEMORYWRITE_EA, IARG_REG_VALUE, REG_INST_PTR, IARG_END); INS_InsertCall(ins,IPOINT_AFTER, (AFUNPTR)IpWriteAfter, IARG_REG_VALUE, REG_INST_PTR, IARG_END); } } VOID PrintFinalInfo(INT32 code, VOID *v) { printf ("globalIpAtReadBefore %p globalEaReadBefore %p globalRegInstPtrAtReadBefore %p globalIpOfReadRecordedAtInstrumentationTime %p globalRegInstPtrAtReadAfter %p globalReadInsSize %d\n", globalIpAtReadBefore, globalEaReadBefore, globalRegInstPtrAtReadBefore, globalIpOfReadRecordedAtInstrumentationTime, globalRegInstPtrAtReadAfter, globalReadInsSize); printf ("globalIpAtWriteBefore %p globalEaWriteBefore %p globalRegInstPtrAtWriteBefore %p globalIpOfWriteRecordedAtInstrumentationTime %p globalRegInstPtrAtWriteAfter %p globalWriteInsSize %d\n", globalIpAtWriteBefore, globalEaWriteBefore, globalRegInstPtrAtWriteBefore, globalIpOfWriteRecordedAtInstrumentationTime, globalRegInstPtrAtWriteAfter, globalWriteInsSize); BOOL hadError = FALSE; if (globalIpAtReadBefore==0 || globalEaReadBefore==0 || globalRegInstPtrAtReadBefore==0 || globalIpOfReadRecordedAtInstrumentationTime==0 || globalReadInsSize==0) { printf ("Error on handling read from [REG_INST_PTR] appears to not have been instrumented\n"); hadError = TRUE; } if (globalIpAtWriteBefore==0 || globalEaWriteBefore==0 || globalRegInstPtrAtWriteBefore==0 || globalIpOfWriteRecordedAtInstrumentationTime==0 || globalWriteInsSize==0) { printf ("Error on handling write to [REG_INST_PTR] appears to not have been instrumented\n"); hadError = TRUE; } if (globalIpAtReadBefore != globalRegInstPtrAtReadBefore || globalIpAtReadBefore != globalIpOfReadRecordedAtInstrumentationTime) { printf ("Error on handling read from [REG_INST_PTR] appears that the rip value received is not correct\n"); hadError = TRUE; } if (globalIpAtWriteBefore != globalRegInstPtrAtWriteBefore || globalIpAtWriteBefore != globalIpOfWriteRecordedAtInstrumentationTime) { printf ("Error on handling write to [REG_INST_PTR] appears that the rip value received is not correct\n"); hadError = TRUE; } if (globalEaReadBefore != globalIpAtReadBefore+globalReadInsSize) { printf ("Error on handling read from [REG_INST_PTR] appears that the effective address value received is not correct\n"); hadError = TRUE; } if (globalEaWriteBefore != globalIpAtWriteBefore+globalWriteInsSize) { printf ("Error on handling write to [REG_INST_PTR] appears that the effective address value received is not correct\n"); hadError = TRUE; } if (globalRegInstPtrAtReadAfter != globalIpAtReadBefore+globalReadInsSize) { printf ("Error on handling read from [REG_INST_PTR] appears that REG_INST_PTR received on the IPOINT_AFTER is not correct\n"); hadError = TRUE; } if (globalRegInstPtrAtWriteAfter != globalIpAtWriteBefore+globalWriteInsSize) { printf ("Error on handling write to [REG_INST_PTR] appears that REG_INST_PTR received on the IPOINT_AFTER is not correct\n"); hadError = TRUE; } if (!hadError) { printf ("SUCCESS\n"); } fflush(stdout); } int main(int argc, char * argv[]) { PIN_Init(argc, argv); INS_AddInstrumentFunction(Instruction, 0); // Register a routine that gets called when the program ends PIN_AddFiniFunction(PrintFinalInfo, 0); PIN_StartProgram(); return 0; }