RAOptConfig::RAOptConfig ( HINSTANCE inst, HWND parent ) { int res; #ifdef _WIN32 res = DialogBox(inst,RAOptConfigDlgName,parent,FARPROC(RAOptConfigDlgProc)); #else DLGPROC thunk = MakeProcInstance(FARPROC(RAOptConfigDlgProc),inst); res = DialogBox(inst,RAOptConfigDlgName,parent,thunk); FreeProcInstance(thunk); #endif if (res) Valid = true; else Valid = false; PopSize = DefPopSize; TestSize = DefTestSize; ReptFreq = DefReptFreq; MinState = DefMinState; MaxState = DefMaxState; MaxMoves = DefMaxMoves; MuteRate = DefMuteRate; WeightO = DefWeightO; WeightT = DefWeightT; WeightA = DefWeightA; WeightD = DefWeightD; WeightN = DefWeightN; FitScale = DefFitScale; FitLinBase = DefFitLinBase; FitLinDec = DefFitLinDec; FitLinMin = DefFitLinMin; }
QString CCrashStack::GetCallStack(PEXCEPTION_POINTERS pException) { PBYTE Module_Addr_1; char bufer[256]={0}; QString sRet; typedef struct STACK { STACK * Ebp; PBYTE Ret_Addr; DWORD Param[0]; } STACK, * PSTACK; STACK Stack = {0, 0}; PSTACK Ebp; if (pException) //fake frame for exception address { Stack.Ebp = (PSTACK)pException->ContextRecord->Ebp; Stack.Ret_Addr = (PBYTE)pException->ExceptionRecord->ExceptionAddress; Ebp = &Stack; } else { Ebp = (PSTACK)&pException - 1; //frame addr of Get_Call_Stack() // Skip frame of Get_Call_Stack(). if (!IsBadReadPtr(Ebp, sizeof(PSTACK))) Ebp = Ebp->Ebp; //caller ebp } // Break trace on wrong stack frame. for (; !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr)); Ebp = Ebp->Ebp) { // If module with Ebp->Ret_Addr found. memset(bufer,0, sizeof(0)); sprintf(bufer, "\n%08X ", (unsigned int)Ebp->Ret_Addr); sRet.append(bufer); QString moduleName = this->GetModuleByRetAddr(Ebp->Ret_Addr, Module_Addr_1) ; if (moduleName.length() > 0) { sRet.append(moduleName); } } return sRet; } //Get_Call_Stack
bool shouldUseStackWalker(PSTACK Ebp, int max_depth) { WCHAR Module_Name[MAX_PATH]; PBYTE Module_Addr = 0; int depth = 0; while (depth < max_depth) { if (IsBadReadPtr(Ebp, sizeof(PSTACK)) || IsBadReadPtr(Ebp->Ebp, sizeof(PSTACK)) || Ebp->Ebp < Ebp || Ebp->Ebp - Ebp > 0xFFFFFF || IsBadCodePtr(FARPROC(Ebp->Ebp->Ret_Addr)) || !Get_Module_By_Ret_Addr(Ebp->Ebp->Ret_Addr, Module_Name, Module_Addr)) { return true; } depth++; Ebp = Ebp->Ebp; } return false; }
BBOptConfig::BBOptConfig ( HINSTANCE inst, HWND parent ) { DLGPROC thunk = MakeProcInstance(FARPROC(BBOptConfigDlgProc),inst); int res = DialogBox(inst,BBOptConfigDlgName,parent,thunk); FreeProcInstance(thunk); if (res) Valid = true; else Valid = false; PopSize = DefPopSize; TestSize = DefTestSize; Crossover = DefCrossover; CrossProb = DefCrossProb; Mutate = DefMutate; MuteProb = DefMuteProb; Scaling = DefScaling; Elitist = DefElitist; }
//****************************************************************** void Get_Call_Stack(PEXCEPTION_POINTERS pException, FILE* fp) //****************************************************************** // Fill Str with call stack info. // pException can be either GetExceptionInformation() or NULL. // If pException = NULL - get current call stack. { TCHAR Module_Name[MAX_PATH]; PBYTE Module_Addr = 0; PBYTE Module_Addr_1; #pragma warning(disable: 4200) //nonstandard extension used : zero-sized array in struct/union typedef struct STACK { STACK * Ebp; PBYTE Ret_Addr; DWORD Param[0]; } STACK, * PSTACK; #pragma warning(default: 4200) STACK Stack = {0, 0}; PSTACK Ebp; if (pException) //fake frame for exception address { Stack.Ebp = (PSTACK)(DWORD_PTR)pException->ContextRecord->Ebp; Stack.Ret_Addr = (PBYTE)pException->ExceptionRecord->ExceptionAddress; Ebp = &Stack; } else { Ebp = (PSTACK)&pException - 1; //frame addr of Get_Call_Stack() // Skip frame of Get_Call_Stack(). if (!IsBadReadPtr(Ebp, sizeof(PSTACK))) Ebp = Ebp->Ebp; //caller ebp } // Trace CALL_TRACE_MAX calls maximum - not to exceed DUMP_SIZE_MAX. // Break trace on wrong stack frame. for (int Ret_Addr_I = 0; (Ret_Addr_I < CALL_TRACE_MAX) && !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr)); Ret_Addr_I++, Ebp = Ebp->Ebp) { // If module with Ebp->Ret_Addr found. if (Get_Module_By_Ret_Addr(Ebp->Ret_Addr, Module_Name, Module_Addr_1)) { if (Module_Addr_1 != Module_Addr) //new module { // Save module's address and full path. Module_Addr = Module_Addr_1; _ftprintf(fp, _T("%08X %s")NL, (LONG_PTR)Module_Addr, Module_Name); } // Save call offset. _ftprintf(fp, _T(" +%08X"), Ebp->Ret_Addr - Module_Addr); // Save 5 params of the call. We don't know the real number of params. if (pException && !Ret_Addr_I) //fake frame for exception address _ftprintf(fp, _T(" Exception Offset") NL); else if (!IsBadReadPtr(Ebp, sizeof(PSTACK) + 5 * sizeof(DWORD))) { _ftprintf(fp, _T(" (%X, %X, %X, %X, %X)") NL, Ebp->Param[0], Ebp->Param[1], Ebp->Param[2], Ebp->Param[3], Ebp->Param[4]); } } else _ftprintf(fp, _T("%08X")NL, (LONG_PTR)(Ebp->Ret_Addr)); } } //Get_Call_Stack
FARPROC WINAPI __delayLoadHelper2( PCImgDelayDescr pidd, FARPROC * ppfnIATEntry ) { // Set up some data we use for the hook procs but also useful for // our own use // InternalImgDelayDescr idd = { pidd->grAttrs, PFromRva<LPCSTR>(pidd->rvaDLLName), PFromRva<HMODULE*>(pidd->rvaHmod), PFromRva<PImgThunkData>(pidd->rvaIAT), PFromRva<PCImgThunkData>(pidd->rvaINT), PFromRva<PCImgThunkData>(pidd->rvaBoundIAT), PFromRva<PCImgThunkData>(pidd->rvaUnloadIAT), pidd->dwTimeStamp }; DelayLoadInfo dli = { sizeof DelayLoadInfo, pidd, ppfnIATEntry, idd.szName, { 0 }, 0, 0, 0 }; if (0 == (idd.grAttrs & dlattrRva)) { PDelayLoadInfo rgpdli[1] = { &dli }; RaiseException( VcppException(ERROR_SEVERITY_ERROR, ERROR_INVALID_PARAMETER), 0, 1, PULONG_PTR(rgpdli) ); return 0; } HMODULE hmod = *idd.phmod; // Calculate the index for the IAT entry in the import address table // N.B. The INT entries are ordered the same as the IAT entries so // the calculation can be done on the IAT side. // const unsigned iIAT = IndexFromPImgThunkData(PCImgThunkData(ppfnIATEntry), idd.pIAT); const unsigned iINT = iIAT; PCImgThunkData pitd = &(idd.pINT[iINT]); dli.dlp.fImportByName = !IMAGE_SNAP_BY_ORDINAL(pitd->u1.Ordinal); if (dli.dlp.fImportByName) { dli.dlp.szProcName = LPCSTR(PFromRva<PIMAGE_IMPORT_BY_NAME>(RVA(UINT_PTR(pitd->u1.AddressOfData)))->Name); } else { dli.dlp.dwOrdinal = DWORD(IMAGE_ORDINAL(pitd->u1.Ordinal)); } // Call the initial hook. If it exists and returns a function pointer, // abort the rest of the processing and just return it for the call. // FARPROC pfnRet = NULL; if (__pfnDliNotifyHook2) { pfnRet = ((*__pfnDliNotifyHook2)(dliStartProcessing, &dli)); if (pfnRet != NULL) { goto HookBypass; } } // Check to see if we need to try to load the library. // if (hmod == 0) { if (__pfnDliNotifyHook2) { hmod = HMODULE(((*__pfnDliNotifyHook2)(dliNotePreLoadLibrary, &dli))); } if (hmod == 0) { hmod = ::LoadLibraryEx(dli.szDll, NULL, 0); } if (hmod == 0) { dli.dwLastError = ::GetLastError(); if (__pfnDliFailureHook2) { // when the hook is called on LoadLibrary failure, it will // return 0 for failure and an hmod for the lib if it fixed // the problem. // hmod = HMODULE((*__pfnDliFailureHook2)(dliFailLoadLib, &dli)); } if (hmod == 0) { PDelayLoadInfo rgpdli[1] = { &dli }; RaiseException( VcppException(ERROR_SEVERITY_ERROR, ERROR_MOD_NOT_FOUND), 0, 1, PULONG_PTR(rgpdli) ); // If we get to here, we blindly assume that the handler of the exception // has magically fixed everything up and left the function pointer in // dli.pfnCur. // return dli.pfnCur; } } // Store the library handle. If it is already there, we infer // that another thread got there first, and we need to do a // FreeLibrary() to reduce the refcount // HMODULE hmodT = HMODULE(InterlockedExchangePointer((PVOID *) idd.phmod, PVOID(hmod))); if (hmodT == hmod) { ::FreeLibrary(hmod); } } // Go for the procedure now. // dli.hmodCur = hmod; if (__pfnDliNotifyHook2) { pfnRet = (*__pfnDliNotifyHook2)(dliNotePreGetProcAddress, &dli); } if (pfnRet == 0) { if (pidd->rvaBoundIAT && pidd->dwTimeStamp) { // bound imports exist...check the timestamp from the target image // PIMAGE_NT_HEADERS pinh(PinhFromImageBase(hmod)); if (pinh->Signature == IMAGE_NT_SIGNATURE && TimeStampOfImage(pinh) == idd.dwTimeStamp && FLoadedAtPreferredAddress(pinh, hmod)) { // Everything is good to go, if we have a decent address // in the bound IAT! // pfnRet = FARPROC(UINT_PTR(idd.pBoundIAT[iIAT].u1.Function)); if (pfnRet != 0) { goto SetEntryHookBypass; } } } pfnRet = ::GetProcAddress(hmod, dli.dlp.szProcName); } if (pfnRet == 0) { dli.dwLastError = ::GetLastError(); if (__pfnDliFailureHook2) { // when the hook is called on GetProcAddress failure, it will // return 0 on failure and a valid proc address on success // pfnRet = (*__pfnDliFailureHook2)(dliFailGetProc, &dli); } if (pfnRet == 0) { PDelayLoadInfo rgpdli[1] = { &dli }; RaiseException( VcppException(ERROR_SEVERITY_ERROR, ERROR_PROC_NOT_FOUND), 0, 1, PULONG_PTR(rgpdli) ); // If we get to here, we blindly assume that the handler of the exception // has magically fixed everything up and left the function pointer in // dli.pfnCur. // pfnRet = dli.pfnCur; } } SetEntryHookBypass: *ppfnIATEntry = pfnRet; HookBypass: if (__pfnDliNotifyHook2) { dli.dwLastError = 0; dli.hmodCur = hmod; dli.pfnCur = pfnRet; (*__pfnDliNotifyHook2)(dliNoteEndProcessing, &dli); } return pfnRet; }
//****************************************************************** void WINAPI Get_Call_Stack(const EXCEPTION_RECORD* exception_record, const CONTEXT* context_record, LLSD& info) //****************************************************************** // Fill Str with call stack info. // pException can be either GetExceptionInformation() or NULL. // If pException = NULL - get current call stack. { LPWSTR Module_Name = new WCHAR[MAX_PATH]; PBYTE Module_Addr = 0; LLSD params; PBYTE Esp = NULL; LLSD tmp_info; bool fake_frame = false; bool ebp_used = false; const int HEURISTIC_MAX_WALK = 20; int heuristic_walk_i = 0; int Ret_Addr_I = 0; WSTACK Stack = {0, 0}; PSTACK Ebp; if (exception_record && context_record) //fake frame for exception address { Stack.Ebp = (PSTACK)(context_record->Ebp); Stack.Ret_Addr = (PBYTE)exception_record->ExceptionAddress; Ebp = &Stack; Esp = (PBYTE) context_record->Esp; fake_frame = true; } else if(context_record) { Ebp = (PSTACK)(context_record->Ebp); Esp = (PBYTE)(context_record->Esp); } else { Ebp = (PSTACK)&exception_record - 1; //frame addr of Get_Call_Stack() Esp = (PBYTE)&exception_record; // Skip frame of Get_Call_Stack(). if (!IsBadReadPtr(Ebp, sizeof(PSTACK))) Ebp = Ebp->Ebp; //caller ebp } // Trace CALL_TRACE_MAX calls maximum - not to exceed DUMP_SIZE_MAX. // Break trace on wrong stack frame. for (Ret_Addr_I = 0; heuristic_walk_i < HEURISTIC_MAX_WALK && Ret_Addr_I < CALL_TRACE_MAX && !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr)); Ret_Addr_I++) { // If module with Ebp->Ret_Addr found. if (Get_Module_By_Ret_Addr(Ebp->Ret_Addr, Module_Name, Module_Addr)) { // Save module's address and full path. tmp_info["CallStack"][Ret_Addr_I]["ModuleName"] = ll_convert_wide_to_string(Module_Name); tmp_info["CallStack"][Ret_Addr_I]["ModuleAddress"] = (int)Module_Addr; tmp_info["CallStack"][Ret_Addr_I]["CallOffset"] = (int)(Ebp->Ret_Addr - Module_Addr); // Save 5 params of the call. We don't know the real number of params. if (fake_frame && !Ret_Addr_I) //fake frame for exception address params[0] = "Exception Offset"; else if (!IsBadReadPtr(Ebp, sizeof(PSTACK) + 5 * sizeof(DWORD))) { for(int j = 0; j < 5; ++j) { params[j] = (int)Ebp->Param[j]; } } tmp_info["CallStack"][Ret_Addr_I]["Parameters"] = params; } tmp_info["CallStack"][Ret_Addr_I]["ReturnAddress"] = (int)Ebp->Ret_Addr; // get ready for next frame // Set ESP to just after return address. Not the real esp, but just enough after the return address if(!fake_frame) { Esp = (PBYTE)Ebp + 8; } else { fake_frame = false; } // is next ebp valid? // only run if we've never found a good ebp // and make sure the one after is valid as well if( !ebp_used && shouldUseStackWalker(Ebp, 2)) { heuristic_walk_i++; PBYTE new_ebp = get_valid_frame(Esp); if (new_ebp != NULL) { Ebp = (PSTACK)new_ebp; } } else { ebp_used = true; Ebp = Ebp->Ebp; } } /* TODO remove or turn this code back on to edit the stack after i see a few raw ones. -Palmer // Now go back through and edit out heuristic stacks that could very well be bogus. // Leave the top and the last 3 stack chosen by the heuristic, however. if(heuristic_walk_i > 2) { info["CallStack"][0] = tmp_info["CallStack"][0]; std::string ttest = info["CallStack"][0]["ModuleName"]; for(int cur_frame = 1; (cur_frame + heuristic_walk_i - 2 < Ret_Addr_I); ++cur_frame) { // edit out the middle heuristic found frames info["CallStack"][cur_frame] = tmp_info["CallStack"][cur_frame + heuristic_walk_i - 2]; } } else { info = tmp_info; } */ info = tmp_info; info["HeuristicWalkI"] = heuristic_walk_i; info["EbpUsed"] = ebp_used; } //Get_Call_Stack
HRESULT ApiHijackImports( HMODULE hModule, //хэндл на эту программу (метод импорта), в ней замещающая процедура LPSTR szVictim, LPSTR szEntry, LPVOID pHijacker, //замещающая процедура LPVOID *ppOrig ) { FILE* pf = fopen("importlog.txt","a+"); // Check args if (::IsBadStringPtrA(szVictim, -1) || (!IS_INTRESOURCE(szEntry) && ::IsBadStringPtrA(szEntry, -1)) || ::IsBadCodePtr(FARPROC(pHijacker))) { fclose(pf); return E_INVALIDARG; } PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER(hModule); //DOS заголовок PE файла (этой программы) if (::IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)) || IMAGE_DOS_SIGNATURE != pDosHeader->e_magic) { fclose(pf); return E_INVALIDARG; } PIMAGE_NT_HEADERS pNTHeaders = MakePtr(PIMAGE_NT_HEADERS, hModule, pDosHeader->e_lfanew); //PE заголовок (этой программы) if (::IsBadReadPtr(pNTHeaders, sizeof(IMAGE_NT_HEADERS)) || IMAGE_NT_SIGNATURE != pNTHeaders->Signature) { fclose(pf); return E_INVALIDARG; } HRESULT hr = E_UNEXPECTED; // Locate the victim IMAGE_DATA_DIRECTORY& impDir = pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; //элемент директории данных опционального заголовка (структура): символы импорта PIMAGE_IMPORT_DESCRIPTOR pImpDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, hModule, impDir.VirtualAddress), //адрес начала таблицы импорта (массив структур IMAGE_IMPORT_DESCRIPTOR) pEnd = pImpDesc + impDir.Size / sizeof(IMAGE_IMPORT_DESCRIPTOR) - 1; //адрес конца таблицы while(pImpDesc < pEnd) { char *p; //debug p=MakePtr(char*,hModule,pImpDesc->Name); if (0 == ::lstrcmpiA(MakePtr(LPSTR, hModule, pImpDesc->Name), szVictim)) //в таблице импорта szVictim { if (0 == pImpDesc->OriginalFirstThunk) { // no import names table fclose(pf); return E_UNEXPECTED; } // Locate the entry PIMAGE_THUNK_DATA pNamesTable = MakePtr(PIMAGE_THUNK_DATA, hModule, pImpDesc->OriginalFirstThunk); if (IS_INTRESOURCE(szEntry)) { // By ordinal while(pNamesTable->u1.AddressOfData) { if (IMAGE_SNAP_BY_ORDINAL(pNamesTable->u1.Ordinal) && WORD(szEntry) == IMAGE_ORDINAL(pNamesTable->u1.Ordinal)) { hr = S_OK; break; } pNamesTable++; } } else { // By name while(pNamesTable->u1.AddressOfData) { if (!IMAGE_SNAP_BY_ORDINAL(pNamesTable->u1.Ordinal)) { PIMAGE_IMPORT_BY_NAME pName = MakePtr(PIMAGE_IMPORT_BY_NAME, hModule, pNamesTable->u1.AddressOfData); if (0 == ::lstrcmpiA(LPSTR(pName->Name), szEntry)) { hr = S_OK; break; } } pNamesTable++; } } if (SUCCEEDED(hr)) { // Get address LPVOID *pProc = MakePtr(LPVOID *, pNamesTable, pImpDesc->FirstThunk - pImpDesc->OriginalFirstThunk); //pImpDesc->FirstThunk - выводится как Address в проге pe_class - import_descriptor_array->FirstThunk // Save original handler if (ppOrig) *ppOrig = *pProc; // write to write-protected memory fprintf(pf, "0x%X 0x%X 0x%X 0x%X\n", pProc, pNamesTable, pImpDesc->FirstThunk, pImpDesc->OriginalFirstThunk); fclose(pf); return WriteProtectedMemory(pProc, &pHijacker, sizeof(LPVOID)); } break; } pImpDesc++; } fclose(pf); return hr; }
void GetCallStack(_EXCEPTION_POINTERS* pException, List<LoadedModule*>* modules, StringList& headers){ typedef struct STACK { STACK* Ebp; PBYTE Ret_Addr; DWORD Param[0]; } STACK, *PSTACK; STACK Stack = {0, 0}; PSTACK Ebp; Stack.Ebp = (PSTACK)pException->ContextRecord->Ebp; Stack.Ret_Addr = (PBYTE)pException->ExceptionRecord->ExceptionAddress; Ebp = &Stack; for(unsigned int i = 0; (i < MAX_CALL_STACK && !IsBadReadPtr(Ebp, sizeof(PSTACK)) && !IsBadCodePtr(FARPROC(Ebp->Ret_Addr))); ++i, Ebp = Ebp->Ebp){ unsigned int addr = (unsigned int)Ebp->Ret_Addr; headers.push_back(String("Call-Stack-%1: %2 %3").arg(i).arg(GetModuleName(addr, modules)).arg(addr, 16, true, 8)); } }
void dumpBackTrace(void* processId) { if (!processId) processId = GetCurrentProcess(); const int maxAddrCount = 32; printf("\n*********** BACKTRACE **************\n"); // Get frame address using builtin GCC function. STACK_FRAME* stackFrame = (STACK_FRAME*)__builtin_frame_address(0); for (int retAddrCount = 0; (retAddrCount < maxAddrCount) && !IsBadReadPtr(stackFrame, sizeof(STACK_FRAME)) && !IsBadCodePtr(FARPROC(stackFrame->retAddr)); retAddrCount++, stackFrame = stackFrame->ebp) { printf("Frame %2d: ", retAddrCount); dumpFrame(processId, stackFrame->retAddr); fflush(stdout); } printf("*********** BACKTRACE **************\n\n"); }