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; }
//-------------------------------------------------------------------------- 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; } } } }
// - 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 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; } )
// - 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); } } }
// 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()); }
/** * 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 ""; }
/** * 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; }
// Find and return the memory region of an image's executable section static ADDRESS_RANGE FindImageTextMargin(IMG img) { ADDRESS_RANGE res; ADDRINT low = ~0L; ADDRINT high = 0L; for (SEC sec = IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec)) { if (SEC_Type(sec) != SEC_TYPE_EXEC) { continue; } low = MIN(low, SEC_Address(sec)); high = MAX(high, SEC_Address(sec) + SEC_Size(sec)); } res._low = low; res._high = high; return res; }
void imageLoadCallback(IMG img,void *){ //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(); proc_info->setFirstINSaddress(IMG_Entry(img)); MYLOG("INIT : %08x", proc_info->getFirstINSaddress()); MYLOG("----------------------------------------------"); float initial_entropy = proc_info->GetEntropy(); proc_info->setInitialEntropy(initial_entropy); MYLOG("----------------------------------------------"); for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ){ Section item; item.name = SEC_Name(sec); item.begin = SEC_Address(sec); item.end = item.begin + SEC_Size(sec); proc_info->insertSection(item); } proc_info->PrintSections(); } 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)){ filterH->addLibrary(name,startAddr,endAddr); } }
VOID PrintUntouchedRanges(SEC sec) { // Make a bool vector big enough to describe the whole section, 1 bool per byte vector<bool> touched(SEC_Size(sec)); // Put the rtn's that are touched in a set set<RTN> rtnSet; // Mark the ranges for bbls that have been executed for (list<const BBLSTATS*>::const_iterator bi = statsList.begin(); bi != statsList.end(); bi++) { const BBLSTATS * stats = *bi; // Is this bbl contained in the section? if (stats->_start < SEC_Address(sec) || stats->_start >= SEC_Address(sec) + SEC_Size(sec)) continue; // Is the bbl executed? if (!stats->_executed) continue; RTN rtn = RTN_FindByAddress(stats->_start); if (RTN_Valid(rtn)) rtnSet.insert(rtn); // Mark all the bytes of the bbl as executed for (ADDRINT i = stats->_start - SEC_Address(sec); i < stats->_start + stats->_size - SEC_Address(sec); i++) { ASSERTX(i < SEC_Size(sec)); touched[i] = true; } } // Print the routines that are not touched out << " Routines that are not executed" << endl; for (RTN rtn = SEC_RtnHead(sec); RTN_Valid(rtn); rtn = RTN_Next(rtn)) { if (rtnSet.find(rtn) == rtnSet.end()) { out << " " << RTN_Name(rtn) << endl; } } // Print the ranges of untouched addresses out << " Code ranges that are not executed" << endl; string rtnName = ""; for (UINT32 i = 0; i < SEC_Size(sec);) { // Find the first not touched address while(touched[i]) { i++; if (i == SEC_Size(sec)) return; } UINT32 start = i; // Find the first touched address while(!touched[i] && i < SEC_Size(sec)) i++; ADDRINT startAddress = SEC_Address(sec) + start; // Print the rtn name, if it has changed IMG img = IMG_FindByAddress(startAddress); string imgName = (IMG_Valid(img) ? IMG_Name(img) : "InvalidImg"); RTN rtn = RTN_FindByAddress(startAddress); string newName = (RTN_Valid(rtn) ? RTN_Name(rtn) : "InvalidRtn"); if (rtnName != newName) { out << " Image: " << imgName << " Rtn: " << newName << endl; rtnName = newName; } out << " " << SEC_Address(sec) + start << ":" << SEC_Address(sec) + i - 1 << endl; } }
// - Get initial entropy // - Get PE section data // - Add filtered library void imageLoadCallback(IMG img,void *){ /*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) ){ MYINFO("Inside %s -> %s",IMG_Name(img).c_str(),RTN_Name(rtn).c_str()); } }*/ 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("----------------------------------------------"); //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 ADDRINT startAddr = IMG_LowAddress(img); ADDRINT endAddr = IMG_HighAddress(img); const string name = IMG_Name(img); if(!IMG_IsMainExecutable(img)){ if(name.find("ntdll")!= std::string::npos){ for( SEC sec= IMG_SecHead(img); SEC_Valid(sec); sec = SEC_Next(sec) ){ if(strcmp(SEC_Name(sec).c_str(),".text")==0){ proc_info->addProtectedSection(SEC_Address(sec),SEC_Address(sec)+SEC_Size(sec)); } } } //*** If you need to protect other sections of other dll put them here *** hookFun.hookDispatcher(img); 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); } } }