You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

217 lines
7.7 KiB

/*
* 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 <assert.h>
#include <stdio.h>
#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;
}