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
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;
|
|
}
|