int main(int argc, char * argv[]){ //If we want to debug the program manually setup the proper options in order to attach an external debugger if(Config::ATTACH_DEBUGGER){ initDebug(); } MYINFO("Strating prototype ins"); FilterHandler *filterH = FilterHandler::getInstance(); //set the filters for the libraries MYINFO("%s",Config::FILTER_WRITES_ENABLES.c_str()); filterH->setFilters(Config::FILTER_WRITES_ENABLES); //get the start time of the execution (benchmark) tStart = clock(); // Initialize pin PIN_InitSymbols(); if (PIN_Init(argc, argv)) return Usage(); INS_AddInstrumentFunction(Instruction,0); PIN_AddThreadStartFunction(OnThreadStart, 0); // Register ImageUnload to be called when an image is unloaded IMG_AddInstrumentFunction(imageLoadCallback, 0); // Register Fini to be called when the application exits PIN_AddFiniFunction(Fini, 0); // Start the program, never returns PIN_StartProgram(); return 0; }
void OS::event_loop() { while (power_) { int rc; // add a global symbol here so we can quickly discard // event loop from stack sampling asm volatile( ".global _irq_cb_return_location;\n" "_irq_cb_return_location:" ); // XXX: temporarily ALWAYS sleep for 0.5 ms. We should ideally ask Timers // for the next immediate timer to fire (the first from the "scheduled" list // of timers?) rc = solo5_poll(solo5_clock_monotonic() + 500000ULL); // now + 0.5 ms Timers::timers_handler(); if (rc) { for(auto& nic : hw::Devices::devices<hw::Nic>()) { nic->poll(); break; } } } MYINFO("Stopping service"); Service::stop(); MYINFO("Powering off"); solo5_poweroff(); }
// print the sections information in a fancy way void ProcInfo::PrintSections(){ MYINFO("======= SECTIONS ======= \n"); for(unsigned int i = 0; i < this->Sections.size(); i++) { Section item = this->Sections.at(i); MYINFO("%s -> begin : %08x end : %08x", item.name.c_str(), item.begin, item.end); } MYINFO("================================= \n"); }
/* Add a section of a module ( for example the .text of the NTDLL ) in order to catch writes/reads inside this area */ VOID ProcInfo::addProtectedSection(ADDRINT startAddr,ADDRINT endAddr){ Section s; s.begin = startAddr; s.end = endAddr; s.name = ".text"; MYINFO("Protected section size is %d\n" , this->protected_section.size()); protected_section.push_back(s); MYINFO("Protected section size is %d\n" , this->protected_section.size()); }
VOID VirtualProtectHook (W::LPVOID baseAddress, W::DWORD size, W::PDWORD oldProtection, BOOL* success) { MYINFO("calling Virutalprotect at address %08x -> %08x",(ADDRINT)baseAddress,size + (ADDRINT)baseAddress); FakeReadHandler* fake_memory_handler = new FakeReadHandler(); if (!fake_memory_handler->isAddrInWhiteList((ADDRINT)baseAddress) && success && *success && oldProtection) { *success = 0; *oldProtection = NULL; } MYINFO("calling Virutalprotect at address %08x -> %08x",(ADDRINT)baseAddress,size + (ADDRINT)baseAddress); }
EXCEPT_HANDLING_RESULT ExceptionHandler(THREADID tid, EXCEPTION_INFO *pExceptInfo, PHYSICAL_CONTEXT *pPhysCtxt, VOID *v){ MYINFO("ECC!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); MYINFO("%s",PIN_ExceptionToString(pExceptInfo).c_str()); MYINFO("ECC!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); return EHR_CONTINUE_SEARCH; }
BOOL followChild(CHILD_PROCESS childProcess, VOID *val) { printf("[INFO] A new process has been spawned!\n"); MYINFO("---------------------------------------------------"); MYINFO("-----------A NEW PROCESS HAS BEEN SPAWNED----------"); MYINFO("-------------[PinDemonium injected]---------------"); MYINFO("---------------------------------------------------"); return 1; }
// This function is called when the application exits VOID Fini(INT32 code, VOID *v){ //DEBUG --- inspect the write set at the end of the execution WxorXHandler *wxorxHandler = WxorXHandler::getInstance(); MYINFO("WRITE SET SIZE: %d", wxorxHandler->getWritesSet().size()); //DEBUG --- get the execution time MYINFO("Total execution Time: %.2fs", (double)(clock() - tStart)/CLOCKS_PER_SEC); CLOSELOG(); Config *config = Config::getInstance(); config->closeReportFile(); }
void OS::start() { // Initialize serial port com1.init(); // Print a fancy header FILLINE('='); CAPTION("#include<os> // Literally\n"); FILLINE('='); debug("\t[*] OS class started\n"); srand(time(NULL)); // Heap extern caddr_t heap_end; extern char _end; MYINFO("Heap start: @ %p", heap_end); MYINFO("Current end is: @ %p", &_end); atexit(default_exit); // Set up interrupt handlers IRQ_manager::init(); // Initialize the Interval Timer hw::PIT::init(); // Initialize PCI devices PCI_manager::init(); /** Estimate CPU frequency MYINFO("Estimating CPU-frequency"); INFO2("|"); INFO2("+--(10 samples, %f sec. interval)", (hw::PIT::frequency() / _cpu_sampling_freq_divider_).count()); INFO2("|"); // TODO: Debug why actual measurments sometimes causes problems. Issue #246. cpu_mhz_ = hw::PIT::CPUFrequency(); INFO2("+--> %f MHz", cpu_mhz_.count()); **/ MYINFO("Starting %s", Service::name().c_str()); FILLINE('='); // Everything is ready Service::start(); event_loop(); }
// - 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 Service::start(const std::string&) { MYINFO("Running CPUID..."); auto detected_features = CPUID::detect_features_str(); MYINFO("Detected %lu CPU features:", detected_features.size()); for (auto f : detected_features) printf("%s %s", f, f == detected_features.back() ? "" : ", "); printf("\n"); }
void Service::start(const std::string&) { const auto number_of_failed_tests = lest::run(ipv4_module_test, {"-p"}); if (number_of_failed_tests) { printf("%d %s failed\n", number_of_failed_tests, (number_of_failed_tests == 1 ? "test has" : "tests have")); MYINFO("FAILURE"); } else { printf("%s\n", "All tests passed"); MYINFO("SUCCESS"); } }
/** Set the filter which will be activated stack: filter all instructions which belong to libraries and write on the stack teb: filter all instructions which belong to libraries and write on the TEB (Exception Handling) **/ VOID FilterHandler::setFilters(const string filters){ MYINFO("Setting write filters" ); vector<string> filterVect; stringstream ss(filters); string temp; while (ss >> temp){ filterVect.push_back(temp); } for(std::vector<string>::iterator filt = filterVect.begin(); filt != filterVect.end(); ++filt) { MYINFO("Activating filter %s",(*filt).c_str() ); filterExecutionFlag += pow(2.0,filterMap[*filt]); //bitmap representing active flags } }
ADDRINT handleWrite(ADDRINT eip, ADDRINT write_addr,void *fakeWriteH){ FakeWriteHandler fakeWrite = *(FakeWriteHandler *)fakeWriteH; //get the new address of the memory operand (same as before if it is inside the whitelist otherwise a NULL poiter) ADDRINT fakeAddr = fakeWrite.getFakeWriteAddress(write_addr); if(write_addr == 0){ return write_addr; // let the program trigger its exception if it want } if(fakeAddr != write_addr){ MYTEST("handleWrite_evasion %08x",write_addr); MYINFO("suspicious write from %08x in %s in %08x redirected to %08x", eip, RTN_FindNameByAddress(write_addr).c_str(), write_addr, fakeAddr); MYINFO("Binary writes %08x\n" , *(unsigned int *)(fakeAddr)); } return fakeAddr; }
int main(int argc, char * argv[]){ //If we want to debug the program manually setup the proper options in order to attach an external debugger if(Config::ATTACH_DEBUGGER){ initDebug(); } MYINFO("->Configuring Pintool<-\n"); //get the start time of the execution (benchmark) tStart = clock(); // Initialize pin PIN_InitSymbols(); if (PIN_Init(argc, argv)) return Usage(); //Register PIN Callbacks INS_AddInstrumentFunction(Instruction,0); //TRACE_AddInstrumentFunction(Trace,0); PIN_AddThreadStartFunction(OnThreadStart, 0); IMG_AddInstrumentFunction(imageLoadCallback, 0); PIN_AddFiniFunction(Fini, 0); PIN_AddInternalExceptionHandler(ExceptionHandler,NULL); //get theknob args ConfigureTool(); if(Config::getInstance()->POLYMORPHIC_CODE_PATCH){ TRACE_AddInstrumentFunction(Trace,0); } proc_info->addProcAddresses(); //init the hooking system HookSyscalls::enumSyscalls(); HookSyscalls::initHooks(); // Start the program, never returns MYINFO("->Starting instrumented program<-\n"); PIN_StartProgram(); return 0; }
void OS::event_loop() { Events::get(0).process_events(); do { OS::halt(); Events::get(0).process_events(); } while (power_); MYINFO("Stopping service"); Service::stop(); MYINFO("Powering off"); extern void __arch_poweroff(); __arch_poweroff(); }
// - 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); } } }
//Adding the SharedMemoryAddress to the generic Memory Ranges VOID ProcInfo::addSharedMemoryAddress(){ MemoryRange readOnlySharedMemoryBase; if(getMemoryRange((ADDRINT) peb->ReadOnlySharedMemoryBase,readOnlySharedMemoryBase)){ MYINFO("Init readOnlySharedMemoryBase base address %08x -> %08x",readOnlySharedMemoryBase.StartAddress,readOnlySharedMemoryBase.EndAddress); genericMemoryRanges.push_back(readOnlySharedMemoryBase); } }
//Adding the CodePageDataAddress to the generic Memory Ranges VOID ProcInfo::addCodePageDataAddress(){ MemoryRange ansiCodePageData; if(getMemoryRange((ADDRINT) peb->AnsiCodePageData,ansiCodePageData)){ MYINFO("Init ansiCodePageData base address %08x -> %08x",ansiCodePageData.StartAddress,ansiCodePageData.EndAddress); genericMemoryRanges.push_back(ansiCodePageData); } }
//Add dynamically created mapped files to the mapped files list VOID ProcInfo::addMappedFilesAddress(ADDRINT startAddr){ MemoryRange mappedFile; if(getMemoryRange((ADDRINT)startAddr,mappedFile)){ MYINFO("Adding mappedFile base address %08x -> %08x ",mappedFile.StartAddress,mappedFile.EndAddress); mappedFiles.push_back(mappedFile); } }
/** Initializing the base stack address **/ VOID FilterHandler::setStackBase(ADDRINT addr){ //hasn't been already initialized if(stackBase == 0) { stackBase = addr; MYINFO("Init FilterHandler Stack from %x to %x",stackBase+STACK_BASE_PADDING,stackBase -MAX_STACK_SIZE); } }
VOID VirtualFreeHook(UINT32 address_to_free){ MYINFO("Have to free the address %08x\n" , address_to_free); ProcInfo *pInfo = ProcInfo::getInstance(); std::vector<HeapZone> HeapMap = pInfo->getHeapMap(); int index_to_remove = -1; MYINFO("HeapZone before free"); for(unsigned index=0; index < HeapMap.size(); index++) { if(address_to_free == pInfo->getHeapZoneByIndex(index)->begin){ index_to_remove = index; } } if(index_to_remove != -1){ pInfo->deleteHeapZone(index_to_remove); } MYINFO("HeapZone after free"); }
void DHClient::acknowledge(const char* data, size_t) { const dhcp_packet_t* dhcp = (const dhcp_packet_t*) data; uint32_t xid = htonl(dhcp->xid); // silently ignore transactions not our own if (xid != this->xid) return; // check if the BOOTP message is a DHCP OFFER const dhcp_option_t* opt; opt = get_option(dhcp->options, DHO_DHCP_MESSAGE_TYPE); if (opt->code == DHO_DHCP_MESSAGE_TYPE) { // verify that the type is indeed DHCPOFFER debug("\tFound DHCP message type %d (DHCP Ack = %d)\n", opt->val[0], DHCPACK); // ignore when not a DHCP Offer if (opt->val[0] != DHCPACK) return; } // ignore message when DHCP message type is missing else return; if (console_spam) MYINFO("Server acknowledged our request!"); // configure our network stack stack.network_config(this->ipaddr, this->netmask, this->router, this->dns_server); // stop timeout from happening hw::PIT::stop(timeout); // run some post-DHCP event to release the hounds this->config_handler(false); }
void FilterHandler::addToFilteredLibrary(std::string name , ADDRINT start_addr , ADDRINT end_addr){ LibraryItem li; li.StartAddress = start_addr; li.EndAddress = end_addr; li.name = name; this->filtered_libray.push_back(li); MYINFO("filtered library size is %d\n" , this->filtered_libray.size()); }
BOOL ProcessInjectionModule::isInsideCreateProcess(){ if(insideCreateProcess && remoteWriteInsideCreateProcess<3){ MYINFO("1. InsideCreateProcess %d remoteWrite %d",insideCreateProcess,remoteWriteInsideCreateProcess); remoteWriteInsideCreateProcess++; return true; } else if(remoteWriteInsideCreateProcess & remoteWriteInsideCreateProcess ==3 ){ MYINFO("2. InsideCreateProcess %d remoteWrite %d",insideCreateProcess,remoteWriteInsideCreateProcess); remoteWriteInsideCreateProcess = 0; insideCreateProcess =false; return false; } else{ MYINFO("3. InsideCreateProcess %d remoteWrite %d",insideCreateProcess,remoteWriteInsideCreateProcess); return false; } }
VOID ProcessInjectionModule::CheckInjectedExecution(W::DWORD pid ){ std::vector<WriteInterval>& currentWriteSet = WxorXHandler::getInstance()->getWxorXintervalInjected(pid); if(!currentWriteSet.empty()){ MYINFO("Identify Injected execution %d",pid); HandleInjectedMemory(currentWriteSet,pid); wxorxHandler->clearWriteSet(pid); //clear the dumped writeItems from the current WriteSet } }
VOID VirtualAllocHook(UINT32 arg0, UINT32 virtual_alloc_size , UINT32 ret_heap_address ){ MYINFO("INSIDE THE INSTRUMENTATION OF VIRTUAL ALLOC\n"); MYINFO("size : %08x" , virtual_alloc_size); MYINFO("return address : %08x" , ret_heap_address); ProcInfo *proc_info = ProcInfo::getInstance(); HeapZone hz; hz.begin = ret_heap_address; hz.size = virtual_alloc_size; hz.end = ret_heap_address + virtual_alloc_size; //saving this heap zone in the map inside ProcInfo proc_info->insertHeapZone(hz); }
BOOL YaraHeuristic::launchYara(std::string yara_path, std::string yara_rules_path, std::string yara_input_path,std::string yara_output,W::PROCESS_INFORMATION * piResults){ //string YaraLauncherBat = Config::getInstance()->getBasePath() + YARA_LAUNCHER; //Running external idaPython script W::STARTUPINFO si ={0}; si.hStdOutput = g_hChildStd_OUT_Wr; si.dwFlags |= STARTF_USESTDHANDLES; W::PROCESS_INFORMATION pi ={0}; si.cb=sizeof(si); //NB There can be problem if using spaces inside the path std::string yara_arguments = yara_path + " " + //path to yara executable yara_rules_path + " " + //path to yara rules yara_input_path; //path to yara input file // Create a file batch which run the IdaPython script and execute it /*FILE *YaraLauncherFile = fopen(YaraLauncherBat.c_str(),"w"); fwrite(YaraLauncher.c_str(),strlen(YaraLauncher.c_str()),1,YaraLauncherFile); fclose(YaraLauncherFile);*/ MYINFO("Launching Yara executable %s command line %s ",yara_path.c_str(),yara_arguments.c_str()); if(!W::CreateProcess(yara_path.c_str(),(char *)yara_arguments.c_str(),NULL,NULL,TRUE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)){ MYERRORE("Can't launch Yara Error %d",W::GetLastError()); return false; } //Timeout 30 sec for the YARA processing W::WaitForSingleObject(pi.hProcess,30000); W::CloseHandle(pi.hProcess); W::CloseHandle(pi.hThread); W::CloseHandle(g_hChildStd_OUT_Wr); *piResults = pi; MYINFO("Yara Finished"); return true; }
//Adding the ContextData to the generic Memory Ranges VOID ProcInfo::addContextDataAddress(){ MemoryRange activationContextData; MemoryRange systemDefaultActivationContextData ; MemoryRange pContextData; if(getMemoryRange((ADDRINT)peb->ActivationContextData,activationContextData)){ MYINFO("Init activationContextData base address %08x -> %08x ",activationContextData.StartAddress,activationContextData.EndAddress); genericMemoryRanges.push_back(activationContextData); } if (getMemoryRange((ADDRINT)peb->SystemDefaultActivationContextData,systemDefaultActivationContextData)){ MYINFO("Init systemDefaultActivationContextData base address %08x -> %08x",systemDefaultActivationContextData.StartAddress,systemDefaultActivationContextData.EndAddress); genericMemoryRanges.push_back(systemDefaultActivationContextData); } if(getMemoryRange((ADDRINT)peb->pContextData,pContextData)){ MYINFO("Init pContextData base address %08x -> %08x",pContextData.StartAddress,pContextData.EndAddress); genericMemoryRanges.push_back(pContextData); } }
// print the whitelisted memory in a fancy way void ProcInfo::PrintWhiteListedAddr(){ //Iterate through the already whitelisted memory addresses for(std::vector<MemoryRange>::iterator item = genericMemoryRanges.begin(); item != genericMemoryRanges.end(); ++item) { MYINFO("[MEMORY RANGE]Whitelisted %08x -> %08x\n",item->StartAddress,item->EndAddress); } for(std::vector<HeapZone>::iterator item = this->HeapMap.begin(); item != this->HeapMap.end(); ++item) { MYINFO("[HEAPZONES]Whitelisted %08x -> %08x\n",item->begin,item->end); } for(std::vector<LibraryItem>::iterator item = this->unknownLibraries.begin(); item != this->unknownLibraries.end(); ++item) { MYINFO("[UNKNOWN LIBRARY ITEM]Whitelisted %08x -> %08x\n",item->StartAddress,item->EndAddress); } for(std::vector<LibraryItem>::iterator item = this->knownLibraries.begin(); item != this->knownLibraries.end(); ++item) { MYINFO("[KNOWN LIBRARY ITEM]Whitelisted %08x -> %08x\n",item->StartAddress,item->EndAddress); } for(std::vector<MemoryRange>::iterator item = this->mappedFiles.begin(); item != this->mappedFiles.end(); ++item) { MYINFO("[MAPPED FILES]Whitelisted %08x -> %08x\n",item->StartAddress,item->EndAddress); } }