static VOID InsertIfNoBridgeThenInline(RTN rtn) { RTN_Open(rtn); INS_InsertIfCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(IfNoBridge), IARG_END); INS_InsertThenCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(ThenInline), IARG_END); RTN_Close(rtn); }
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); numRtnsFoundInImageCallback++; INS ins = RTN_InsHeadOnly(rtn); if (INS_Invalid() == ins) { // no instruction found - assert that RTN_InsHead(rtn) also doesn't find any INS ASSERTX (INS_Invalid() == RTN_InsHead(rtn)); RTN_Close(rtn); continue; } if (INS_HasFallThrough(ins)) { ADDRINT insAddress = INS_Address(ins); numRtnsInstrumentedFromImageCallback++; RTN_InsertCall( rtn, IPOINT_BEFORE, AFUNPTR(AtRtn), IARG_ADDRINT, RTN_Address(rtn), IARG_END); INS_InsertCall (ins, IPOINT_BEFORE, AFUNPTR(BeforeInsHeadOnly), IARG_ADDRINT, INS_Address(ins), IARG_END); INS_InsertCall (ins, IPOINT_AFTER, AFUNPTR(AfterInsHeadOnly), IARG_ADDRINT, INS_Address(ins), IARG_END); ins = RTN_InsHead(rtn); ASSERTX(INS_Invalid() != ins); ASSERTX(INS_Address(ins)==insAddress); INS_InsertCall (ins, IPOINT_BEFORE, AFUNPTR(BeforeInsHead), IARG_ADDRINT, insAddress, IARG_END); INS_InsertCall (ins, IPOINT_AFTER, AFUNPTR(AfterInsHead), IARG_ADDRINT, insAddress, IARG_END); } RTN_Close(rtn); } } }
static VOID InsertIfBridgeThenBridge(RTN rtn) { RTN_Open(rtn); INS_InsertIfCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(IfBridge), IARG_BRIDGE_IF, IARG_END); INS_InsertThenCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(ThenBridge), IARG_BRIDGE, IARG_END); RTN_Close(rtn); }
static VOID OnRoutine(RTN rtn, VOID *) { #if defined(TARGET_MAC) if (RTN_Name(rtn) == "_DoThenInstrumentation") #else if (RTN_Name(rtn) == "DoThenInstrumentation") #endif { RTN_Open(rtn); INS_InsertIfCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(IfTrue), IARG_END); INS_InsertThenCall(RTN_InsHead(rtn), IPOINT_BEFORE, AFUNPTR(ThenFunction), IARG_END); RTN_Close(rtn); } }
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); } }
// 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; } } }
/* * 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; } } }
// 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); }
PyObject* Python_RTN_InsHead(PyObject* self, PyObject* args) { PyObject* rtn; PyArg_ParseTuple(args, "L", &rtn); RTN rtn_object = *(RTN*) rtn; INS* ins_return = (INS*) malloc(sizeof(INS)); *ins_return = RTN_InsHead(rtn_object); return Py_BuildValue("L", ins_return); }
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); } }
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; } } }
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); } } }
// Insert an indirect branch over the first mov immediate static VOID insertIndirectJump (RTN rtn) { for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_IsMov(ins) && INS_HasImmediateOperand(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(returnValue), IARG_ADDRINT, INS_Address(ins) + INS_Size(ins), IARG_RETURN_REGS, scratchReg, IARG_END); INS_InsertIndirectJump(ins, IPOINT_BEFORE, scratchReg); instrumentationCount++; return; } } }
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)) { sandbox.RecordIns(ins); } RTN_Close(rtn); } } }
// Insert a call to an analysis routine that sets the scratch xmm registers, the call is inserted just after the // movdqa instruction of DoXmm (see xmm-asm-*.s) static VOID InstrumentRoutine(RTN rtn, VOID *) { if (RTN_Name(rtn) == "DoXmm") { RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { if (INS_Opcode(ins)==XED_ICLASS_MOVDQA) { fprintf (fp, "instrumenting ins %p %s\n", (void *)INS_Address(ins), INS_Disassemble(ins).c_str()); instrumented = TRUE; INS_InsertCall(ins, IPOINT_AFTER, (AFUNPTR)SetXmmScratchesFun, IARG_PTR, xmmInitVals, IARG_END); } } RTN_Close(rtn); } }
static VOID imageLoad(IMG img, VOID *v) { // Just instrument the main image. if (!IMG_IsMainExecutable(img)) 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)) { RTN_Open(rtn); for (INS ins=RTN_InsHead(rtn); INS_Valid(ins); ins=INS_Next(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)incCount, IARG_END); } RTN_Close(rtn); } } }
VOID Routine(RTN rtn, VOID *v) { std::string name = PIN_UndecorateSymbolName(RTN_Name(rtn).c_str(), UNDECORATION_NAME_ONLY); std::vector<std::string>::iterator it; for (it = userFuncs.begin(); it != userFuncs.end(); ++it) { std::string userFunc = *it; if (name.find(userFunc) == std::string::npos) continue; RTN_Open(rtn); // For each instruction of the routine for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { UINT32 memOperands = INS_MemoryOperandCount(ins); // Iterate over each memory operand of the instruction. for (UINT32 memOp = 0; memOp < memOperands; memOp++) { if (INS_IsStackRead(ins) || INS_IsStackWrite(ins)) break; if (INS_MemoryOperandIsRead(ins, memOp)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead, IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END); } if (INS_MemoryOperandIsWritten(ins, memOp)) { INS_InsertPredicatedCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_MEMORYOP_EA, memOp, IARG_THREAD_ID, IARG_END); } } } RTN_Close(rtn); } }
/* ===================================================================== */ VOID Image(IMG img, VOID *v){ for (UINT16 i = 0; i < n_excluded_lib_names; i++) { if (IMG_Name(img).find(excluded_lib_names[i]) != string::npos){ cout << "Excluded module: " << IMG_Name(img) << endl; 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)) { RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { // Avoid instrumenting the instrumentation if (!INS_IsOriginal(ins)) continue; if(!SeqProgram) { if ((INS_IsMemoryWrite(ins) || INS_IsMemoryRead(ins)) && INS_HasFallThrough(ins)) { if (INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) && INS_HasMemoryRead2(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID, IARG_MEMORYWRITE_EA, IARG_MEMORYREAD_EA, IARG_MEMORYREAD2_EA, IARG_INST_PTR, IARG_END); } else if (INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) && !INS_HasMemoryRead2(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID, IARG_MEMORYWRITE_EA, IARG_MEMORYREAD_EA, IARG_ADDRINT, 0, IARG_INST_PTR, IARG_END); } else if (INS_IsMemoryWrite(ins) && !INS_IsMemoryRead(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID, IARG_MEMORYWRITE_EA, IARG_ADDRINT, 0, IARG_ADDRINT, 0, IARG_INST_PTR, IARG_END); } else if (!INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) && INS_HasMemoryRead2(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID, IARG_ADDRINT, 0, IARG_MEMORYREAD_EA, IARG_MEMORYREAD2_EA, IARG_INST_PTR, IARG_END); } else if (!INS_IsMemoryWrite(ins) && INS_IsMemoryRead(ins) && !INS_HasMemoryRead2(ins)) { INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessInst, IARG_THREAD_ID, IARG_ADDRINT, 0, IARG_MEMORYREAD_EA, IARG_ADDRINT,0, IARG_INST_PTR, IARG_END); } else { //not a memory opeartion ASSERTX(0); } } } else { if(INS_IsBranch(ins)){ INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)ProcessBranch, IARG_BRANCH_TAKEN, IARG_INST_PTR, IARG_END); } } } RTN_Close(rtn); } } }
int rtn_ins_head (lua_State *L) { RTN* v1 = check_rtn(L,1); INS_to_lua(L, RTN_InsHead(*v1)); return 1; }
int main(INT32 argc, CHAR **argv) { PIN_InitSymbols(); if( PIN_Init(argc,argv) ) { return Usage(); } IMG img = IMG_Open(KnobInputFile); if (!IMG_Valid(img)) { std::cout << "Could not open " << KnobInputFile.Value() << endl; exit(1); } std::cout << hex; rtnInternalRangeList.clear(); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { std::cout << "Section: " << setw(8) << SEC_Address(sec) << " " << SEC_Name(sec) << endl; for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { std::cout << " Rtn: " << setw(8) << hex << RTN_Address(rtn) << " " << RTN_Name(rtn) << endl; string path; INT32 line; PIN_GetSourceLocation(RTN_Address(rtn), NULL, &line, &path); if (path != "") { std::cout << "File " << path << " Line " << line << endl; } RTN_Open(rtn); if (!INS_Valid(RTN_InsHead(rtn))) { RTN_Close(rtn); continue; } RTN_INTERNAL_RANGE rtnInternalRange; rtnInternalRange.start = INS_Address(RTN_InsHead(rtn)); rtnInternalRange.end = INS_Address(RTN_InsHead(rtn)) + INS_Size(RTN_InsHead(rtn)); INS lastIns = INS_Invalid(); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { std::cout << " " << setw(8) << hex << INS_Address(ins) << " " << INS_Disassemble(ins) << endl; if (INS_Valid(lastIns)) { if ((INS_Address(lastIns) + INS_Size(lastIns)) == INS_Address(ins)) { rtnInternalRange.end = INS_Address(ins)+INS_Size(ins); } else { rtnInternalRangeList.push_back(rtnInternalRange); std::cout << " rtnInternalRangeList.push_back " << setw(8) << hex << rtnInternalRange.start << " " << setw(8) << hex << rtnInternalRange.end << endl; // make sure this ins has not already appeared in this RTN for (vector<RTN_INTERNAL_RANGE>::iterator ri = rtnInternalRangeList.begin(); ri != rtnInternalRangeList.end(); ri++) { if ((INS_Address(ins) >= ri->start) && (INS_Address(ins)<ri->end)) { std::cout << "***Error - above instruction already appeared in this RTN\n"; std::cout << " in rtnInternalRangeList " << setw(8) << hex << ri->start << " " << setw(8) << hex << ri->end << endl; exit (1); } } rtnInternalRange.start = INS_Address(ins); rtnInternalRange.end = INS_Address(ins) + INS_Size(ins); } } lastIns = ins; } RTN_Close(rtn); rtnInternalRangeList.clear(); } } IMG_Close(img); }
// This function is called before every instruction is executed VOID instrument_routine(RTN rtn, void *ip) { string name = RTN_Name(rtn); if(name == "ivan") { RTN_Open(rtn); for (INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins)) { int opCount = INS_OperandCount(ins); int opcode = INS_Opcode(ins); if(INS_IsMemoryRead(ins)) { for(int i = 0; i< opCount; i++) { if(INS_MemoryOperandIsRead(ins,i)) { /* INS_InsertCall(ins, IPOINT_BEFORE, (AFUNPTR)RecordMemRead,IARG_PTR,ins, IARG_INST_PTR, IARG_MEMORYOP_EA, i, IARG_END); */ cout<<"opcode:"<<INS_Opcode(ins)<<", mnemonic: "<<INS_Mnemonic(ins)<<endl; if(INS_Opcode(ins)!= XED_ICLASS_RET_NEAR) { REG scratchReg = GetScratchReg(i); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(GetMemAddress), IARG_MEMORYOP_EA, i, IARG_RETURN_REGS, scratchReg, IARG_END); INS_RewriteMemoryOperand(ins, i, scratchReg); } } } } if(INS_IsMemoryWrite(ins)) { for(int i = 0; i< opCount; i++) { /* if(INS_OperandIsImmediate(ins,i)) { cout<<"immediate "<<INS_OperandImmediate(ins,i)<<endl; } */ if(INS_MemoryOperandIsWritten(ins,i) && INS_HasFallThrough(ins)) { /* INS_InsertCall( ins, IPOINT_BEFORE, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_MEMORYOP_EA, i, IARG_END); INS_InsertCall( ins, IPOINT_AFTER, (AFUNPTR)RecordMemWrite, IARG_INST_PTR, IARG_MEMORYOP_EA, i, IARG_END); */ if(opcode != XED_ICLASS_PUSH) { REG scratchReg = GetScratchReg(i); INS_InsertCall(ins, IPOINT_BEFORE, AFUNPTR(GetMemAddress), IARG_MEMORYOP_EA, i, IARG_RETURN_REGS, scratchReg, IARG_END); INS_RewriteMemoryOperand(ins, i, scratchReg); } } } } } RTN_Close(rtn); } }
VOID Image(IMG img, VOID *v) { #ifdef HEAP // Instrument the malloc() and free() functions. Print the input argument // of each malloc() or free(), and the return value of malloc(). // // 1. Find the malloc() function. RTN mallocRtn = RTN_FindByName(img, MALLOC); if (RTN_Valid(mallocRtn)) { RTN_Open(mallocRtn); // Instrument malloc() to print the input argument value and the return value. RTN_InsertCall(mallocRtn, IPOINT_BEFORE, (AFUNPTR)AllocSize, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END); RTN_InsertCall(mallocRtn, IPOINT_AFTER, (AFUNPTR)AllocAddress, IARG_FUNCRET_EXITPOINT_VALUE, IARG_END); RTN_Close(mallocRtn); } // 2. Find the free() function. RTN freeRtn = RTN_FindByName(img, FREE); if (RTN_Valid(freeRtn)) { RTN_Open(freeRtn); // Instrument free() to print the input argument value. RTN_InsertCall(freeRtn, IPOINT_BEFORE, (AFUNPTR)DeallocAddress, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_END); RTN_Close(freeRtn); } #endif #ifdef STACK // 3. Visit all routines to collect frame size 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); // collect user functions as well as their addresses ADDRINT fAddr = RTN_Address(rtn); string szFunc = RTN_Name(rtn); g_hAddr2Name[fAddr] = szFunc; //cerr << fAddr << ":\t" << szFunc << endl; //bool bFound = false; for(INS ins = RTN_InsHead(rtn); INS_Valid(ins); ins = INS_Next(ins) ) { // collecting stack size according to "SUB 0x20, %esp" or "ADD 0xffffffe0, %esp" if( INS_Opcode(ins) == XED_ICLASS_SUB && INS_OperandIsReg(ins, 0 ) && INS_OperandReg(ins, 0) == REG_STACK_PTR && INS_OperandIsImmediate(ins, 1) ) { int nOffset = INS_OperandImmediate(ins, 1); if(nOffset < 0 ) { nOffset = -nOffset; } g_hFunc2FrameSize[fAddr] = nOffset; //bFound = true; break; } if( INS_Opcode(ins) == XED_ICLASS_ADD && INS_OperandIsReg(ins, 0 ) && INS_OperandReg(ins, 0) == REG_STACK_PTR && INS_OperandIsImmediate(ins, 1) ) { int nOffset = INS_OperandImmediate(ins, 1); if(nOffset < 0 ) { nOffset = -nOffset; } g_hFunc2FrameSize[fAddr] = nOffset; //bFound = true; break; } } //if( !bFound ) // g_hFunc2FrameSize[fAddr] = 0; RTN_Close(rtn); } } #endif }