I am using Intel PIN to modify an instruction in my application. I am using the Safecopy() example from this link as a reference:
https://software.intel.com/sites/landingpage/pintool/docs/81205/Pin/html/index.html#SafeCopy
I have the following sample C program:
int main()
{
asm(".byte 0x16");
return 0;
}
0x16 is illegal in x86_64 and when I run the executable it displays the following error as expected:
Illegal instruction (core dumped)
I have a pintool which takes the above executable as input and modifies the illegal instruction 0x16 to do something else.
My Pintool is as follows:
#include "pin.H"
#include <iostream>
#include <fstream>
using namespace std;
KNOB<string> KnobOutputFile(KNOB_MODE_WRITEONCE, "pintool", "o", "test.out","This pin tool simulates ULI");
FILE * op;
//====================================================================
// Analysis Routines
//====================================================================
VOID analysis_routine(VOID *ip, UINT32 size)
{
fprintf(op,"16 came to analysis routine\n\n");
}
//====================================================================
// Instrumentation Routines
//====================================================================
VOID Instruction(INS ins, void *v)
{
UINT8 opcodeBytes[15];
UINT64 fetched = PIN_SafeCopy(&opcodeBytes[0],(void *)INS_Address(ins),INS_Size(ins));
if (fetched != INS_Size(ins))
fprintf(op,"\nBad\n");
else
{
if(opcodeBytes[0]==0x16)
{
fprintf(op,"\n16 came to instrumentation routine\n");
INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)analysis_routine, IARG_INST_PTR, IARG_UINT64, INS_Size(ins) , IARG_END);
INS_Delete(ins);
}
}
}
VOID Fini(INT32 code, VOID *v)
{
}
INT32 Usage() {
PIN_ERROR("This Pintool failed\n" + KNOB_BASE::StringKnobSummary() + "\n");
return -1;
}
int main(int argc, char *argv[])
{
op = fopen("test.out", "w");
if (PIN_Init(argc, argv))
return Usage();
PIN_InitSymbols();
INS_AddInstrumentFunction(Instruction, 0);
PIN_AddFiniFunction(Fini, 0);
PIN_StartProgram();
return 0;
}
According to my understanding the instrumentation routine Instruction is executed everytime a new instruction is encountered and according to my code, the analysis routine is called before the instruction is executed as I am using the IPOINT_BEFORE argument in my instrumentation function to invoke the analysis routine. I am thus checking for my opcode and if it is 0x16, then I am invoking my analysis routine and deleting my original instruction. Since the insturction was illegal and it has been deleted, my trace should proceed futher without any problems.
However even with this logic, it seems my illegal instruction is being executed and my program crashes and gives the same illegal instruction error. I am not able to understand the problem as I seem to be deleting the instruction before it executes and I am using the same example from the Pin tutorial.
Any ideas if I am invoking anything wrong? Also please correct me if I am wrong anywhere above. According to my understanding the instrumentation routine is invoked before the instruction executes and thus I can modify the instruction that time also. Please correct me if I am wrong.