VOID Trace (TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { xed_iclass_enum_t iclass1 = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); if (iclass1 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(ins))) { xed_iclass_enum_t iclass2 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(ins))); if (iclass2 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(INS_Next(ins)))) { xed_iclass_enum_t iclass3 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(INS_Next(ins)))); if (iclass3 == XED_ICLASS_FLD1) { printf ("found fld1 sequence at %x\n", INS_Address(INS_Next(INS_Next(ins)))); { INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_AFTER, AFUNPTR(CallToFldzToTop3), IARG_END); printf ("Inserted call1 to FldzToTop3 after instruction at %x\n", INS_Address(INS_Next(INS_Next(ins)))); } } } } } } }
VOID Trace (TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { xed_iclass_enum_t iclass1 = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); if (iclass1 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(ins))) { xed_iclass_enum_t iclass2 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(ins))); if (iclass2 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(INS_Next(ins)))) { xed_iclass_enum_t iclass3 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(INS_Next(ins)))); if (iclass3 == XED_ICLASS_FLD1) { printf ("tool: found fld1 sequence at %p\n", (void *)INS_Address(INS_Next(INS_Next(ins)))); fflush (stdout); // Insert an analysis call that will cause the xmm scratch registers to be spilled INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_AFTER, (AFUNPTR)SetXmmScratchesFun, IARG_END); return; } } } } } }
VOID Trace (TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { xed_iclass_enum_t iclass1 = static_cast<xed_iclass_enum_t>(INS_Opcode(ins)); if (iclass1 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(ins))) { xed_iclass_enum_t iclass2 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(ins))); if (iclass2 == XED_ICLASS_FLD1 && INS_Valid(INS_Next(INS_Next(ins)))) { xed_iclass_enum_t iclass3 = static_cast<xed_iclass_enum_t>(INS_Opcode(INS_Next(INS_Next(ins)))); if (iclass3 == XED_ICLASS_FLD1) { printf ("found fld1 sequence at %lx\n", (unsigned long)(INS_Address(INS_Next(INS_Next(ins))))); if (testNum == 0) { INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_AFTER, AFUNPTR(CallToUnMaskZeroDivideInMxcsr), IARG_END); printf ("Inserted call1 to UnMaskZeroDivideInMxcsr after instruction at %lx\n", (unsigned long)(INS_Address(INS_Next(INS_Next(ins))))); testNum++; } return; } } } } } }
VOID Image(IMG img, VOID * v) { if (strstr (IMG_Name(img).c_str(), "flags_at_analysis_app")==NULL) { return; } for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { // Prepare for processing of RTN, an RTN is not broken up into BBLs, // it is merely a sequence of INSs RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_Opcode(ins)==XED_ICLASS_POPF || INS_Opcode(ins)==XED_ICLASS_POPFD || INS_Opcode(ins)==XED_ICLASS_POPFQ) { // popf is the marker printf ("found popf in rtn %s\n", RTN_Name(rtn).c_str()); if (!INS_Valid(INS_Next(ins)) || !INS_Valid(INS_Next(INS_Next(ins)))) { printf ("wrong popf marker found\n"); exit (-1); } printf ("next ins should be cmp al, 0x81 it is %s\n", INS_Disassemble(INS_Next(ins)).c_str()); printf ("next ins should be xor ecx, ecx it is %s\n", INS_Disassemble(INS_Next(INS_Next(ins))).c_str()); // Insert analysis calls to read the value of the flags register just after the cmp al, 0x81 - the OF flag should be set INS_InsertIfCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)IfReturnTrue, IARG_INST_PTR, IARG_END); INS_InsertThenCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)ThenFunc, IARG_REG_VALUE, REG_GFLAGS, IARG_END); INS_InsertCall(INS_Next(INS_Next(ins)), IPOINT_BEFORE, (AFUNPTR)AnalysisFunc, IARG_REG_VALUE, REG_GFLAGS, IARG_END); } } // to preserve space, release data associated with RTN after we have processed it RTN_Close(rtn); } } }
INT32 RecordRegisters(BBL bbl, UINT16 * stats, UINT32 max_stats) { UINT32 count = 0; for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { if (count >= max_stats) { cerr << "Too many stats in this block" << endl; exit(1); } bool rmem = INS_IsMemoryRead(ins) || INS_HasMemoryRead2(ins); bool wmem = INS_IsMemoryWrite(ins); bool rw_mem = rmem & wmem; if (rw_mem) stats[count++] = PATTERN_MEM_RW; else if (rmem) stats[count++] = PATTERN_MEM_R; else if (wmem) stats[count++] = PATTERN_MEM_W; else if (INS_SegmentRegPrefix(ins) != REG_INVALID()) stats[count++] = PATTERN_NO_MEM_LIES; else stats[count++] = PATTERN_NO_MEM; } stats[count++] = 0; return count; }
bool TraceManager::IsNormal(RTN myrtn) { BBL my_bbl=RTN_BblTail(myrtn); if(BBL_Valid(my_bbl)) { INS my_ins=BBL_InsTail(my_bbl); while(INS_Valid(my_ins)) { if(INS_IsRet(my_ins)) { //cerr<<"Normal Routine::"<<RTN_Name(myrtn)<<endl; return true; } my_ins=INS_Prev(my_ins); } /*if(INS_IsBranch(my_ins)|| INS_IsNop(my_ins)) { cerr<<"!!!Abnormal Routine::"<<RTN_Name(myrtn)<<endl; return false; } my_bbl=BBL_Prev(my_bbl); */ } //cerr<<"!!!!Abnormal Routine::"<<RTN_Name(myrtn)<<endl; return false; }
VOID Image(IMG img, VOID * v) { for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if( INS_IsPredicated(ins) ) GlobalStatsStatic.predicated[ INS_Category(ins) ]++; else GlobalStatsStatic.unpredicated[ INS_Category(ins) ]++; } RTN_Close(rtn); } } if( KnobProfileStaticOnly.Value() ) { Fini(0,0); exit(0); } }
// Pin calls this function every time a new rtn is executed VOID Routine(RTN rtn, VOID *v) { // Allocate a counter for this routine RTN_COUNT * rc = new RTN_COUNT; // The RTN goes away when the image is unloaded, so save it now // because we need it in the fini rc->_name = RTN_Name(rtn); rc->_image = StripPath(IMG_Name(SEC_Img(RTN_Sec(rtn))).c_str()); rc->_address = RTN_Address(rtn); rc->_icount = 0; rc->_rtnCount = 0; // Add to list of routines rc->_next = RtnList; RtnList = rc; RTN_Open(rtn); // Insert a call at the entry point of a routine to increment the call count RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)docount, IARG_PTR, &(rc->_rtnCount), IARG_END); // For each instruction of the routine for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { // Insert a call to docount to increment the instruction counter for this rtn INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)docount, IARG_PTR, &(rc->_icount), IARG_END); } RTN_Close(rtn); }
// Pin calls this function every time a new basic block is encountered // It inserts a call to docount VOID Trace(TRACE trace, VOID *v) { // Visit every basic block in the trace for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsMemoryRead(ins)) { INS_InsertIfCall(ins, IPOINT_BEFORE, (AFUNPTR)ReadAlways, IARG_MEMORYREAD_EA, IARG_END); INS_InsertThenCall(ins, IPOINT_BEFORE, (AFUNPTR)ReadRare, IARG_MEMORYREAD_EA, IARG_END); } } // Always()->Rare() are partially inlined BBL_InsertIfCall(bbl, IPOINT_BEFORE, (AFUNPTR)Always, IARG_END); BBL_InsertThenCall(bbl, IPOINT_BEFORE, (AFUNPTR)Rare, IARG_END); // Always()->Rare() are partially inlined BBL_InsertIfCall(bbl, IPOINT_BEFORE, (AFUNPTR)AlwaysNoinline, IARG_END); BBL_InsertThenCall(bbl, IPOINT_BEFORE, (AFUNPTR)RareNoinline, IARG_END); // Noinline() is not inlined BBL_InsertCall(bbl, IPOINT_BEFORE, (AFUNPTR)Noinline, IARG_END); } }
VOID PolymorphicCodeHandlerModule::inspectTrace(TRACE trace){ // set the range of address in which the current trace resides this->trace_head = TRACE_Address(trace); this->trace_tail = trace_head + TRACE_Size(trace); for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { // for ech instruction we have to check if it has been overwritten by a previous instruction of the current trace (polimiorfic code detection) INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(checkIfWrittenAddress), IARG_INST_PTR, IARG_CONTEXT, IARG_UINT32, INS_Size(ins), IARG_PTR, this, IARG_END); for (UINT32 op = 0; op<INS_MemoryOperandCount(ins); op++) { if(INS_MemoryOperandIsWritten(ins,op)){ // for each write operation we have to check if the traget address is inside the current trace (attempt to write polimorfic code) INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(polimorficCodeHandler), IARG_INST_PTR, IARG_MEMORYOP_EA, op, IARG_PTR, this, IARG_END); } } } } }
// Offset the addressing of the first "or" instruction back by 4 bytes. static VOID modifyAddressing (RTN rtn) { for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_Opcode(ins) == XED_ICLASS_OR) { printf ("Rewriting address of ins\n%x: %s\n", INS_Address(ins), INS_Disassemble(ins).c_str()); // pass the original memory address accessed by the app instruction (i.e. before the rewrite) to AddrValueA INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(AddrValueA), IARG_MEMORYOP_EA, 0, IARG_END); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(returnValueMinus4), IARG_MEMORYOP_EA, 0, IARG_RETURN_REGS, scratchReg, IARG_END); INS_RewriteMemoryOperand(ins, 0, scratchReg); // pass the original memory address accessed by the app instruction (i.e. before the rewrite) to AddrValueB INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(AddrValueB), IARG_MEMORYOP_EA, 0, IARG_END); instrumentationCount++; return; } } }
static VOID Image(IMG img, VOID *v) { RTN rtn = RTN_FindByName(img, watch_rtn); if (!RTN_Valid(rtn)) { return; } printf("Instrumenting %s at %p\n", watch_rtn, reinterpret_cast<void *>(RTN_Address(rtn))); RTN_Open(rtn); INS ins = RTN_InsHeadOnly(rtn); ASSERTX (INS_Valid(ins)); // version_reg is used to select the version, use the first // argument of watch_rtn to set it INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(select_version), IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_REG_VALUE, version_reg, IARG_RETURN_REGS, version_reg, IARG_END); // Note that the version instrumentation will occur before any // instrumentation done on this ins from Trace or Instruction // instrumentation time callbacks INS_InsertVersionCase(ins, version_reg, 10, VERSION_1, IARG_END); INS_InsertVersionCase(ins, version_reg, 20, VERSION_2, IARG_END); RTN_Close(rtn); }
VOID Trace(TRACE trace, VOID *v) { BOOL rewrite = false; for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { // If we see an instruction that needs rewriting, then rewrite all if (SwizzleRefs.find(INS_Address(ins)) != SwizzleRefs.end()) rewrite = true; if (rewrite) { // If we suspect this instruction needs to be swizzled, generate safe, but slow code RewriteIns(ins); } else { // Generate code to check if swizzling is needed, but not do it CheckIns(ins, TRACE_Address(trace)); } } } }
/* * Instrumentation-time routine looking for the routine we'd like to instrument. */ static VOID ImageLoad(IMG img, VOID * v) { if (IMG_IsMainExecutable(img)) { *outFile << "In main application image" << endl; // Search for the assembly routine in the application RTN AsmRtn = RTN_FindByName(img, "operImmCmds"); if (!RTN_Valid(AsmRtn)) { AsmRtn = RTN_FindByName(img, "_operImmCmds"); } if (RTN_Valid(AsmRtn)) { *outFile << "Function operImmCmds found" << endl; RTN_Open(AsmRtn); // Go over each of the routine's instructions for (INS ins = RTN_InsHead(AsmRtn); INS_Valid(ins); ins = INS_Next(ins)) { Instruction(ins, 0); } RTN_Close(AsmRtn); *outFile << "Done with function operImmCmds" << endl; } else { *outFile << "Function operImmCmds not found!" << endl; } } }
VOID Instruction(INS ins, VOID *v) { //if (RTN_Valid(INS_Rtn(ins)) && RTN_Name(INS_Rtn(ins)) == "__SEH_epilog4") { // cerr << "image " << IMG_Name(SEC_Img(RTN_Sec(INS_Rtn(ins)))) << endl; //} if ( leaflag && INS_IsLea(ins) ) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(LeaAdd), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_INST_PTR, IARG_REG_VALUE, REG_GBP, IARG_END); } if ( INS_IsBranch(ins) && !(INS_IsCall(ins)) && !(INS_IsRet(ins)) ) { INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(Branch), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_END); } else if (INS_IsRet(ins)) { INS prev = INS_Prev(ins); //cout<< "CALL TO RET" << endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(Ret), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_UINT32, (INS_Valid(prev) && INS_Opcode(prev) == XED_CATEGORY_PUSH), IARG_END); } else if (INS_IsCall(ins)) { //cout << "CALL TO CALL" << endl; INS_InsertCall(ins, IPOINT_TAKEN_BRANCH, AFUNPTR(Call), IARG_THREAD_ID, IARG_REG_VALUE, REG_STACK_PTR, IARG_BRANCH_TARGET_ADDR, IARG_INST_PTR, IARG_END); } else if (INS_IsMemoryWrite(ins)) { //cout<< "CALL TO MEWRITE" << endl; INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(MemWrite), IARG_THREAD_ID, IARG_MEMORYWRITE_EA, IARG_END); } }
// Pin calls this function every time a new instruction is encountered void Trace(TRACE trace , void *v) { for(BBL bbl= TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)){ for( INS ins = BBL_InsHead(bbl); INS_Valid(ins) ; ins =INS_Next(ins)){ oepf.IsCurrentInOEP(ins); } } }
VOID Instruction(INS ins, VOID *v) { if (INS_IsBranchOrCall(ins) || !INS_Valid(INS_Next(ins))) { INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)BblRef, IARG_END); } }
bool BBLContainMemOp(BBL bbl) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsStackRead(ins) || INS_IsStackWrite(ins)) continue; if (INS_IsMemoryRead(ins) || INS_IsMemoryWrite(ins)) return true; } return false; }
static void instrument_trace(TRACE trace, VOID *v) { sse_aligner_t* pthis = static_cast<sse_aligner_t*>(v); bool is_read = false; for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) if (check_for_sse_memop(ins, is_read, pthis)) rewrite_instruction(ins, is_read, pthis); }
VOID TraceInserted(TRACE trace, VOID *) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { cacheInstructions++; } } }
VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { RewriteIns(ins); } } }
VOID Rtn(RTN rtn, VOID * v) { string name = RTN_Name(rtn); if (name == "test1") { RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { CountsUpdate(ins); } RTN_Close(rtn); } }
INT32 RecordRegisters(BBL bbl, UINT16 * stats) { INT32 count = 0; for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { const UINT32 max_r = INS_MaxNumRRegs(ins); for( UINT32 i=0; i < max_r; i++ ) { const REG reg = INS_RegR(ins, i ); if( REG_is_gr(reg) ) { stats[count++] = REG_GetStatsIndex(reg,FALSE); } #if 0 // This is for arm else if( REG_is_aggregate(reg) ) { REGSET regset = INS_RegAggregateR(ins); for( REG reg = REGSET_PopNext(regset); REG_valid(reg); reg = REGSET_PopNext(regset) ) { stats[count++] = REG_GetStatsIndex(reg,FALSE); } } #endif } const UINT32 max_w = INS_MaxNumWRegs(ins); for( UINT32 i=0; i < max_w; i++ ) { const REG reg = INS_RegW(ins, i ); if( REG_is_gr(reg) ) { stats[count++] = REG_GetStatsIndex(reg,TRUE); } #if 0 else if( REG_is_aggregate(reg) ) { REGSET regset = INS_RegAggregateW(ins); for( REG reg = REGSET_PopNext(regset); REG_valid(reg); reg = REGSET_PopNext(regset) ) { stats[count++] = REG_GetStatsIndex(reg,TRUE); } } #endif } } stats[count++] = 0; return count; }
VOID DumpTrace(CHAR * message, TRACE trace) { fprintf(stderr,"\n%s:\n",message); for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { fprintf(stderr,"%p %s\n",(void*)INS_Address(ins),INS_Disassemble(ins).c_str()); } } }
/* * trace inspection (instrumentation function) * * traverse the basic blocks (BBLs) on the trace and * inspect every instruction for instrumenting it * accordingly * * @trace: instructions trace; given by PIN * @v: callback value */ static void trace_inspect(TRACE trace, VOID *v) { /* iterators */ BBL bbl; INS ins; xed_iclass_enum_t ins_indx; /* versioning support */ ADDRINT version, version_mask = (ADDRINT)v; if (version_mask) { /* * ignore code cache versions that we * are not supposed to instrument */ version = TRACE_Version(trace); if ((version & version_mask) == 0) return; } /* traverse all the BBLs in the trace */ for (bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { /* traverse all the instructions in the BBL */ for (ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { /* * use XED to decode the instruction and * extract its opcode */ ins_indx = (xed_iclass_enum_t)INS_Opcode(ins); /* * invoke the pre-ins instrumentation callback */ if (ins_desc[ins_indx].pre != NULL) ins_desc[ins_indx].pre(ins); /* * analyze the instruction (default handler) */ if (ins_desc[ins_indx].dflact == INSDFL_ENABLE) ins_inspect(ins); /* * invoke the post-ins instrumentation callback */ if (ins_desc[ins_indx].post != NULL) ins_desc[ins_indx].post(ins); } } }
VOID Trace(TRACE trace, VOID *v) { for (BBL bbl = TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)) { BasicBlockTrace(trace, bbl); for (INS ins = BBL_InsHead(bbl); INS_Valid(ins); ins = INS_Next(ins)) { CallTrace(trace, ins); MemoryTrace(trace, ins); } } }
static void InstrumentImage(IMG img, VOID *dummy) { RTN rtn = RTN_FindByName(img, "MakeSegv"); if (RTN_Valid(rtn)) { RTN_Open(rtn); INS first = RTN_InsHead(rtn); if (INS_Valid(first)) INS_InsertCall(first, IPOINT_BEFORE, (AFUNPTR)AtSegv, IARG_END); RTN_Close(rtn); } }
// Delete the first mov immediate static VOID deleteMov (RTN rtn) { for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsMov(ins) && INS_HasImmediateOperand(ins)) { INS_Delete(ins); instrumentationCount++; return; } } }
// Insert a direct branch over the first mov immediate static VOID insertJump (RTN rtn) { for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsMov(ins) && INS_HasImmediateOperand(ins)) { INS_InsertDirectJump(ins, IPOINT_BEFORE, INS_Address(ins) + INS_Size(ins)); instrumentationCount++; return; } } }
// Pin calls this function every time a new instruction is encountered void Trace(TRACE trace , void *v) { for(BBL bbl= TRACE_BblHead(trace); BBL_Valid(bbl); bbl = BBL_Next(bbl)){ fprintf(file, "----BEGIN BBL---\n"); for( INS ins = BBL_InsHead(bbl); INS_Valid(ins) ; ins =INS_Next(ins)){ fprintf(file , "%s\n" , INS_Disassemble(ins).c_str()); } fprintf(file, "----END BBL---\n"); } }