/***************************************************************************** 函 数 名 : traceBack 功能描述 : 回溯已经调用的函数栈,解析当前函数调用的信息 输入参数 : const char* cfuncName ADDRINT funcAddr ADDRINT funcBP 输出参数 : 无 返 回 值 : 调用函数 : 被调函数 : 修改历史 : 1.日 期 : 2012年5月16日 作 者 : @zhi 修改内容 : 新生成函数 *****************************************************************************/ VOID traceBack( ADDRINT funcCurSP, ADDRINT funcUpperBP ) { if(g_backTraceFlg) { #if 1 string funcName; std::stack<FuncItem>tmpFuncs; ADDRINT tmpAddr; ADDRINT funcAddr; //待运行函数入栈,后面的插入直接是从该函数开始 //tmpFuncs.push(FuncItem(funcName, funcAddr, funcBP-1)); tmpAddr = *((ADDRINT *)funcCurSP); funcName = RTN_FindNameByAddress(tmpAddr); //获取不到函数名 if("" == funcName) { funcName = "[unknown]"; } PIN_LockClient(); funcAddr = RTN_Address(RTN_FindByAddress(tmpAddr)); PIN_UnlockClient(); ADDRINT funcBP = funcUpperBP; while(0 != funcBP) { tmpFuncs.push(FuncItem(funcName, funcAddr, funcBP)); tmpAddr = *((ADDRINT *)funcBP + 1); funcName = RTN_FindNameByAddress(tmpAddr); //获取不到函数名 if("" == funcName) { funcName = "[unknown]"; } PIN_LockClient(); funcAddr = RTN_Address(RTN_FindByAddress(tmpAddr)); PIN_UnlockClient(); funcBP = *(ADDRINT*) funcBP; } #endif #if 1 tmpAddr =0; while(!tmpFuncs.empty()) { funcPackage(tmpFuncs.top().funcName.c_str(), tmpFuncs.top().funcAddr, tmpAddr); tmpAddr = tmpFuncs.top().upperFuncBP; tmpFuncs.pop(); } #endif g_backTraceFlg = false; } }
VOID WriteMem(UINT64 insAddr, std::string insDis, UINT32 opCount, REG reg_r, UINT64 memOp) { std::list<struct mallocArea>::iterator i; UINT64 addr = memOp; PIN_LockClient(); IMG img = IMG_FindByAddress(addr); PIN_UnlockClient(); SEC sec; if (opCount != 2){ return; } /* Check if the address is in a section */ for(sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)){ if (addr >= SEC_Address(sec) && addr < (SEC_Address(sec) + SEC_Size(sec))) return; } /* Check if the address is mapped */ for(i = mallocAreaList.begin(); i != mallocAreaList.end(); i++){ if (i->status == ALLOCATE && addr >= i->base && addr < (i->base + i->size)) return; if (i->status == FREE && addr >= i->base && addr < (i->base + i->size)){ std::cout << std::hex << insAddr << ": " << insDis << " -- Use after free in " << addr << std::endl; return; } } /* check if the address is in a stack area */ if (addr > 0x700000000000) return; std::cout << std::hex << insAddr << ": " << insDis << " -- Heap overflow in " << addr << std::endl; }
VOID MemWrite(THREADID tid, ADDRINT ea, ADDRINT eip ) { IMG imgR; string retName = "ANON", rR = "unknown"; thread_data_t *tdata = get_tls(tid); list<ADDRINT>::const_iterator sp_iter; for (sp_iter = tdata->data_sp.begin(); sp_iter != tdata->data_sp.end(); sp_iter++) { if ( *sp_iter == ea ) break; } if ( sp_iter != tdata->data_sp.end() ) { PIN_LockClient(); imgR = IMG_FindByAddress((ADDRINT)eip); PIN_UnlockClient(); if ( IMG_Valid(imgR) ) { retName = IMG_Name(imgR); } rR = RTN_FindNameByAddress((ADDRINT)eip); OutFile[tid] << tid << hex << "return address overwrite!!! " << ea << " " << eip << " " << retName << " " << rR << endl; } }
static void A_DoMem(bool isStore, void *ea, ADDRINT pc) { string filename; int lineno; if( addrsToDump.find(ea) != addrsToDump.end() ) { PIN_LockClient(); PIN_GetSourceLocation(pc, NULL, &lineno, &filename); PIN_UnlockClient(); *Output << (isStore ? "store" : "load") << " pc=" << (void*)pc << " ea=" << ea << endl; if( filename != "") { *Output << filename << ":" << lineno; } else { *Output << "UNKNOWN:0"; } *Output << endl; callStack.DumpStack(Output); *Output << endl; } }
/* Callback after instruction processing */ static void callbackAfter(triton::arch::Instruction* tritonInst, CONTEXT* ctx, THREADID threadId) { if (!tracer::pintool::analysisTrigger.getState() || threadId != tracer::pintool::options::targetThreadId) /* Analysis locked */ return; /* Mutex */ PIN_LockClient(); /* Update CTX */ tracer::pintool::context::lastContext = ctx; /* Execute the Python callback */ tracer::pintool::callbacks::after(tritonInst); /* Some configurations must be applied after processing */ tracer::pintool::callbacks::postProcessing(tritonInst, threadId); /* Clear Instruction information because of the Pin's cache */ tritonInst->clear(); /* Check if we must execute a new context */ if (tracer::pintool::context::mustBeExecuted == true) tracer::pintool::context::executeContext(); /* Check if we must restore the snapshot */ if (tracer::pintool::snapshot.mustBeRestored() == true) tracer::pintool::snapshot.restoreSnapshot(ctx); /* Mutex */ PIN_UnlockClient(); }
static void FreeProbe(void (*origFree)(void *), UINT32 freeNum, void *ptr, ADDRINT appTP) { origFree(ptr); PIN_LockClient(); TraceFile << freeNum << " free(" << ptr << ")" << std::endl; PIN_UnlockClient(); }
// This function is called before every block VOID PIN_FAST_ANALYSIS_CALL docount(UINT32 c, THREADID tid, ADDRINT iAddr) { icount[tid]._count += c; if ((icount[tid]._count - icount[tid]._prev_count) >= sampleRate) { // Arbitrary sample point icount[tid]._prev_count += sampleRate; // Get Pin client lock according to description of PIN_GetSourceLocation() PIN_LockClient(); INT32 lineNumber; string fileName; // Get line info PIN_GetSourceLocation(iAddr, NULL, &lineNumber, &fileName); PIN_UnlockClient(); // RTN_FindNameByAddress() may not be called under Pin client lock string rtnName = RTN_FindNameByAddress(iAddr); if (lineNumber != 0) { icount[tid]._line_number = lineNumber; icount[tid]._file_name = fileName; icount[tid]._rtn_name = rtnName; } } }
/* Save the memory access into the Triton instruction */ static void saveMemoryAccess(triton::arch::Instruction* tritonInst, triton::__uint addr, triton::uint32 size) { /* Mutex */ PIN_LockClient(); triton::uint512 value = tracer::pintool::context::getCurrentMemoryValue(addr, size); tracer::pintool::api.setConcreteMemoryValue(triton::arch::MemoryAccess(addr, size), value); /* Mutex */ PIN_UnlockClient(); }
/* Callback before instruction processing */ static void callbackBefore(triton::arch::Instruction* tritonInst, triton::uint8* addr, triton::uint32 size, CONTEXT* ctx, THREADID threadId) { /* Some configurations must be applied before processing */ tracer::pintool::callbacks::preProcessing(tritonInst, threadId); if (!tracer::pintool::analysisTrigger.getState() || threadId != tracer::pintool::options::targetThreadId) /* Analysis locked */ return; /* Mutex */ PIN_LockClient(); /* Update CTX */ tracer::pintool::context::lastContext = ctx; /* Setup Triton information */ tritonInst->clear(); tritonInst->setOpcode(addr, size); tritonInst->setAddress(reinterpret_cast<triton::__uint>(addr)); tritonInst->setThreadId(reinterpret_cast<triton::uint32>(threadId)); /* Disassemble the instruction */ tracer::pintool::api.disassembly(*tritonInst); /* Execute the Python callback before the IR processing */ if (tracer::pintool::context::mustBeExecuted == false) tracer::pintool::callbacks::beforeIRProc(tritonInst); else tracer::pintool::context::mustBeExecuted = false; /* Check if we must execute a new context */ if (tracer::pintool::context::mustBeExecuted == true) { tritonInst->clear(); tracer::pintool::context::executeContext(); } /* Synchronize gliches between Pintool and libTriton */ tracer::pintool::context::synchronizeContext(); /* Process the IR and spread taint only if one of both engines are enabled */ if (tracer::pintool::api.isTaintEngineEnabled() || tracer::pintool::api.isSymbolicEngineEnabled()) tracer::pintool::api.buildSemantics(*tritonInst); /* Execute the Python callback */ if (tracer::pintool::context::mustBeExecuted == false) tracer::pintool::callbacks::before(tritonInst); /* Check if we must restore the snapshot */ if (tracer::pintool::snapshot.mustBeRestored() == true) { tritonInst->clear(); tracer::pintool::snapshot.restoreSnapshot(ctx); } /* Some configurations must be applied after processing */ tracer::pintool::callbacks::postProcessing(tritonInst, threadId); /* Mutex */ PIN_UnlockClient(); }
// Replay the image log. // We run this before the each instruction of the code as an analysis routine. // So we eat up the image loads one instruction at a time! // We can also call it before PIN_StartProgram, to check that queuing // the replay calls up works. // static void ReplayImageEntry() { if (feof(imgLog)) exit(0); char tag = fgetc(imgLog); switch (tag) { case 'L': { string imageName; ADDRINT offset; ParseImageLoadLine(imageName, &offset); if (KnobVerbose) fprintf (trace, "Replaying load for %s\n", imageName.c_str()); // And, finally, inform Pin that it is all there, which will invoke // image load callbacks. PIN_LockClient(); // Tag the first image as the main program PIN_ReplayImageLoad(imageName.c_str(), imageName.c_str(), offset, replayedImageCount++==0); PIN_UnlockClient(); break; } case 'U': { string imageName; ParseImageUnloadLine(imageName); IMG img = FindNamedImg(imageName); if (KnobVerbose) fprintf (trace, "Replaying unload for %s\n", imageName.c_str()); // And, finally, inform Pin that it has gone, which will invoke // image unload callbacks. PIN_LockClient(); PIN_ReplayImageUnload(img); PIN_UnlockClient(); break; } default: fprintf (trace, "Unexpected line in log file starting with '%c'\n", tag); exit(0); } }
static void *MallocProbe(void *(*origMalloc)(size_t), UINT32 mallocNum, size_t size, ADDRINT appTP) { void *ptr = origMalloc(size); PIN_LockClient(); TraceFile << mallocNum << " malloc(" << size << ") returns " << ptr << std::endl; PIN_UnlockClient(); return ptr; }
std::string getRoutineName(triton::__uint address) { RTN rtn; PIN_LockClient(); rtn = RTN_FindByAddress(address); PIN_UnlockClient(); if (RTN_Valid(rtn)) { return RTN_Name(rtn); } return ""; }
VOID InstructionProp(INS ins, VOID *v) { PIN_LockClient(); for (IMG image = APP_ImgHead();image!=IMG_Invalid();image=IMG_Next(image)) { inst_func_summary(image); } PIN_UnlockClient(); }
static VOID AnalysisFindImg (ADDRINT ip) { PIN_LockClient(); IMG img = IMG_FindByAddress(ip); PIN_UnlockClient(); if (IMG_Valid(img)) { numTimesImgFoundInAnalysis++; } else { numTimesImgNotFoundInAnalysis++; } }
/* * Callback when an image is loaded. * This callback must be called even outside the range analysis. */ static void callbackImageLoad(IMG img) { /* Mutex */ PIN_LockClient(); /* Collect image information */ std::string imagePath = IMG_Name(img); triton::__uint imageBase = IMG_LowAddress(img); triton::__uint imageSize = (IMG_HighAddress(img) + 1) - imageBase; /* Execute the Python callback */ tracer::pintool::callbacks::imageLoad(imagePath, imageBase, imageSize); /* Mutex */ PIN_UnlockClient(); }
static void FreeProbe(void (*origFree)(void *), UINT32 freeNum, void *ptr, ADDRINT appTP) { #if defined(TARGET_IPF) ADDRINT toolTP = IPF_GetTP(); IPF_SetTP(appTP); origFree(ptr); IPF_SetTP(toolTP); #else origFree(ptr); #endif PIN_LockClient(); TraceFile << freeNum << " free(" << ptr << ")" << std::endl; PIN_UnlockClient(); }
// ------------------------------------------------------------- // Get function address by branch target address // ------------------------------------------------------------- ADDRINT Target2FunAddr(ADDRINT target) { PIN_LockClient(); ADDRINT funAddr; const RTN rtn = RTN_FindByAddress(target); if ( RTN_Valid(rtn) ) funAddr = RTN_Address(rtn); else funAddr = target; PIN_UnlockClient(); return funAddr; }
VOID fn_indirect_call(CONTEXT* ctxt, ADDRINT target) { trace_enter(); // Indirect call, we have to look up the function each time // The functions `fn_lookup` & `fn_register` needs PIN's Lock. // Locking is not implicit in inserted call, as opposed // to callback added with *_AddInstrumentFunction(). PIN_LockClient(); FID fid = fn_lookup_by_address(target); PIN_UnlockClient(); fn_call(ctxt, fid); trace_leave(); }
// ------------------------------------------------------------- // STool_LibraryIDByAddr // ------------------------------------------------------------- // Return ID of the library of the routine to which the instruction // at address rtnAddr belongs, or STool_INVALID_LIB, if rtnAddr does not belong to // any routine. UINT32 STool_LibraryIDByAddr(ADDRINT rtnAddr){ PIN_LockClient(); const RTN rtn = RTN_FindByAddress(rtnAddr); UINT32 libID; if( RTN_Valid(rtn) ) libID = IMG_Id(SEC_Img(RTN_Sec(rtn))); else libID = STool_INVALID_LIB; PIN_UnlockClient(); return libID; }
/* Callback at the syscall exit */ static void callbackSyscallExit(unsigned int threadId, CONTEXT* ctx, SYSCALL_STANDARD std, void* v) { if (!tracer::pintool::analysisTrigger.getState() || threadId != tracer::pintool::options::targetThreadId) /* Analysis locked */ return; /* Mutex */ PIN_LockClient(); /* Update CTX */ tracer::pintool::context::lastContext = ctx; /* Execute the Python callback */ tracer::pintool::callbacks::syscallExit(threadId, std); /* Mutex */ PIN_UnlockClient(); }
VOID Branch( THREADID tid, ADDRINT sp, ADDRINT target, ADDRINT eip ) { if ( target >= (start+FFI_CALL_UNIX64) && (target <= start+FF64END) ) { OutFile << tid << " BRANCH" << hex <<" "<< eip << " " << target << " " << sp << endl; leaflag = true; size_t sizeread; ADDRINT value; PIN_LockClient(); sizeread = PIN_SafeCopy(&value, (const VOID *)sp, sizeof(uint64_t)); if ( sizeread != sizeof(uint64_t) ) OutFile << "Incorrect Size read from stack for sp: " << hex << sp << " " << sizeread << endl; else OutFile << tid << " Stack " << hex << sp << " Val " << value << endl; PIN_UnlockClient(); } if ( target == (start+FF64PLT) ) OutFile << tid << " J-PLT64 " << hex <<" "<< eip << " " << target << " " << sp << endl; if ( eip >= (start+FFI_CALL_UNIX64) && eip <= (start+FF64END) ) { OutFile << tid << " J-FF64 " << hex << eip << " " << target << " " << sp << endl; } // Reading value on threads stack /* if ( eip >= (ANONST) && eip <= (ANONEND) ) { OutFile << tid << " BRANCH-I " << hex << eip << " " << target << " " << sp << endl; } if ( target >= (ANONST) && target <= (ANONEND) ) { OutFile << tid << " BRANCH-T " << hex << eip << " " << target << " " << sp << endl; } */ }
/* Callback at a routine exit */ static void callbackRoutineExit(CONTEXT* ctx, THREADID threadId, PyObject* callback) { if (!tracer::pintool::analysisTrigger.getState() || threadId != tracer::pintool::options::targetThreadId) /* Analysis locked */ return; /* Mutex lock */ PIN_LockClient(); /* Update CTX */ tracer::pintool::context::lastContext = ctx; /* Execute the Python callback */ tracer::pintool::callbacks::routine(threadId, callback); /* Mutex unlock */ PIN_UnlockClient(); }
static void *MallocProbe(void *(*origMalloc)(size_t), UINT32 mallocNum, size_t size, ADDRINT appTP) { #if defined(TARGET_IPF) ADDRINT toolTP = IPF_GetTP(); IPF_SetTP(appTP); void *ptr = origMalloc(size); IPF_SetTP(toolTP); #else void *ptr = origMalloc(size); #endif PIN_LockClient(); TraceFile << mallocNum << " malloc(" << size << ") returns " << ptr << std::endl; PIN_UnlockClient(); return ptr; }
std::string getImageName(triton::__uint address) { RTN rtn; SEC sec; IMG img; PIN_LockClient(); rtn = RTN_FindByAddress(address); PIN_UnlockClient(); if (RTN_Valid(rtn)) { sec = RTN_Sec(rtn); if (SEC_Valid(sec)) { img = SEC_Img(sec); if (IMG_Valid(img)) { return IMG_Name(img); } } } return ""; }
triton::__uint getBaseAddress(triton::__uint address) { RTN rtn; SEC sec; IMG img; PIN_LockClient(); rtn = RTN_FindByAddress(address); PIN_UnlockClient(); if (RTN_Valid(rtn)) { sec = RTN_Sec(rtn); if (SEC_Valid(sec)) { img = SEC_Img(sec); if (IMG_Valid(img)) { return IMG_LowAddress(img); } } } return 0; }
/* Callback to save bytes for the snapshot engine */ static void callbackSnapshot(triton::__uint mem, triton::uint32 writeSize) { if (!tracer::pintool::analysisTrigger.getState()) /* Analysis locked */ return; /* If the snapshot is not enable we don't save the memory */ if (tracer::pintool::snapshot.isLocked()) return; /* Mutex */ PIN_LockClient(); for (triton::uint32 i = 0; i < writeSize ; i++) tracer::pintool::snapshot.addModification(mem+i, *(reinterpret_cast<triton::uint8*>(mem+i))); /* Mutex */ PIN_UnlockClient(); }
const string& Target2LibName(ADDRINT target) { PIN_LockClient(); const RTN rtn = RTN_FindByAddress(target); static const string _invalid_rtn("[Unknown image]"); string name; if( RTN_Valid(rtn) ) { name = IMG_Name(SEC_Img(RTN_Sec(rtn))); } else { name = _invalid_rtn; } PIN_UnlockClient(); return *new string(name); }
VOID PIN_FAST_ANALYSIS_CALL LogBBL(ADDRINT addr) { PIN_LockClient(); IMG img = IMG_FindByAddress(addr); PIN_UnlockClient(); if (IMG_Valid(img)){ std::set<ADDRINT> *s = bbls[IMG_Name(img)]; if (s == NULL){ s = new std::set<ADDRINT> (); bbls[IMG_Name(img)] = s; } s->insert(addr - IMG_LowAddress(img)); } }
VOID LeaAdd(THREADID tid, ADDRINT sp, ADDRINT eip, ADDRINT bp ) { size_t sizeread1, sizeread2, sizeread3; ADDRINT value, bpval, bp18 = bp + 0x18, bp18val; PIN_LockClient(); sizeread1 = PIN_SafeCopy(&value, (const VOID *)sp, sizeof(uint64_t)); sizeread2 = PIN_SafeCopy(&bpval, (const VOID *)bp, sizeof(uint64_t)); sizeread3 = PIN_SafeCopy(&bp18val, (const VOID *)bp18, sizeof(uint64_t)); if ( sizeread1 != sizeof(uint64_t) || sizeread2 != sizeof(uint64_t) || sizeread3 != sizeof(uint64_t) ) OutFile << "Incorrect Size read from stack for sp: " << hex << sp << " " << sizeread1 << " " << sizeread2 << endl; else OutFile << tid << " Stack " << hex << sp << " Val " << value << " BP " << bp << " BPVAL " << bpval << " BP+18 " << bp18 <<" Valbp+18 " << bp18val << endl; PIN_UnlockClient(); OutFile << dec << tid << " LEA " << hex << eip << " " << sp << " "<< bp << endl; }
/* Callback when a signals occurs */ static bool callbackSignals(unsigned int threadId, int sig, CONTEXT* ctx, bool hasHandler, const EXCEPTION_INFO* pExceptInfo, void* v) { /* Mutex */ PIN_LockClient(); /* Update CTX */ tracer::pintool::context::lastContext = ctx; /* Execute the Python callback */ tracer::pintool::callbacks::signals(threadId, sig); /* Mutex */ PIN_UnlockClient(); /* * We must exit. If you don't want to exit, * you must use the restoreSnapshot() function. */ exit(0); return true; }