static BOOL DebugInterpreter(THREADID tid, CONTEXT *ctxt, const string &cmd, string *result, VOID *) { TINFO_MAP::iterator it = ThreadInfos.find(tid); if (it == ThreadInfos.end()) return FALSE; TINFO *tinfo = it->second; std::string line = TrimWhitespace(cmd); *result = ""; if (line == "help") { result->append("mappings -- Mappings.\n"); return TRUE; } else if(line == "mappings") { tinfo->_os.str(""); tinfo->_os << "{"; //open JSON for( IMG img= APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img) ) { const string& name = LEVEL_PINCLIENT::IMG_Name(img); tinfo->_os <<"\""<< name << "\":{"; //open img ADDRINT address = LEVEL_PINCLIENT::IMG_LowAddress(img); tinfo->_os << "\"start\":" << address << ","; address = LEVEL_PINCLIENT::IMG_HighAddress(img); tinfo->_os << "\"end\":" << address << ","; tinfo->_os << "\"sections\":" << "{"; //open sections for( SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { const string& name = LEVEL_PINCLIENT::SEC_Name(sec); if(name != "") { tinfo->_os << "\"" << name <<"\":{"; //open section ADDRINT address = LEVEL_PINCLIENT::SEC_Address(sec); tinfo->_os << "\"start\":" << address << ","; USIZE size = LEVEL_PINCLIENT::SEC_Size(sec); if(SEC_Valid(SEC_Next(sec))) { tinfo->_os << "\"size\":" << size << "},"; //close section }else { tinfo->_os << "\"size\":" << size << "}}"; //close section and sections } } } if(IMG_Valid(IMG_Next(img))) { tinfo->_os << "},"; //close img }else { tinfo->_os << "}}"; //close img and json } } *result = tinfo->_os.str(); return TRUE; } return FALSE; /* Unknown command */ }
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); } } }
// When an image is loaded, check for a MyAlloc function VOID Image(IMG img, VOID *v) { //fprintf(stderr, "Loading %s\n",IMG_name(img)); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { //fprintf(stderr, " sec %s\n", SEC_name(sec).c_str()); for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { //fprintf(stderr, " rtn %s\n", RTN_name(rtn).c_str()); // Swizzle the return value of MyAlloc if (RTN_Name(rtn) == "MyAlloc") { RTN_Open(rtn); fprintf(stderr, "Adding Swizzle to %s\n", "MyAlloc"); RTN_InsertCall(rtn, IPOINT_AFTER, AFUNPTR(SwizzleRef), IARG_FUNCRET_EXITPOINT_REFERENCE, IARG_END); RTN_Close(rtn); } if (RTN_Name(rtn) == "MyFree") { RTN_Open(rtn); fprintf(stderr, "Adding SwizzleArg to %s\n", "MyFree"); RTN_InsertCall(rtn, IPOINT_BEFORE, AFUNPTR(UnswizzleRef), IARG_FUNCARG_ENTRYPOINT_REFERENCE, 0, IARG_END); RTN_Close(rtn); } } } }
//-------------------------------------------------------------------------- static VOID app_start_cb(VOID *v) { IMG img = APP_ImgHead(); for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ) { ADDRINT sec_ea = SEC_Address(sec); if ( sec_ea != 0 ) { ADDRINT check; size_t bytes = PIN_SafeCopy(&check, (void*)sec_ea, sizeof(ADDRINT)); if ( bytes == sizeof(ADDRINT) ) { if ( min_ea > sec_ea || min_ea == 0 ) min_ea = sec_ea; if ( max_ea < sec_ea || max_ea == (unsigned)-1 ) max_ea = sec_ea; segdata_t seg; seg.size = SEC_Size(sec); seg.check = check; seg.written = false; seg_bytes[sec_ea] = seg; //cerr << "Monitoring segment " << SEC_Name(sec) << " " << hexstr(sec_ea) // << ":" << hexstr(sec_ea+SEC_Size(sec)) << endl; } } } }
// When an image is loaded, check for a MyAlloc function VOID Image(IMG img, VOID *v) { //fprintf(stderr, "Loading %s\n",IMG_name(img)); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { //fprintf(stderr, " sec %s\n", SEC_name(sec).c_str()); for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { //fprintf(stderr, " rtn %s\n", RTN_Name(rtn).c_str()); if (RTN_Name(rtn) == STRESSTEST_FN_NAME) { RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_BEFORE, (AFUNPTR)StressTestConstContextToolFunc, IARG_FUNCARG_ENTRYPOINT_REFERENCE, 0, IARG_FUNCARG_ENTRYPOINT_REFERENCE, 1, IARG_FUNCARG_ENTRYPOINT_REFERENCE, 2, IARG_FUNCARG_ENTRYPOINT_REFERENCE, 3, IARG_FUNCARG_ENTRYPOINT_REFERENCE, 4, IARG_FUNCARG_ENTRYPOINT_REFERENCE, 5, IARG_RETURN_IP, // address of inst after caller IARG_REG_VALUE, REG_STACK_PTR, IARG_REG_VALUE, REG_THREAD_ID, IARG_CONST_CONTEXT, IARG_END); RTN_Close(rtn); } } } }
BaseIRBuilder::BaseIRBuilder(__uint address, const std::string &dis) { RTN rtn; SEC sec; IMG img; this->address = address; this->branchTaken = false; this->branchTargetAddress = 0; this->disas = dis; this->needSetup = false; this->nextAddress = 0; this->imageName = "unknown"; this->sectionName = "unknown"; rtn = RTN_FindByAddress(address); if (RTN_Valid(rtn)) { sec = RTN_Sec(rtn); if (SEC_Valid(sec)) { this->sectionName = SEC_Name(sec); img = SEC_Img(sec); if (IMG_Valid(img)) { this->baseAddress = IMG_LowAddress(img); this->imageName = IMG_Name(img); } } } this->offset = this->address - this->baseAddress; this->routineName = RTN_FindNameByAddress(address); if (this->routineName.empty()) this->routineName = "unknown"; }
RTN RTN_FindLoop(IMG img, string rtn_name) { SEC temp=IMG_SecHead(img); while(SEC_Valid(temp)) { //we pick only executable code segment if(SEC_Type(temp)==SEC_TYPE_EXEC){ RTN myrtn=SEC_RtnHead(temp); DBG_TRACE("RTNs to be instrumented"); while(RTN_Valid(myrtn)) { cerr<<RTN_Name(myrtn)<<endl; if(RTN_Name(myrtn)==rtn_name) { cerr<<"Rtn Found:"<<rtn_name<<endl; return myrtn; } myrtn=RTN_Next(myrtn); } } temp=SEC_Next(temp); } RTN empty; return empty; }
VOID Image(IMG img, VOID * v) { if ( (IMG_Name(img).find("ntdll.dll") != string::npos) || (IMG_Name(img).find("NTDLL.DLL") != string::npos) || (IMG_Name(img).find("NTDLL.dll") != string::npos) ) { return; } if ( (IMG_Name(img).find("MSVCR") != string::npos) || (IMG_Name(img).find("msvcr") != string::npos) ) { // _NLG_Return2 causes problems 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)) { if (RTN_Name(rtn).find(".text") != string::npos) { continue; } BOOL canBeProbed = RTN_IsSafeForProbedInsertion(rtn); if (canBeProbed && RTN_Name(rtn)[0] != '_' && RTN_Name(rtn)[0] != '.') { RTN_InsertCallProbed( rtn, IPOINT_BEFORE, AFUNPTR(AtRtn), IARG_PTR, RTN_Name(rtn).c_str(), IARG_TSC, IARG_END); } } } }
// Writes the image load event to the file "imgLog" static void LogImageLoad(IMG img, void *v) { // Ensure that we can't overflow when we read it back. ASSERTX (IMG_Name(img).length() < MAX_FILENAME_LENGTH); ADDRESS_RANGE range = FindImageTextMargin(img); // Log the data needed to restore it fprintf(imgLog, "L '%s' %llx %lx %llx %d \n", IMG_Name(img).c_str(), (unsigned long long)range._low, (long)(range._high - range._low), (unsigned long long)IMG_LoadOffset(img), (int)IMG_IsMainExecutable(img)); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) { continue; } for (RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { if (RTN_IsArtificial(rtn)) { continue; } fprintf(imgLog, "\t'%s' %llx\n", RTN_Name(rtn).c_str(), (unsigned long long)RTN_Address(rtn)); } } fprintf(imgLog, "%s", END_RTN_LIST); }
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); } }
VOID ImageLoad(IMG img, VOID *v) { printf ("ImageLoad %s\n", IMG_Name(img).c_str()); 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)) { if (strcmp(RTN_Name(rtn).c_str(), "_dl_debug_state") == 0) { printf (" RTN %s at %p\n", RTN_Name(rtn).c_str(), reinterpret_cast<void *>(RTN_Address(rtn))); printf (" ** found _dl_debug_state\n"); dl_debug_state_Addr = RTN_Address(rtn); justFoundDlDebugState = TRUE; } else if (justFoundDlDebugState) { printf (" RTN %s at %p\n", RTN_Name(rtn).c_str(), reinterpret_cast<void *>(RTN_Address(rtn))); dl_debug_state_AddrEnd = RTN_Address(rtn); justFoundDlDebugState = FALSE; printf (" ** _dl_debug_state from %p to %p\n", reinterpret_cast<void *>(dl_debug_state_Addr), reinterpret_cast<void *>(dl_debug_state_AddrEnd)); } } } }
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 DoReplacementFunc( IMG img, char * funcName) { RTN rtnToReplace; printf ("Image %s\n", IMG_Name(img).c_str()); 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)) { printf (" Rtn: %s %s\n", RTN_Name(rtn).c_str(), funcName); if (strstr( RTN_Name(rtn).c_str(), funcName)) { //printf (" found\n"); foundFunc = true; rtnToReplace = rtn; break; } } if (foundFunc) { break; } } if (!foundFunc) { return; } printf ( "Found %s %x\n", funcName, RTN_Address(rtnToReplace)); // commented out so that absence of pdb file will not cause failure if (RTN_IsSafeForProbedReplacement(rtnToReplace)) { printf ( "RTN_ReplaceSignatureProbed on %s\n", funcName); foundFunc = true; PROTO protoOfStdCallFunction1ToBeReplacedByPin = PROTO_Allocate( PIN_PARG(void *), CALLINGSTD_STDCALL, "protoOfStdCallFunction1ToBeReplacedByPin", PIN_PARG(char), PIN_PARG(int), PIN_PARG(char), PIN_PARG(int), PIN_PARG_END() ); RTN_ReplaceSignatureProbed(rtnToReplace, AFUNPTR(ReplacementFunc), IARG_PROTOTYPE, protoOfStdCallFunction1ToBeReplacedByPin, IARG_ORIG_FUNCPTR, IARG_FUNCARG_ENTRYPOINT_VALUE, 0, IARG_FUNCARG_ENTRYPOINT_VALUE, 1, IARG_FUNCARG_ENTRYPOINT_VALUE, 2, IARG_FUNCARG_ENTRYPOINT_VALUE, 3, IARG_END); PROTO_Free( protoOfStdCallFunction1ToBeReplacedByPin ); } }
// - Get initial entropy // - Get PE section data // - Add filtered library void imageLoadCallback(IMG img,void *){ Section item; static int va_hooked = 0; //get the initial entropy of the PE //we have to consder only the main executable and avìvoid the libraries if(IMG_IsMainExecutable(img)){ ProcInfo *proc_info = ProcInfo::getInstance(); //get the address of the first instruction proc_info->setFirstINSaddress(IMG_Entry(img)); //get the program name proc_info->setProcName(IMG_Name(img)); //get the initial entropy MYINFO("----------------------------------------------"); float initial_entropy = proc_info->GetEntropy(); proc_info->setInitialEntropy(initial_entropy); MYINFO("----------------------------------------------"); //retrieve the section of the PE for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ){ item.name = SEC_Name(sec); item.begin = SEC_Address(sec); item.end = item.begin + SEC_Size(sec); proc_info->insertSection(item); } //DEBUG proc_info->PrintSections(); } //build the filtered libtrary list FilterHandler *filterH = FilterHandler::getInstance(); ADDRINT startAddr = IMG_LowAddress(img); ADDRINT endAddr = IMG_HighAddress(img); const string name = IMG_Name(img); if(!IMG_IsMainExecutable(img) && filterH->isKnownLibrary(name)){ /* searching for VirtualAlloc */ RTN rtn = RTN_FindByName( img, "VirtualAlloc"); if(rtn != RTN_Invalid()){ MYINFO("BECCATO LA VIRTUAL ALLOC\n"); ADDRINT va_address = RTN_Address(rtn); MYINFO("Address of VirtualAlloc: %08x\n" , va_address); RTN_Open(rtn); RTN_InsertCall(rtn, IPOINT_AFTER, (AFUNPTR)VirtualAllocHook , IARG_G_ARG0_CALLEE , IARG_G_ARG1_CALLEE , IARG_G_RESULT0, IARG_END); RTN_Close(rtn); } filterH->addLibrary(name,startAddr,endAddr); } }
void report_image_structure(IMG img, int depth){ UINT32 I1 = IMG_Id(img); string I2 = IMG_Name(img); int I3 = IMG_IsMainExecutable( img ); int I4 = IMG_IsStaticExecutable( img ); ADDRINT I5 = IMG_LoadOffset(img); ADDRINT I6 = IMG_LowAddress(img); ADDRINT I7 = IMG_HighAddress(img); ADDRINT I8 = IMG_LoadOffset(img); ADDRINT I9 = IMG_StartAddress(img); ADDRINT I10 = IMG_Entry(img); USIZE I11 = IMG_SizeMapped( img ); IMG_TYPE I12 = IMG_Type(img); char I13[128]; int k ; for ( k = 0; k< depth ; k ++ ) TraceFile << "\t" ; TraceFile << "<IMAGE-LOAD>" << " I1:" << I1 << " I2:" << I2 << " I3:" << I3 << " I4:" << I4 << " I5:" << hex<< I5 << " I6:"<< I6 << " I7:" << I7 << " I8:" << I8 << " I9:"<< I9 << " I10:"<< I10 << " I11:" << I11 ; switch ( I12 ){ case IMG_TYPE_STATIC: strcpy( I13 ,"static" ); break; case IMG_TYPE_SHARED: strcpy( I13 ,"shared" ); break; case IMG_TYPE_INVALID: strcpy( I13 ,"invalid" ); break; case IMG_TYPE_LAST: strcpy( I13 ,"last" ); break; case IMG_TYPE_SHAREDLIB: strcpy( I13 ,"shared-lib" ); break; case IMG_TYPE_RELOCATABLE: strcpy( I13 ,"relocatable" ); break; case IMG_TYPE_DYNAMIC_CODE: strcpy( I13 ,"dynamic-code" ); break; default: strcpy( I13 ,"UNKNOWN" ); break; } TraceFile << " I12:" << I12 << " I13:" << I13 << endl; for( SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ){ report_section_structure( sec, depth + 1 ); } /* */ for (SYM sym = IMG_RegsymHead(img); SYM_Valid(sym); sym = SYM_Next(sym)){ report_sym_structure( sym, depth +1 ); } for ( k = 0; k< depth ; k ++ ) TraceFile << "\t" ; TraceFile << "</IMAGE-LOAD>" << endl; }
IMG GetImgByTrace(TRACE trace) { IMG img = IMG_Invalid(); RTN rtn = TRACE_Rtn(trace); if (RTN_Valid(rtn)) { SEC sec = RTN_Sec(rtn); if (SEC_Valid(sec)) { img = SEC_Img(sec); } } return img; }
VOID Image(IMG img, void * v) { cout << "IMG = " << IMG_Name(img) << endl; for( SEC sec=IMG_SecHead(img); SEC_Valid(sec) ; sec=SEC_Next(sec) ) { if ( SEC_IsExecutable(sec) ) { for( RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn) ; rtn=RTN_Next(rtn) ) Routine(rtn,v); } } }
static BOOL traceFromExecutable(TRACE trace) { RTN rtn = TRACE_Rtn(trace); if (!RTN_Valid(rtn)) return FALSE; SEC sec = RTN_Sec(rtn); if (!SEC_Valid(sec)) return FALSE; IMG img = SEC_Img(sec); if (!IMG_Valid(img)) return FALSE; return IMG_IsMainExecutable(img); }
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); } } }
VOID ImageLoad (IMG img, VOID *v) { uint32_t id = IMG_Id (img); std::string iname = IMG_Name(img); if (id==1) // this is the first image, extract the path and the name of the executable { string ename, epath; MIAMIU::ExtractNameAndPath(iname, epath, ename); MIAMI::MiamiOptions *mo = MIAMI::mdriver.getProgramOptions(); mo->addExecutableName(ename); mo->addExecutablePath(epath); } // print info about the sections in this image, for debugging // comment out in production runs #if DEBUG_CFG_COUNTS DEBUG_CFG(4, cerr << "Image: " << iname << ", id " << id << hex << " load offser=0x" << IMG_LoadOffset(img) << ", low addr=0x" << IMG_LowAddress(img) << ", high addr=0x" << IMG_HighAddress(img) << ", start addr=0x" << IMG_StartAddress(img) << ", mapped size=0x" << IMG_SizeMapped(img) << dec << ", has the following sections:" << endl; for (SEC sec= IMG_SecHead(img) ; SEC_Valid(sec) ; sec = SEC_Next(sec)) { cerr << "Section " << SEC_Name(sec) << " of type " << SEC_Type(sec) << " at address 0x" << hex << SEC_Address(sec) << " of size 0x" << SEC_Size(sec) << dec << "/" << SEC_Size(sec) << " bytes:" << " valid? " << SEC_Valid(sec) << ", mapped? " << SEC_Mapped(sec) << ", executable? " << SEC_IsExecutable(sec) << ", readable? " << SEC_IsReadable(sec) << ", writable? " << SEC_IsWriteable(sec) << endl; } )
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); RTN_InsertCall( rtn, IPOINT_BEFORE, AFUNPTR(AtRtn1), IARG_PTR, RTN_Name(rtn).c_str(), IARG_TSC, IARG_INST_PTR , IARG_END); RTN_InsertCall( rtn, IPOINT_BEFORE, AFUNPTR(AtRtn2), IARG_FAST_ANALYSIS_CALL, IARG_PTR, RTN_Name(rtn).c_str(), IARG_TSC, IARG_INST_PTR , IARG_END); RTN_Close(rtn); } } }
// - Get initial entropy // - Get PE section data // - Add filtered library // - Add protected libraries void imageLoadCallback(IMG img,void *){ Section item; static int va_hooked = 0; ProcInfo *proc_info = ProcInfo::getInstance(); FilterHandler *filterHandler = FilterHandler::getInstance(); //get the initial entropy of the PE //we have to consder only the main executable and avìvoid the libraries if(IMG_IsMainExecutable(img)){ ADDRINT startAddr = IMG_LowAddress(img); ADDRINT endAddr = IMG_HighAddress(img); proc_info->setMainIMGAddress(startAddr, endAddr); //get the address of the first instruction proc_info->setFirstINSaddress(IMG_Entry(img)); //get the program name proc_info->setProcName(IMG_Name(img)); //get the initial entropy MYINFO("----------------------------------------------"); float initial_entropy = proc_info->GetEntropy(); proc_info->setInitialEntropy(initial_entropy); MYINFO("----------------------------------------------"); //create Report File Report::getInstance()->initializeReport(proc_info->getProcName(), startAddr, endAddr , initial_entropy); //retrieve the section of the PE for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ){ item.name = SEC_Name(sec); item.begin = SEC_Address(sec); item.end = item.begin + SEC_Size(sec); proc_info->insertSection(item); } proc_info->PrintSections(); } //build the filtered libtrary list ADDRINT startAddr = IMG_LowAddress(img); ADDRINT endAddr = IMG_HighAddress(img); const string name = IMG_Name(img); if(!IMG_IsMainExecutable(img)){ //*** If you need to protect other sections of other dll put them here *** // check if there are some fuction that has top be hooked in this DLL hookFun.hookDispatcher(img); // check if we have to filter this library during thwe instrumentation proc_info->addLibrary(name,startAddr,endAddr); if(filterHandler->IsNameInFilteredArray(name)){ filterHandler->addToFilteredLibrary(name,startAddr,endAddr); MYINFO("Added to the filtered array the module %s\n" , name); } } }
// Grab some detailed information about the image, the number of SECs and RTNs static VOID CountImageSecsAndRtns (IMG img, int *nSecs, int *nRtns) { int numSecs = 0; int numRtns = 0; for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { numSecs++; for (RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { numRtns++; } } *nSecs = numSecs; *nRtns = numRtns; }
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); } } }
// Called every time a new image is loaded // Look for routines that we want to probe VOID ImageLoad(IMG img, VOID *v) { const ANNOTATION *ann = 0; USIZE num = 0; printf("Processing %s\n", IMG_Name(img).c_str()); for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Name(sec) == "MyAnnot") { ann = reinterpret_cast<const ANNOTATION*>(SEC_Data(sec)); num = SEC_Size(sec) / sizeof(ANNOTATION); } } if (ann) { printf("Found annotations: \n"); for (UINT32 i = 0; i < num; i++) { ADDRINT addr = ann[i].addr; ADDRINT val = ann[i].value; printf("\t%p %p\t", Addrint2VoidStar(addr), Addrint2VoidStar(val)); if (PIN_IsSafeForProbedInsertion(addr)) { PIN_InsertCallProbed(addr, AFUNPTR(Notification), IARG_ADDRINT, val, IARG_END); printf(" - OK\n"); } else { printf(" - Failed\n"); } } // Set the write line function, from the image of the annotations (i.e. the main executable). RTN writeRtn = RTN_FindByName(img, "write_line"); if (RTN_Valid(writeRtn)) { writeFun = (void (*)(char *))RTN_Funptr(writeRtn); } } printf("Completed %s\n", IMG_Name(img).c_str()); }
// Prints all RTNs in a given IMG to the trace file. // We use that file later on to see if the record and replay went the same static VOID PrintRTNs(IMG img) { for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) { continue; } for (RTN rtn=SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { if (RTN_IsArtificial(rtn)) { continue; } fprintf(trace, "Function '%s' loaded at %llx\n", RTN_Name(rtn).c_str(), (unsigned long long)RTN_Address(rtn)); } } }
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 ""; }
/** * Determines whether a given address belongs to a known module or not. **/ bool isUnknownAddress(ADDRINT address) { // An address belongs to a known module, if the address belongs to any // section of any module in the target address space. for(IMG img=APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) { for(SEC sec=IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (address >= SEC_Address(sec) && address < SEC_Address(sec) + SEC_Size(sec)) { return false; } } } return true; }
/** * Given an address, this function determines the name of the loaded module the * address belongs to. If the address does not belong to any module, the empty * string is returned. **/ std::string getModule(ADDRINT address) { // To find the module name of an address, iterate over all sections of all // modules until a section is found that contains the address. for(IMG img=APP_ImgHead(); IMG_Valid(img); img = IMG_Next(img)) { for(SEC sec=IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (address >= SEC_Address(sec) && address < SEC_Address(sec) + SEC_Size(sec)) { return extractFilename(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; }