Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- There's some Chinese characters in "Architecture:" output and a whole lot in "Exported Functions:" output especially for 64bit files, and also the "Imported Functions:" and Exports and "Resource Directory:" output doesn't display for 64bit files. Also when opening 32bit files the Progress Bar gets stuck at "Analyzing 90%". Can you fix these issues please?
- */
- /*
- Wait for me to say "O.K. I finished" while I post my source code in multi-parts, then read my prompt with reference to the code O.K. ? I have a cpp file (Win32 GUI-based) for Parsing a PE Header, I will explain what I need help with after the full code is posted, please hold on till then.
- */
- #define STRICT
- #define WIN32_LEAN_AND_MEAN
- #include <Windows.h>
- #include <winternl.h>
- #include <CommCtrl.h>
- #include <commdlg.h>
- #include <string>
- #include <strsafe.h>
- #include <sstream>
- #include <iomanip>
- #include <stdio.h>
- #include <vector>
- #include <shellapi.h>
- //#include "helpers.h"
- #include "resource.h"
- #pragma comment(lib, "comctl32.lib")
- //bool Is64BitPE(PIMAGE_NT_HEADERS pNtHeaders);
- namespace PEHelpers {
- // Add these new helper functions
- bool Is64BitPE(PIMAGE_NT_HEADERS pNtHeaders) {
- return pNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;
- }
- DWORD_PTR GetImageBase(PIMAGE_NT_HEADERS pNtHeaders) {
- if (PEHelpers::Is64BitPE(pNtHeaders)) {
- auto pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
- return static_cast<DWORD_PTR>(pNtHeaders64->OptionalHeader.ImageBase);
- }
- else {
- auto pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
- return static_cast<DWORD_PTR>(pNtHeaders32->OptionalHeader.ImageBase);
- }
- }
- DWORD GetSizeOfImage(PIMAGE_NT_HEADERS pNtHeaders) {
- if (PEHelpers::Is64BitPE(pNtHeaders)) {
- auto pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
- return pNtHeaders64->OptionalHeader.SizeOfImage;
- }
- else {
- auto pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
- return pNtHeaders32->OptionalHeader.SizeOfImage;
- }
- }
- bool ValidateFileSize(DWORD expectedSize, DWORD fileSize) {
- // Validate against SizeOfHeaders instead of SizeOfImage
- return expectedSize > 0 && expectedSize <= fileSize;
- }
- //}
- // Replace the existing GetRvaPtr function in PEHelpers namespace with this:
- DWORD_PTR GetRvaPtr(DWORD rva, PIMAGE_SECTION_HEADER pSectionHeader, WORD numberOfSections, LPVOID baseAddress) {
- for (WORD i = 0; i < numberOfSections; i++) {
- if (rva >= pSectionHeader[i].VirtualAddress &&
- rva < (pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData)) {
- DWORD_PTR delta = (DWORD_PTR)baseAddress + pSectionHeader[i].PointerToRawData;
- return delta + (rva - pSectionHeader[i].VirtualAddress);
- }
- }
- return 0;
- }
- // Add to PEHelpers namespace:
- bool IsRvaValid(DWORD rva, DWORD fileSize, PIMAGE_NT_HEADERS pNtHeaders) {
- return rva < pNtHeaders->OptionalHeader.SizeOfImage&& rva < fileSize;
- }
- // Add this new helper function in PEHelpers namespace:
- PIMAGE_SECTION_HEADER GetEnclosingSectionHeader(DWORD rva, PIMAGE_SECTION_HEADER pSectionHeader, WORD numberOfSections) {
- for (WORD i = 0; i < numberOfSections; i++) {
- if ((rva >= pSectionHeader[i].VirtualAddress) &&
- (rva < (pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData))) {
- return &pSectionHeader[i];
- }
- }
- return nullptr;
- }
- std::wstring GetImageCharacteristics(DWORD characteristics) {
- if (characteristics & IMAGE_FILE_DLL) return L"(DLL)";
- if (characteristics & IMAGE_FILE_SYSTEM) return L"(DRIVER)";
- if (characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) return L"(EXE)";
- return L"(UNKNOWN)";
- }
- std::wstring GetSubsystem(WORD subsystem) {
- switch (subsystem) {
- case IMAGE_SUBSYSTEM_NATIVE: return L"(NATIVE/DRIVER)";
- case IMAGE_SUBSYSTEM_WINDOWS_GUI: return L"(GUI)";
- case IMAGE_SUBSYSTEM_WINDOWS_CUI: return L"(CONSOLE)";
- default: return L"(UNKNOWN)";
- }
- }
- std::wstring GetDataDirectoryName(int DirectoryNumber) {
- switch (DirectoryNumber) {
- case 0: return L"Export Table";
- case 1: return L"Import Table";
- case 2: return L"Resource Table";
- case 3: return L"Exception Entry";
- case 4: return L"Security Entry";
- case 5: return L"Relocation Table";
- case 6: return L"Debug Entry";
- case 7: return L"Copyright Entry";
- case 8: return L"Global PTR Entry";
- case 9: return L"TLS Entry";
- case 10: return L"Configuration Entry";
- case 11: return L"Bound Import Entry";
- case 12: return L"IAT";
- case 13: return L"Delay Import Descriptor";
- case 14: return L"COM Descriptor";
- default: return L"Unknown";
- }
- }
- std::wstring GetSectionProtection(DWORD characteristics) {
- std::wstring protection = L"(";
- bool needsSeparator = false;
- if (characteristics & IMAGE_SCN_MEM_EXECUTE) {
- protection += L"EXECUTE";
- needsSeparator = true;
- }
- if (characteristics & IMAGE_SCN_MEM_READ) {
- if (needsSeparator) protection += L" | ";
- protection += L"READ";
- needsSeparator = true;
- }
- if (characteristics & IMAGE_SCN_MEM_WRITE) {
- if (needsSeparator) protection += L" | ";
- protection += L"WRITE";
- }
- protection += L")";
- return protection;
- }
- PIMAGE_SECTION_HEADER GetExportSection(const PIMAGE_SECTION_HEADER pImageSectionHeader,
- const int NumberOfSections,
- const DWORD_PTR dExportAddress) {
- for (int i = 0; i < NumberOfSections; ++i) {
- const auto pCurrentSectionHeader =
- (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageSectionHeader + i * sizeof(IMAGE_SECTION_HEADER));
- if (dExportAddress >= pCurrentSectionHeader->VirtualAddress &&
- dExportAddress < pCurrentSectionHeader->VirtualAddress + pCurrentSectionHeader->Misc.VirtualSize)
- return pCurrentSectionHeader;
- }
- return nullptr;
- }
- DWORD RvaToOffset(DWORD rva, PIMAGE_SECTION_HEADER pSectionHeader, WORD numberOfSections) {
- for (WORD i = 0; i < numberOfSections; i++) {
- if (rva >= pSectionHeader[i].VirtualAddress &&
- rva < (pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData)) {
- return (rva - pSectionHeader[i].VirtualAddress) + pSectionHeader[i].PointerToRawData;
- }
- }
- return 0;
- }
- }
- using namespace std;
- // At the top of your file, change the window class name to wide string
- #define WINDOW_CLASS_NAME L"PEAnalyzerWindow"
- //const wchar_t* const WINDOW_CLASS_NAME = L"PEAnalyzerWindow";
- // Use ANSI versions explicitly
- //#undef CreateWindow
- //#undef CreateWindowEx
- //#define CreateWindow CreateWindowW
- //#define CreateWindowEx CreateWindowExW
- // Helper function to replace printf with GUI output
- #define OUTPUT(format, ...) AppendToOutput(L##format, ##__VA_ARGS__)
- //#define OUTPUT(format, ...) AppendToOutput(format, ##__VA_ARGS__)
- //#define printf(format, ...) AppendToOutput(format, ##__VA_ARGS__)
- // Window dimensions
- #define WINDOW_WIDTH 1024
- #define WINDOW_HEIGHT 768
- #define EDIT_MARGIN 10
- // Global variables
- HWND g_hMainWindow = NULL;
- HWND g_hEditControl = NULL;
- HFONT g_hFont = NULL;
- std::wstringstream g_OutputText;
- WCHAR filePathW[MAX_PATH];
- std::vector<wchar_t> g_OutputBuffer;
- std::wstring tempBuffer; // Declare tempBuffer globally
- HWND g_hStatusBar = NULL;
- HWND g_hProgressBar = NULL; // Add this with your other global variables
- //int virtualHeight = 100; // Initialize with an appropriate value
- // Function declarations
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
- LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
- void CreateMainWindow(HINSTANCE hInstance);
- void InitializeControls(HWND hwnd);
- void AddMenus(HWND hwnd);
- void OpenFileDialog(HWND hwnd);
- //void AnalyzePEFile(const WCHAR* filePathW);
- void AnalyzePEFile(const wchar_t* filePathW);
- HANDLE GetFileContent(const wchar_t* lpFilePath);
- /*void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory);
- PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader,
- int NumberOfSections, DWORD dImportAddress);
- void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
- DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection);
- void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
- DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection);*/
- void AppendToOutput(const wchar_t* format, ...);
- void UpdateEditControl();
- // Main window class name
- //const char* const WINDOW_CLASS_NAME = "PEAnalyzerWindow";
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
- INITCOMMONCONTROLSEX icc = { sizeof(INITCOMMONCONTROLSEX), ICC_WIN95_CLASSES };
- InitCommonControlsEx(&icc);
- // Get command line parameters in Unicode
- int argc;
- LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
- CreateMainWindow(hInstance);
- if (!g_hMainWindow) {
- LocalFree(argv);
- return -1;
- }
- ShowWindow(g_hMainWindow, nCmdShow);
- UpdateWindow(g_hMainWindow);
- // If there's a command line parameter, process it
- if (argc > 1) {
- // Process the first parameter as file path
- SetWindowTextW(g_hEditControl, L"");
- g_OutputText.str(L"");
- g_OutputText.clear();
- AnalyzePEFile(argv[1]);
- UpdateEditControl();
- }
- LocalFree(argv);
- MSG msg = {};
- while (GetMessage(&msg, NULL, 0, 0)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- if (g_hFont) DeleteObject(g_hFont);
- return (int)msg.wParam;
- }
- void CreateMainWindow(HINSTANCE hInstance) {
- WNDCLASSEXW wc = { sizeof(WNDCLASSEXW), 0, WindowProc, 0, 0, hInstance,
- LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)),
- LoadCursor(NULL, IDC_ARROW),
- (HBRUSH)(COLOR_WINDOW + 1),
- NULL, WINDOW_CLASS_NAME,
- LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)) };
- RegisterClassExW(&wc);
- // Get screen dimensions
- int screenWidth = GetSystemMetrics(SM_CXSCREEN);
- int screenHeight = GetSystemMetrics(SM_CYSCREEN);
- // Calculate center position
- int windowX = (screenWidth - WINDOW_WIDTH) / 2;
- int windowY = (screenHeight - WINDOW_HEIGHT) / 2;
- // Remove WS_MAXIMIZEBOX and WS_THICKFRAME from the window style
- DWORD style = (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX) & ~WS_THICKFRAME;
- //WS_OVERLAPPEDWINDOW ~~> style
- g_hMainWindow = CreateWindowExW(0, WINDOW_CLASS_NAME, L"PE File Analyzer",
- style, windowX, windowY, WINDOW_WIDTH, WINDOW_HEIGHT,
- nullptr, nullptr, hInstance, nullptr);
- }
- void InitializeControls(HWND hwnd) {
- // Create status bar
- g_hStatusBar = CreateWindowEx(0, STATUSCLASSNAME, NULL,
- WS_CHILD | WS_VISIBLE,
- 0, 0, 0, 0, hwnd, NULL,
- (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
- // Set up status bar parts
- RECT rcClient;
- GetClientRect(hwnd, &rcClient);
- int statusParts[2] = { 150, rcClient.right };
- SendMessage(g_hStatusBar, SB_SETPARTS, 2, (LPARAM)statusParts);
- // Create progress bar in the second part of status bar
- RECT rcPart;
- SendMessage(g_hStatusBar, SB_GETRECT, 1, (LPARAM)&rcPart);
- g_hProgressBar = CreateWindowEx(0, PROGRESS_CLASS, NULL,
- WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
- rcPart.left + 5, rcPart.top + 2,
- rcPart.right - rcPart.left - 10, rcPart.bottom - rcPart.top - 4,
- g_hStatusBar, NULL,
- (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
- // Set blue color and range
- SendMessage(g_hProgressBar, PBM_SETBARCOLOR, 0, (LPARAM)RGB(0, 120, 215)); // Windows 10 blue
- SendMessage(g_hProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
- SendMessage(g_hProgressBar, PBM_SETSTEP, 1, 0);
- // Get status bar height for edit control positioning
- RECT rcStatus;
- GetWindowRect(g_hStatusBar, &rcStatus);
- int statusHeight = rcStatus.bottom - rcStatus.top;
- // Create edit control
- g_hEditControl = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"",
- WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL |
- ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
- EDIT_MARGIN, EDIT_MARGIN,
- rcClient.right - (2 * EDIT_MARGIN),
- rcClient.bottom - statusHeight - (2 * EDIT_MARGIN),
- hwnd, nullptr,
- (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), nullptr);
- // Create and set font
- g_hFont = CreateFont(-14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
- ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
- DEFAULT_QUALITY, DEFAULT_PITCH | FF_MODERN, L"Consolas");
- if (g_hFont)
- SendMessage(g_hEditControl, WM_SETFONT, (WPARAM)g_hFont, TRUE);
- SetWindowSubclass(g_hEditControl, EditSubclassProc, 0, 0);
- }
- void AddMenus(HWND hwnd) {
- HMENU hMenuBar = CreateMenu();
- HMENU hFileMenu = CreateMenu();
- AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hFileMenu, L"&File");
- AppendMenu(hFileMenu, MF_STRING, 1, L"&Open\tCtrl+O"); // Updated to show shortcut
- AppendMenu(hFileMenu, MF_STRING, 2, L"E&xit");
- SetMenu(hwnd, hMenuBar);
- }
- /*LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
- if (uMsg == WM_KEYDOWN) {
- // Check for Ctrl+O
- if ((GetKeyState(VK_CONTROL) & 0x8000) && wParam == 'O') {
- SendMessage(GetParent(hwnd), WM_COMMAND, 1, 0); // Send the Open command
- return 0;
- }
- // Existing cases
- switch (wParam) {
- case VK_F1:
- SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_F1, 0);
- return 0;
- case VK_ESCAPE:
- SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_ESCAPE, 0);
- return 0;
- case VK_PRIOR: // Page Up
- SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_PRIOR, 0);
- return 0;
- case VK_NEXT: // Page Down
- SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_NEXT, 0);
- return 0;
- }
- }
- else if (uMsg == WM_MOUSEWHEEL) {
- int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
- if (zDelta > 0) {
- SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_PRIOR, 0); // Mouse Wheel Up
- }
- else if (zDelta < 0) {
- SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_NEXT, 0); // Mouse Wheel Down
- }
- return 0;
- }
- return DefSubclassProc(hwnd, uMsg, wParam, lParam);
- }*/
- // First, add this helper function to determine if the PE file is 64-bit
- bool Is64BitPE(PIMAGE_NT_HEADERS pNtHeaders) {
- return pNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;
- }
- LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
- if (uMsg == WM_KEYDOWN) {
- if ((GetKeyState(VK_CONTROL) & 0x8000) && wParam == 'O') {
- SendMessage(GetParent(hwnd), WM_COMMAND, 1, 0);
- return 0;
- }
- switch (wParam) {
- case VK_F1:
- SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_F1, 0);
- return 0;
- case VK_ESCAPE:
- SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_ESCAPE, 0);
- return 0;
- case VK_PRIOR:
- // Scroll up
- SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
- return 0;
- case VK_NEXT:
- // Scroll down
- SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
- return 0;
- case VK_UP:
- // Scroll one line up
- SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0);
- return 0;
- case VK_DOWN:
- // Scroll one line down
- SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0);
- return 0;
- }
- }
- if (uMsg == WM_MOUSEWHEEL) {
- int delta = GET_WHEEL_DELTA_WPARAM(wParam);
- if (delta > 0) {
- // Scroll up
- SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
- }
- else {
- // Scroll down
- SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
- }
- return 0;
- }
- return DefSubclassProc(hwnd, uMsg, wParam, lParam);
- }
- LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- switch (uMsg) {
- case WM_CREATE: InitializeControls(hwnd); AddMenus(hwnd); return 0;
- case WM_SIZE:
- {
- RECT rcClient;
- GetClientRect(hwnd, &rcClient);
- // Resize status bar
- SendMessage(g_hStatusBar, WM_SIZE, 0, 0);
- // Recalculate status bar parts
- int statusParts[2] = { 150, rcClient.right };
- SendMessage(g_hStatusBar, SB_SETPARTS, 2, (LPARAM)statusParts);
- // Reposition progress bar
- RECT rcPart;
- SendMessage(g_hStatusBar, SB_GETRECT, 1, (LPARAM)&rcPart);
- SetWindowPos(g_hProgressBar, NULL,
- rcPart.left + 5, rcPart.top + 2,
- rcPart.right - rcPart.left - 10, rcPart.bottom - rcPart.top - 4,
- SWP_NOZORDER);
- // Get status bar height
- RECT rcStatus;
- GetWindowRect(g_hStatusBar, &rcStatus);
- int statusHeight = rcStatus.bottom - rcStatus.top;
- // Resize edit control
- SetWindowPos(g_hEditControl, NULL,
- EDIT_MARGIN,
- EDIT_MARGIN,
- rcClient.right - (2 * EDIT_MARGIN),
- rcClient.bottom - statusHeight - (2 * EDIT_MARGIN),
- SWP_NOZORDER);
- return 0;
- }
- /*case WM_KEYDOWN:
- {
- // Check if Ctrl is pressed
- if (GetKeyState(VK_CONTROL) & 0x8000) {
- switch (wParam) {
- case 'O': // Ctrl+O
- OpenFileDialog(hwnd);
- return 0;
- }
- }
- // Handle Page Up/Page Down
- switch (wParam) {
- case VK_PRIOR: // Page Up
- ScrollWindow(hwnd, 0, -virtualHeight, NULL, NULL);
- UpdateWindow(hwnd);
- return 0;
- case VK_NEXT: // Page Down
- ScrollWindow(hwnd, 0, virtualHeight, NULL, NULL);
- UpdateWindow(hwnd);
- return 0;
- case VK_F1:
- MessageBoxW(hwnd,
- L"PE Header Parser 2.9 GUI-based Programmed in C++ Win32 API (1369 lines of code) by Entisoft Software(c) Evans Thorpemorton",
- L"About",
- MB_OK | MB_ICONINFORMATION);
- return 0;
- case VK_ESCAPE:
- PostQuitMessage(0);
- return 0;
- }
- }
- break;
- case WM_MOUSEWHEEL:
- {
- int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
- if (zDelta > 0) {
- ScrollWindow(hwnd, 0, -virtualHeight, NULL, NULL); // Mouse Wheel Up
- }
- else if (zDelta < 0) {
- ScrollWindow(hwnd, 0, virtualHeight, NULL, NULL); // Mouse Wheel Down
- }
- UpdateWindow(hwnd);
- return 0;
- }*/
- case WM_KEYDOWN:
- {
- if (GetKeyState(VK_CONTROL) & 0x8000) {
- switch (wParam) {
- case 'O':
- OpenFileDialog(hwnd);
- return 0;
- }
- }
- switch (wParam) {
- case VK_F1:
- MessageBoxW(hwnd,
- L"PE Header Parser 4.3 GUI-based Programmed in C++ Win32 API (1546 lines of code) by Entisoft Software(c) Evans Thorpemorton",
- L"About",
- MB_OK | MB_ICONINFORMATION);
- return 0;
- case VK_ESCAPE:
- PostQuitMessage(0);
- return 0;
- case VK_PRIOR:
- // Scroll up
- SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
- return 0;
- case VK_NEXT:
- // Scroll down
- SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
- return 0;
- case VK_UP:
- // Scroll one line up
- SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0);
- return 0;
- case VK_DOWN:
- // Scroll one line down
- SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0);
- return 0;
- }
- break;
- }
- case WM_MOUSEWHEEL:
- {
- int delta = GET_WHEEL_DELTA_WPARAM(wParam);
- if (delta > 0) {
- // Scroll up
- SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
- }
- else {
- // Scroll down
- SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
- }
- return 0;
- }
- case WM_COMMAND: if (LOWORD(wParam) == 1) OpenFileDialog(hwnd); if (LOWORD(wParam) == 2) PostQuitMessage(0); return 0;
- case WM_DESTROY:
- if (g_hStatusBar) DestroyWindow(g_hStatusBar);
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
- }
- void SetStatusText(const wchar_t* text) {
- SendMessage(g_hStatusBar, SB_SETTEXT, 0, (LPARAM)text);
- }
- void ShowProgress(int percentage) {
- // Update progress bar
- SendMessage(g_hProgressBar, PBM_SETPOS, (WPARAM)percentage, 0);
- // Update status text in first part
- wchar_t status[256];
- swprintf_s(status, L"Analyzing... %d%%", percentage);
- //swprintf_s(status, L"Analyzing...");
- SetStatusText(status); //commented-out
- SendMessage(g_hStatusBar, SB_SETTEXT, 0, (LPARAM)status);
- }
- void OpenFileDialog(HWND hwnd) {
- WCHAR fileName[MAX_PATH] = L"";
- OPENFILENAMEW ofn = { sizeof(OPENFILENAMEW), hwnd, NULL, L"Executable Files (*.exe;*.dll)\0*.exe;*.dll\0All Files (*.*)\0*.*\0", NULL, 0, 1, fileName, MAX_PATH, NULL, 0, NULL, NULL, OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, 0, 0, L"exe", NULL, NULL, NULL };
- if (GetOpenFileNameW(&ofn)) {
- SetWindowTextW(g_hEditControl, L"");
- g_OutputText.str(L"");
- g_OutputText.clear();
- AnalyzePEFile(ofn.lpstrFile);
- UpdateEditControl();
- }
- }
- class FileMapper {
- private:
- HANDLE hFile = INVALID_HANDLE_VALUE;
- HANDLE hMapping = nullptr;
- LPVOID lpView = nullptr;
- public:
- ~FileMapper() {
- if (lpView) UnmapViewOfFile(lpView);
- if (hMapping) CloseHandle(hMapping);
- if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
- }
- bool Initialize(const wchar_t* path) {
- hFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, nullptr,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (hFile == INVALID_HANDLE_VALUE) return false;
- hMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr);
- if (!hMapping) return false;
- lpView = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
- return lpView != nullptr;
- }
- LPVOID GetView() const { return lpView; }
- };
- // Modified AppendToOutput to handle newlines properly:
- void AppendToOutput(const wchar_t* format, ...) {
- std::vector<wchar_t> buffer(1024);
- va_list args;
- va_start(args, format);
- while (true) {
- int result = _vsnwprintf(buffer.data(), buffer.size(), format, args);
- if (result >= 0) break;
- buffer.resize(buffer.size() * 2);
- }
- va_end(args);
- // Convert \n to \r\n
- std::wstring output = buffer.data();
- size_t pos = 0;
- while ((pos = output.find(L'\n', pos)) != std::wstring::npos) {
- if (pos == 0 || output[pos - 1] != L'\r') {
- output.insert(pos, L"\r");
- pos += 2;
- }
- else {
- pos++;
- }
- }
- g_OutputText << output;
- UpdateEditControl();
- }
- /*
- void AppendToOutput(const wchar_t* format, ...) {
- wchar_t buffer[16384]; // Ensure sufficient buffer size
- va_list args;
- va_start(args, format);
- StringCchVPrintfW(buffer, ARRAYSIZE(buffer), format, args);
- va_end(args);
- tempBuffer += buffer;
- // Update Edit Control periodically to improve performance
- if (tempBuffer.size() > 8000) {
- g_OutputText << tempBuffer;
- tempBuffer.clear();
- SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
- SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
- SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
- }
- }
- // Final update to flush any remaining content
- void FlushOutput() {
- if (!tempBuffer.empty()) {
- g_OutputText << tempBuffer;
- tempBuffer.clear();
- SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
- SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
- SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
- }
- }
- */
- /*
- //use below ^^ ALWAYS
- void AppendToOutput(const wchar_t* format, ...) {
- va_list args;
- va_start(args, format);
- // Use a vector as a dynamically resizable buffer
- std::vector<wchar_t> buffer(16384); // Start with an initial size
- int result = -1;
- while (true) {
- // Attempt to format the string
- result = _vsnwprintf(buffer.data(), buffer.size(), format, args);
- if (result >= 0 && static_cast<size_t>(result) < buffer.size()) {
- // Successfully formatted within the current buffer size
- break;
- }
- // Resize the buffer and try again
- buffer.resize(buffer.size() * 2);
- }
- va_end(args);
- // Convert `\n` to `\r\n` for proper display in the EditBox
- std::wstring formattedOutput(buffer.data());
- size_t pos = 0;
- while ((pos = formattedOutput.find(L'\n', pos)) != std::wstring::npos) {
- formattedOutput.replace(pos, 1, L"\r\n");
- pos += 2; // Move past the replacement
- }
- // Append to the global output buffer
- g_OutputText << formattedOutput;
- // Update the EditBox periodically to prevent overloading
- if (g_OutputText.str().size() > 8000) {
- SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
- SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
- SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
- }
- }
- //use above ^^ ALWAYS
- */
- //currentlatest
- /*void AppendToOutput(const wchar_t* format, ...) {
- wchar_t buffer[4096];
- va_list args;
- va_start(args, format);
- StringCchVPrintfW(buffer, ARRAYSIZE(buffer), format, args);
- va_end(args);
- g_OutputText << buffer;
- SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
- SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
- SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
- }
- */
- //use-below-basic-failsafe-working vv
- //basic test function
- /*void AnalyzePEFile(const wchar_t* filePathW) {
- OUTPUT("[+] Analyzing file: %s\n", filePathW);
- LPVOID lpFileContent = GetFileContent(filePathW);
- if (!lpFileContent) { OUTPUT("[-] Could not read file.\n"); return; }
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileContent;
- if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) { OUTPUT("[-] Invalid DOS signature.\n"); HeapFree(GetProcessHeap(), 0, lpFileContent); return; }
- PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)lpFileContent + dosHeader->e_lfanew);
- if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) { OUTPUT("[-] Invalid NT signature.\n"); HeapFree(GetProcessHeap(), 0, lpFileContent); return; }
- OUTPUT("[+] PE file analyzed successfully.\n");
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- UpdateEditControl();
- }*/
- //use-above-basic-failsafe-working vv
- //use vectors for unlimited size growth of buffer, use an alternative to editbox, check for fast loops overloading, in its primitive form it works properly! try w/o getimports3264 datadirectories getsections
- void ProcessResourceDirectory(
- PIMAGE_RESOURCE_DIRECTORY resDir,
- int level,
- const wchar_t* type,
- PIMAGE_RESOURCE_DIRECTORY pResourceDir,
- const wchar_t* resourceTypes[],
- PIMAGE_NT_HEADERS pNtHeaders,
- LPVOID lpFileContent)
- {
- if (IsBadReadPtr(resDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
- return;
- }
- auto entry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resDir + 1);
- WORD totalEntries = resDir->NumberOfNamedEntries + resDir->NumberOfIdEntries;
- for (WORD i = 0; i < totalEntries; i++) {
- if (IsBadReadPtr(entry + i, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))) {
- break;
- }
- for (int indent = 0; indent < level; indent++) {
- OUTPUT("\t");
- }
- if (entry[i].NameIsString) {
- auto nameEntry = (PIMAGE_RESOURCE_DIR_STRING_U)((BYTE*)pResourceDir + entry[i].NameOffset);
- if (!IsBadReadPtr(nameEntry, sizeof(IMAGE_RESOURCE_DIR_STRING_U))) {
- std::vector<wchar_t> resourceName(nameEntry->Length + 1);
- wcsncpy_s(resourceName.data(), nameEntry->Length + 1,
- nameEntry->NameString, nameEntry->Length);
- resourceName[nameEntry->Length] = L'\0';
- if (level == 0) {
- OUTPUT("Resource Type: Custom (%s)\n", resourceName.data());
- }
- else {
- OUTPUT("Name: %s\n", resourceName.data());
- }
- }
- }
- else {
- if (level == 0) {
- DWORD resourceType = entry[i].Id;
- if (resourceType < 16) {
- OUTPUT("Resource Type: %s (ID: %d)\n", resourceTypes[resourceType], resourceType);
- }
- else {
- OUTPUT("Resource Type: Custom (ID: %d)\n", resourceType);
- }
- }
- else {
- OUTPUT("ID: %d\n", entry[i].Id);
- }
- }
- if (entry[i].DataIsDirectory) {
- auto nextDir = (PIMAGE_RESOURCE_DIRECTORY)((BYTE*)pResourceDir + entry[i].OffsetToDirectory);
- if (!IsBadReadPtr(nextDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
- ProcessResourceDirectory(nextDir, level + 1,
- level == 0 ? resourceTypes[min(entry[i].Id, 15)] : type,
- pResourceDir, resourceTypes, pNtHeaders, lpFileContent);
- }
- }
- else {
- auto dataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((BYTE*)pResourceDir + entry[i].OffsetToData);
- if (!IsBadReadPtr(dataEntry, sizeof(IMAGE_RESOURCE_DATA_ENTRY))) {
- for (int indent = 0; indent < level + 1; indent++) {
- OUTPUT("\t");
- }
- OUTPUT("Size: %d bytes, RVA: 0x%X\n",
- dataEntry->Size, dataEntry->OffsetToData);
- if (type && wcscmp(type, L"Version") == 0) {
- auto versionData = (BYTE*)PEHelpers::GetRvaPtr(
- dataEntry->OffsetToData,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (versionData && !IsBadReadPtr(versionData, sizeof(VS_FIXEDFILEINFO))) {
- auto versionInfo = (VS_FIXEDFILEINFO*)(versionData + 40);
- if (versionInfo->dwSignature == 0xFEEF04BD) {
- for (int indent = 0; indent < level + 2; indent++) {
- OUTPUT("\t");
- }
- OUTPUT("File Version: %d.%d.%d.%d\n",
- HIWORD(versionInfo->dwFileVersionMS),
- LOWORD(versionInfo->dwFileVersionMS),
- HIWORD(versionInfo->dwFileVersionLS),
- LOWORD(versionInfo->dwFileVersionLS));
- }
- }
- }
- }
- }
- }
- }
- void AnalyzePEFile(const wchar_t* filePathW) {
- OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
- // Initialize all variables at the start
- HANDLE hFile = INVALID_HANDLE_VALUE;
- HANDLE hFileMapping = nullptr;
- LPVOID lpFileContent = nullptr;
- FileMapper mapper;
- if (!mapper.Initialize(filePathW)) {
- SetStatusText(L"Failed to open file!");
- OUTPUT("[-] Failed to open file! Error: %d\r\n", GetLastError());
- return;
- }
- ShowProgress(20);
- hFile = CreateFileW(filePathW, GENERIC_READ, FILE_SHARE_READ, nullptr,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (hFile == INVALID_HANDLE_VALUE) {
- OUTPUT("[-] Failed to open file! Error: %d\n", GetLastError());
- return;
- }
- DWORD fileSize = GetFileSize(hFile, nullptr);
- if (fileSize == INVALID_FILE_SIZE) {
- CloseHandle(hFile);
- OUTPUT("[-] Failed to get file size! Error: %d\n", GetLastError());
- return;
- }
- hFileMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr);
- if (!hFileMapping) {
- CloseHandle(hFile);
- OUTPUT("[-] Failed to create file mapping! Error: %d\n", GetLastError());
- return;
- }
- lpFileContent = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
- if (!lpFileContent) {
- CloseHandle(hFileMapping);
- CloseHandle(hFile);
- OUTPUT("[-] Failed to map view of file! Error: %d\n", GetLastError());
- return;
- }
- // Declare pNtHeaders here, outside the do-while loop.
- PIMAGE_NT_HEADERS pNtHeaders = nullptr; // Initialize to nullptr
- do {
- const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(mapper.GetView());
- if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
- OUTPUT("[-] Invalid DOS signature!\r\n");
- break;
- }
- ShowProgress(30);
- pNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>( // Assign pNtHeaders here
- static_cast<BYTE*>(mapper.GetView()) + pImageDosHeader->e_lfanew);
- if (IsBadReadPtr(pNtHeaders, sizeof(IMAGE_NT_HEADERS)) ||
- pNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
- OUTPUT("[-] Invalid NT signature!\r\n");
- break;
- }
- bool is64Bit = PEHelpers::Is64BitPE(pNtHeaders);
- PIMAGE_NT_HEADERS32 pNtHeaders32 = nullptr;
- PIMAGE_NT_HEADERS64 pNtHeaders64 = nullptr;
- if (is64Bit) {
- auto pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
- }
- else {
- auto pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
- }
- DWORD_PTR imageBase = PEHelpers::GetImageBase(pNtHeaders);
- DWORD sizeOfImage = PEHelpers::GetSizeOfImage(pNtHeaders);
- if (pNtHeaders->FileHeader.NumberOfSections > 96) {
- OUTPUT("[-] Suspicious number of sections detected!\n");
- break;
- }
- //Move this check here after pNtHeaders is defined
- if (!PEHelpers::ValidateFileSize(pNtHeaders->OptionalHeader.SizeOfHeaders, fileSize)) {
- OUTPUT("[-] Invalid image size detected!\n");
- return;
- }
- OUTPUT("[+] PE IMAGE INFORMATION\n\n");
- OUTPUT("[+] Architecture: %s\n\n", is64Bit ? "x64" : "x86");
- OUTPUT("[+] DOS HEADER\n");
- OUTPUT("\te_magic : 0x%X\n", pImageDosHeader->e_magic);
- OUTPUT("\te_cblp : 0x%X\n", pImageDosHeader->e_cblp);
- OUTPUT("\te_cp : 0x%X\n", pImageDosHeader->e_cp);
- OUTPUT("\te_crlc : 0x%X\n", pImageDosHeader->e_crlc);
- OUTPUT("\te_cparhdr : 0x%X\n", pImageDosHeader->e_cparhdr);
- OUTPUT("\te_minalloc : 0x%X\n", pImageDosHeader->e_minalloc);
- OUTPUT("\te_maxalloc : 0x%X\n", pImageDosHeader->e_maxalloc);
- OUTPUT("\te_ss : 0x%X\n", pImageDosHeader->e_ss);
- OUTPUT("\te_sp : 0x%X\n", pImageDosHeader->e_sp);
- OUTPUT("\te_csum : 0x%X\n", pImageDosHeader->e_csum);
- OUTPUT("\te_ip : 0x%X\n", pImageDosHeader->e_ip);
- OUTPUT("\te_cs : 0x%X\n", pImageDosHeader->e_cs);
- OUTPUT("\te_lfarlc : 0x%X\n", pImageDosHeader->e_lfarlc);
- OUTPUT("\te_ovno : 0x%X\n", pImageDosHeader->e_ovno);
- OUTPUT("\te_oemid : 0x%X\n", pImageDosHeader->e_oemid);
- OUTPUT("\te_oeminfo : 0x%X\n", pImageDosHeader->e_oeminfo);
- OUTPUT("\te_lfanew : 0x%X\n\n", pImageDosHeader->e_lfanew);
- OUTPUT("[+] NT HEADER\n");
- OUTPUT("\tSignature : 0x%X\n\n", pNtHeaders->Signature);
- ShowProgress(40);
- OUTPUT("[+] FILE HEADER\n");
- OUTPUT("\tMachine: 0x%X\n", pNtHeaders->FileHeader.Machine);
- OUTPUT("\tNumberOfSections: 0x%X\n", pNtHeaders->FileHeader.NumberOfSections);
- OUTPUT("\tTimeDateStamp: 0x%X\n", pNtHeaders->FileHeader.TimeDateStamp);
- OUTPUT("\tPointerToSymbolTable: 0x%X\n", pNtHeaders->FileHeader.PointerToSymbolTable);
- OUTPUT("\tNumberOfSymbols: 0x%X\n", pNtHeaders->FileHeader.NumberOfSymbols);
- OUTPUT("\tSizeOfOptionalHeader: 0x%X\n", pNtHeaders->FileHeader.SizeOfOptionalHeader);
- OUTPUT("\tCharacteristics: 0x%X %s\n\n",
- pNtHeaders->FileHeader.Characteristics,
- PEHelpers::GetImageCharacteristics(pNtHeaders->FileHeader.Characteristics).c_str());
- ShowProgress(50);
- OUTPUT("[+] OPTIONAL HEADER\n");
- OUTPUT("\tMagic: 0x%X\n", pNtHeaders->OptionalHeader.Magic);
- OUTPUT("\tAddressOfEntryPoint: 0x%X\n", pNtHeaders->OptionalHeader.AddressOfEntryPoint);
- OUTPUT("\tImageBase: 0x%p\n", (void*)imageBase);
- OUTPUT("\tSectionAlignment: 0x%X\n", pNtHeaders->OptionalHeader.SectionAlignment);
- OUTPUT("\tFileAlignment: 0x%X\n", pNtHeaders->OptionalHeader.FileAlignment);
- OUTPUT("\tMajorOperatingSystemVersion: 0x%X\n", pNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
- OUTPUT("\tMinorOperatingSystemVersion: 0x%X\n", pNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
- OUTPUT("\tMajorImageVersion: 0x%X\n", pNtHeaders->OptionalHeader.MajorImageVersion);
- OUTPUT("\tMinorImageVersion: 0x%X\n", pNtHeaders->OptionalHeader.MinorImageVersion);
- OUTPUT("\tMajorSubsystemVersion: 0x%X\n", pNtHeaders->OptionalHeader.MajorSubsystemVersion);
- OUTPUT("\tMinorSubsystemVersion: 0x%X\n", pNtHeaders->OptionalHeader.MinorSubsystemVersion);
- OUTPUT("\tWin32VersionValue: 0x%X\n", pNtHeaders->OptionalHeader.Win32VersionValue);
- OUTPUT("\tSizeOfImage: 0x%X\n", sizeOfImage);
- OUTPUT("\tSizeOfHeaders: 0x%X\n", pNtHeaders->OptionalHeader.SizeOfHeaders);
- OUTPUT("\tCheckSum: 0x%X\n", pNtHeaders->OptionalHeader.CheckSum);
- OUTPUT("\tSubsystem: 0x%X %s\n",
- pNtHeaders->OptionalHeader.Subsystem,
- PEHelpers::GetSubsystem(pNtHeaders->OptionalHeader.Subsystem).c_str());
- OUTPUT("\n[+] DATA DIRECTORIES\n");
- for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
- const auto& dir = pNtHeaders->OptionalHeader.DataDirectory[i];
- if (dir.VirtualAddress != 0) {
- if (!PEHelpers::IsRvaValid(dir.VirtualAddress, fileSize, pNtHeaders)) {
- OUTPUT("\t%s: Invalid RVA detected!\n", PEHelpers::GetDataDirectoryName(i).c_str());
- continue;
- }
- OUTPUT("\t%s:\n", PEHelpers::GetDataDirectoryName(i).c_str());
- OUTPUT("\t\tVirtualAddress: 0x%X\n", dir.VirtualAddress);
- OUTPUT("\t\tSize: 0x%X\n", dir.Size);
- }
- }
- ShowProgress(60);
- OUTPUT("\n[+] SECTION HEADERS\n");
- auto pSection = IMAGE_FIRST_SECTION(pNtHeaders);
- for (WORD i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++, pSection++) {
- if (IsBadReadPtr(pSection, sizeof(IMAGE_SECTION_HEADER))) {
- OUTPUT("[-] Invalid section header detected!\n");
- break;
- }
- char sectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
- memcpy(sectionName, pSection->Name, IMAGE_SIZEOF_SHORT_NAME);
- for (int j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) {
- if (!isprint(static_cast<unsigned char>(sectionName[j]))) {
- sectionName[j] = '\0';
- }
- }
- wchar_t wideSectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
- sectionName, -1,
- wideSectionName, IMAGE_SIZEOF_SHORT_NAME + 1);
- OUTPUT("\tSECTION: %s\n", wideSectionName);
- OUTPUT("\t\tVirtualSize: 0x%X\n", pSection->Misc.VirtualSize);
- OUTPUT("\t\tVirtualAddress: 0x%X\n", pSection->VirtualAddress);
- OUTPUT("\t\tSizeOfRawData: 0x%X\n", pSection->SizeOfRawData);
- OUTPUT("\t\tPointerToRawData: 0x%X\n", pSection->PointerToRawData);
- OUTPUT("\t\tPointerToRelocations: 0x%X\n", pSection->PointerToRelocations);
- OUTPUT("\t\tPointerToLinenumbers: 0x%X\n", pSection->PointerToLinenumbers);
- OUTPUT("\t\tNumberOfRelocations: 0x%X\n", pSection->NumberOfRelocations);
- OUTPUT("\t\tNumberOfLinenumbers: 0x%X\n", pSection->NumberOfLinenumbers);
- OUTPUT("\t\tCharacteristics: 0x%X %s\n\n",
- pSection->Characteristics,
- PEHelpers::GetSectionProtection(pSection->Characteristics).c_str());
- }
- ShowProgress(70);
- const auto& importDir = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
- if (importDir.VirtualAddress && importDir.Size) {
- if (!PEHelpers::IsRvaValid(importDir.VirtualAddress, fileSize, pNtHeaders)) {
- OUTPUT("[-] Invalid import directory RVA!\n");
- break;
- }
- OUTPUT("\n[+] IMPORT DIRECTORY\n");
- auto pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)PEHelpers::GetRvaPtr(
- importDir.VirtualAddress,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pImportDesc) {
- while (pImportDesc->Name != 0) {
- if (IsBadReadPtr(pImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
- OUTPUT("[-] Invalid import descriptor detected!\n");
- break;
- }
- const char* dllName = (const char*)PEHelpers::GetRvaPtr(
- pImportDesc->Name,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (dllName && !IsBadReadPtr(dllName, 1)) {
- std::vector<wchar_t> wideDllName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, dllName, -1, wideDllName.data(), MAX_PATH);
- OUTPUT("\n\tDLL NAME: %s\n", wideDllName.data());
- OUTPUT("\tCharacteristics: 0x%X\n", pImportDesc->Characteristics);
- OUTPUT("\tTimeDateStamp: 0x%X\n", pImportDesc->TimeDateStamp);
- OUTPUT("\tForwarderChain: 0x%X\n", pImportDesc->ForwarderChain);
- OUTPUT("\tFirstThunk: 0x%X\n", pImportDesc->FirstThunk);
- OUTPUT("\n\tImported Functions:\n");
- if (is64Bit) {
- auto pThunk = (PIMAGE_THUNK_DATA64)PEHelpers::GetRvaPtr(
- pImportDesc->OriginalFirstThunk ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- while (pThunk && pThunk->u1.AddressOfData) {
- if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)) {
- auto pImportByName = (PIMAGE_IMPORT_BY_NAME)PEHelpers::GetRvaPtr(
- (DWORD)pThunk->u1.AddressOfData,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pImportByName && !IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
- std::vector<wchar_t> wideFuncName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, (char*)pImportByName->Name, -1,
- wideFuncName.data(), MAX_PATH);
- OUTPUT("\t\t%s\n", wideFuncName.data());
- }
- }
- else {
- OUTPUT("\t\tOrdinal: %lld\n", pThunk->u1.Ordinal & 0xFFFF);
- }
- pThunk++;
- }
- }
- else {
- auto pThunk = (PIMAGE_THUNK_DATA32)PEHelpers::GetRvaPtr(
- pImportDesc->OriginalFirstThunk ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- while (pThunk && pThunk->u1.AddressOfData) {
- if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)) {
- auto pImportByName = (PIMAGE_IMPORT_BY_NAME)PEHelpers::GetRvaPtr(
- pThunk->u1.AddressOfData,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pImportByName && !IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
- std::vector<wchar_t> wideFuncName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, (char*)pImportByName->Name, -1,
- wideFuncName.data(), MAX_PATH);
- OUTPUT("\t\t%s\n", wideFuncName.data());
- }
- }
- else {
- OUTPUT("\t\tOrdinal: %d\n", pThunk->u1.Ordinal & 0xFFFF);
- }
- pThunk++;
- }
- }
- }
- pImportDesc++;
- }
- }
- }
- ShowProgress(80);
- const auto& exportDir = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
- if (exportDir.VirtualAddress && exportDir.Size) {
- if (!PEHelpers::IsRvaValid(exportDir.VirtualAddress, fileSize, pNtHeaders)) {
- OUTPUT("[-] Invalid export directory RVA!\n");
- break;
- }
- OUTPUT("\n[+] EXPORT DIRECTORY\n");
- auto pExportDir = (PIMAGE_EXPORT_DIRECTORY)PEHelpers::GetRvaPtr(
- exportDir.VirtualAddress,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pExportDir && !IsBadReadPtr(pExportDir, sizeof(IMAGE_EXPORT_DIRECTORY))) {
- OUTPUT("\tCharacteristics: 0x%X\n", pExportDir->Characteristics);
- OUTPUT("\tTimeDateStamp: 0x%X\n", pExportDir->TimeDateStamp);
- OUTPUT("\tMajorVersion: %d\n", pExportDir->MajorVersion);
- OUTPUT("\tMinorVersion: %d\n", pExportDir->MinorVersion);
- OUTPUT("\tName: 0x%X\n", pExportDir->Name);
- OUTPUT("\tBase: %d\n", pExportDir->Base);
- OUTPUT("\tNumberOfFunctions: %d\n", pExportDir->NumberOfFunctions);
- OUTPUT("\tNumberOfNames: %d\n", pExportDir->NumberOfNames);
- OUTPUT("\tAddressOfFunctions: 0x%X\n", pExportDir->AddressOfFunctions);
- OUTPUT("\tAddressOfNames: 0x%X\n", pExportDir->AddressOfNames);
- OUTPUT("\tAddressOfNameOrdinals: 0x%X\n\n", pExportDir->AddressOfNameOrdinals);
- auto pFunctions = (PDWORD)PEHelpers::GetRvaPtr(
- pExportDir->AddressOfFunctions,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- auto pNames = (PDWORD)PEHelpers::GetRvaPtr(
- pExportDir->AddressOfNames,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- auto pNameOrdinals = (PWORD)PEHelpers::GetRvaPtr(
- pExportDir->AddressOfNameOrdinals,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pNames && pNameOrdinals && pFunctions) {
- OUTPUT("\tExported Functions:\n\n");
- for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {
- if (IsBadReadPtr(pNames + i, sizeof(DWORD)) ||
- IsBadReadPtr(pNameOrdinals + i, sizeof(WORD))) {
- break;
- }
- const char* functionName = (const char*)PEHelpers::GetRvaPtr(
- pNames[i],
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (functionName && !IsBadReadPtr(functionName, 1)) {
- WORD ordinal = pNameOrdinals[i];
- if (ordinal < pExportDir->NumberOfFunctions) {
- DWORD functionRva = pFunctions[ordinal];
- if (functionRva >= exportDir.VirtualAddress &&
- functionRva < (exportDir.VirtualAddress + exportDir.Size)) {
- const char* forwardName = (const char*)PEHelpers::GetRvaPtr(
- functionRva,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (forwardName && !IsBadReadPtr(forwardName, 1)) {
- std::vector<wchar_t> wideForwardName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, forwardName, -1,
- wideForwardName.data(), MAX_PATH);
- OUTPUT("\t\t%s (Ordinal: %d) -> Forward to: %s\n",
- functionName,
- ordinal + pExportDir->Base,
- wideForwardName.data());
- }
- }
- else {
- OUTPUT("\t\t%s (Ordinal: %d, RVA: 0x%08X)\n",
- functionName,
- ordinal + pExportDir->Base,
- functionRva);
- }
- }
- }
- }
- }
- }
- }
- ShowProgress(90);
- const auto& resourceDir = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
- if (resourceDir.VirtualAddress && resourceDir.Size) {
- if (!PEHelpers::IsRvaValid(resourceDir.VirtualAddress, fileSize, pNtHeaders)) {
- OUTPUT("[-] Invalid resource directory RVA!\n");
- break;
- }
- OUTPUT("\n[+] RESOURCE DIRECTORY\n");
- auto pResourceDir = (PIMAGE_RESOURCE_DIRECTORY)PEHelpers::GetRvaPtr(
- resourceDir.VirtualAddress,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pResourceDir && !IsBadReadPtr(pResourceDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
- const wchar_t* resourceTypes[] = {
- L"Unknown", L"Cursor", L"Bitmap", L"Icon",
- L"Menu", L"Dialog", L"String", L"FontDir",
- L"Font", L"Accelerator", L"RCData", L"MessageTable",
- L"GroupCursor", L"GroupIcon", L"Version", L"DlgInclude"
- };
- ProcessResourceDirectory(pResourceDir, 0, nullptr,
- pResourceDir, resourceTypes, pNtHeaders, lpFileContent);
- }
- else {
- OUTPUT("[-] Invalid or corrupted resource directory\n");
- }
- }
- const auto& debugDir = pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
- if (debugDir.VirtualAddress && debugDir.Size) {
- if (!PEHelpers::IsRvaValid(debugDir.VirtualAddress, fileSize, pNtHeaders)) {
- OUTPUT("[-] Invalid debug directory RVA!\n");
- break;
- }
- OUTPUT("\n[+] DEBUG DIRECTORY\n");
- auto pDebugDir = (PIMAGE_DEBUG_DIRECTORY)PEHelpers::GetRvaPtr(
- debugDir.VirtualAddress,
- IMAGE_FIRST_SECTION(pNtHeaders),
- pNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pDebugDir && !IsBadReadPtr(pDebugDir, sizeof(IMAGE_DEBUG_DIRECTORY))) {
- DWORD numEntries = min(debugDir.Size / sizeof(IMAGE_DEBUG_DIRECTORY), 16);
- for (DWORD i = 0; i < numEntries; i++) {
- OUTPUT("\tCharacteristics: 0x%X\n", pDebugDir[i].Characteristics);
- OUTPUT("\tTimeDateStamp: 0x%X\n", pDebugDir[i].TimeDateStamp);
- OUTPUT("\tMajorVersion: %d\n", pDebugDir[i].MajorVersion);
- OUTPUT("\tMinorVersion: %d\n", pDebugDir[i].MinorVersion);
- OUTPUT("\tType: 0x%X", pDebugDir[i].Type);
- switch (pDebugDir[i].Type) {
- case IMAGE_DEBUG_TYPE_COFF:
- OUTPUT(" (COFF)\n"); break;
- case IMAGE_DEBUG_TYPE_CODEVIEW:
- OUTPUT(" (CodeView)\n"); break;
- case IMAGE_DEBUG_TYPE_FPO:
- OUTPUT(" (FPO)\n"); break;
- case IMAGE_DEBUG_TYPE_MISC:
- OUTPUT(" (Misc)\n"); break;
- case IMAGE_DEBUG_TYPE_EXCEPTION:
- OUTPUT(" (Exception)\n"); break;
- default:
- OUTPUT(" (Unknown)\n"); break;
- }
- OUTPUT("\tSizeOfData: 0x%X\n", pDebugDir[i].SizeOfData);
- OUTPUT("\tAddressOfRawData: 0x%X\n", pDebugDir[i].AddressOfRawData);
- OUTPUT("\tPointerToRawData: 0x%X\n\n", pDebugDir[i].PointerToRawData);
- if (pDebugDir[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW &&
- pDebugDir[i].PointerToRawData != 0 &&
- pDebugDir[i].SizeOfData >= 24) {
- auto pCVHeader = (DWORD*)((BYTE*)lpFileContent + pDebugDir[i].PointerToRawData);
- if (!IsBadReadPtr(pCVHeader, sizeof(DWORD)) && *pCVHeader == 0x53445352) {
- auto pCVData = (char*)(pCVHeader + 1);
- if (!IsBadReadPtr(pCVData + 16, 1)) {
- std::vector<wchar_t> pdbPath(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, pCVData + 16, -1,
- pdbPath.data(), MAX_PATH);
- OUTPUT("\tPDB Path: %s\n\n", pdbPath.data());
- }
- }
- }
- }
- }
- }
- ShowProgress(100);
- SetStatusText(L"Analysis complete");
- ShowWindow(g_hProgressBar, SW_HIDE);
- } while (false); // End of the do-while loop that replaced goto
- // Cleanup
- if (lpFileContent) UnmapViewOfFile(lpFileContent);
- if (hFileMapping) CloseHandle(hFileMapping);
- if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
- UpdateEditControl();
- }
- /*OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
- FileMapper mapper;
- if (!mapper.Initialize(filePathW)) {
- SetStatusText(L"Failed to open file!");
- OUTPUT("[-] Failed to open file! Error: %d\r\n", GetLastError());
- return;
- }
- ShowProgress(20); // After initial file opening
- // Open and read file
- HANDLE hFile = CreateFileW(filePathW, GENERIC_READ, FILE_SHARE_READ, nullptr,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
- if (hFile == INVALID_HANDLE_VALUE) {
- OUTPUT("[-] Failed to open file! Error: %d\n", GetLastError());
- return;
- }
- DWORD fileSize = GetFileSize(hFile, nullptr);
- if (fileSize == INVALID_FILE_SIZE) {
- CloseHandle(hFile);
- OUTPUT("[-] Failed to get file size! Error: %d\n", GetLastError());
- return;
- }
- HANDLE hFileMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr);
- if (!hFileMapping) {
- CloseHandle(hFile);
- OUTPUT("[-] Failed to create file mapping! Error: %d\n", GetLastError());
- return;
- }
- LPVOID lpFileContent = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
- if (!lpFileContent) {
- CloseHandle(hFileMapping);
- CloseHandle(hFile);
- OUTPUT("[-] Failed to map view of file! Error: %d\n", GetLastError());
- return;
- }
- const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(mapper.GetView());
- if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
- OUTPUT("[-] Invalid DOS signature!\r\n");
- return;
- }
- ShowProgress(30);
- const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
- static_cast<BYTE*>(mapper.GetView()) + pImageDosHeader->e_lfanew);
- if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
- OUTPUT("[-] Invalid NT signature!\r\n");
- return;
- }
- // Add right after this line:
- // OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
- // Add PE Image Information and Architecture
- OUTPUT("[+] PE IMAGE INFORMATION\n\n");
- // Replace the Architecture output line with this:
- if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
- OUTPUT("[+] Architecture: x86\n\n");
- }
- else if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) {
- OUTPUT("[+] Architecture: x64\n\n");
- }
- else {
- OUTPUT("[+] Architecture: Unknown\n\n");
- }
- // Add complete DOS Header information
- OUTPUT("[+] DOS HEADER\n");
- OUTPUT("\te_magic : 0x%X\n", pImageDosHeader->e_magic);
- OUTPUT("\te_cblp : 0x%X\n", pImageDosHeader->e_cblp);
- OUTPUT("\te_cp : 0x%X\n", pImageDosHeader->e_cp);
- OUTPUT("\te_crlc : 0x%X\n", pImageDosHeader->e_crlc);
- OUTPUT("\te_cparhdr : 0x%X\n", pImageDosHeader->e_cparhdr);
- OUTPUT("\te_minalloc : 0x%X\n", pImageDosHeader->e_minalloc);
- OUTPUT("\te_maxalloc : 0x%X\n", pImageDosHeader->e_maxalloc);
- OUTPUT("\te_ss : 0x%X\n", pImageDosHeader->e_ss);
- OUTPUT("\te_sp : 0x%X\n", pImageDosHeader->e_sp);
- OUTPUT("\te_csum : 0x%X\n", pImageDosHeader->e_csum);
- OUTPUT("\te_ip : 0x%X\n", pImageDosHeader->e_ip);
- OUTPUT("\te_cs : 0x%X\n", pImageDosHeader->e_cs);
- OUTPUT("\te_lfarlc : 0x%X\n", pImageDosHeader->e_lfarlc);
- OUTPUT("\te_ovno : 0x%X\n", pImageDosHeader->e_ovno);
- OUTPUT("\te_oemid : 0x%X\n", pImageDosHeader->e_oemid);
- OUTPUT("\te_oeminfo : 0x%X\n", pImageDosHeader->e_oeminfo);
- OUTPUT("\te_lfanew : 0x%X\n\n", pImageDosHeader->e_lfanew);
- // Add NT Header signature before the existing PE FILE HEADER section
- OUTPUT("[+] NT HEADER\n");
- OUTPUT("\tSignature : 0x%X\n\n", pImageNtHeaders->Signature);
- // The rest of your existing code continues here...
- // OUTPUT("[+] PE FILE HEADER\n");
- ShowProgress(40);
- // Print File Header Information
- OUTPUT("[+] PE FILE HEADER\n");
- OUTPUT("\tMachine: 0x%X\n", pImageNtHeaders->FileHeader.Machine);
- OUTPUT("\tNumberOfSections: 0x%X\n", pImageNtHeaders->FileHeader.NumberOfSections);
- OUTPUT("\tTimeDateStamp: 0x%X\n", pImageNtHeaders->FileHeader.TimeDateStamp);
- OUTPUT("\tPointerToSymbolTable: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->FileHeader.PointerToSymbolTable));
- OUTPUT("\tNumberOfSymbols: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->FileHeader.NumberOfSymbols));
- OUTPUT("\tSizeOfOptionalHeader: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->FileHeader.SizeOfOptionalHeader));
- OUTPUT("\tCharacteristics: 0x%X %s\n\n",
- pImageNtHeaders->FileHeader.Characteristics,
- PEHelpers::GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics).c_str());
- ShowProgress(50);
- // Print Optional Header Information
- OUTPUT("[+] PE OPTIONAL HEADER\n");
- OUTPUT("\tMagic: 0x%X\n", pImageNtHeaders->OptionalHeader.Magic);
- OUTPUT("\tAddressOfEntryPoint: 0x%X\n", pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
- OUTPUT("\tImageBase: 0x%llX\n", (ULONGLONG)pImageNtHeaders->OptionalHeader.ImageBase);
- OUTPUT("\tSectionAlignment: 0x%X\n", pImageNtHeaders->OptionalHeader.SectionAlignment);
- OUTPUT("\tFileAlignment: 0x%X\n", pImageNtHeaders->OptionalHeader.FileAlignment);
- // Added missing Optional Header fields
- OUTPUT("\tMajorOperatingSystemVersion: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion));
- OUTPUT("\tMinorOperatingSystemVersion: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion));
- OUTPUT("\tMajorImageVersion: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorImageVersion));
- OUTPUT("\tMinorImageVersion: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorImageVersion));
- OUTPUT("\tMajorSubsystemVersion: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorSubsystemVersion));
- OUTPUT("\tMinorSubsystemVersion: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorSubsystemVersion));
- OUTPUT("\tWin32VersionValue: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.Win32VersionValue));
- OUTPUT("\tSizeOfImage: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.SizeOfImage));
- OUTPUT("\tSizeOfHeaders: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.SizeOfHeaders));
- OUTPUT("\tCheckSum: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.CheckSum));
- OUTPUT("\tSubsystem: 0x%X %s\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.Subsystem),
- PEHelpers::GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem).c_str());
- OUTPUT("\tDllCharacteristics: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.DllCharacteristics));
- OUTPUT("\tSizeOfStackReserve: 0x%llX\r\n",
- static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfStackReserve));
- OUTPUT("\tSizeOfStackCommit: 0x%llX\r\n",
- static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfStackCommit));
- OUTPUT("\tSizeOfHeapReserve: 0x%llX\r\n",
- static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfHeapReserve));
- OUTPUT("\tSizeOfHeapCommit: 0x%llX\r\n",
- static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfHeapCommit));
- OUTPUT("\tLoaderFlags: 0x%X\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.LoaderFlags));
- OUTPUT("\tNumberOfRvaAndSizes: 0x%X\r\n\r\n",
- static_cast<DWORD>(pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes));
- OUTPUT("\tSubsystem: 0x%X %s\n\n",
- pImageNtHeaders->OptionalHeader.Subsystem,
- PEHelpers::GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem).c_str());
- // Print Data Directories
- OUTPUT("[+] PE DATA DIRECTORIES\n");
- for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
- const auto& dir = pImageNtHeaders->OptionalHeader.DataDirectory[i];
- if (dir.VirtualAddress != 0) {
- OUTPUT("\t%s:\n", PEHelpers::GetDataDirectoryName(i).c_str());
- OUTPUT("\t\tVirtualAddress: 0x%X\n", dir.VirtualAddress);
- OUTPUT("\t\tSize: 0x%X\n", dir.Size);
- }
- }
- // Analyze Sections
- OUTPUT("\n[+] PE IMAGE SECTIONS\r\n");
- auto pSection = IMAGE_FIRST_SECTION(pImageNtHeaders);
- for (WORD i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++, pSection++) {
- // Create a null-terminated string from the section name
- char sectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
- memcpy(sectionName, pSection->Name, IMAGE_SIZEOF_SHORT_NAME);
- // Remove any non-printable characters
- for (int j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) {
- if (!isprint(static_cast<unsigned char>(sectionName[j]))) {
- sectionName[j] = '\0';
- }
- }
- // Convert to wide string
- wchar_t wideSectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
- MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
- sectionName, -1,
- wideSectionName, IMAGE_SIZEOF_SHORT_NAME + 1);
- OUTPUT("\tSECTION : %s\r\n", wideSectionName);
- OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\r\n", pSection->Misc.PhysicalAddress);
- OUTPUT("\t\tMisc (VirtualSize) : 0x%X\r\n", pSection->Misc.VirtualSize);
- OUTPUT("\t\tVirtualAddress : 0x%X\r\n", pSection->VirtualAddress);
- OUTPUT("\t\tSizeOfRawData : 0x%X\r\n", pSection->SizeOfRawData);
- OUTPUT("\t\tPointerToRawData : 0x%X\r\n", pSection->PointerToRawData);
- OUTPUT("\t\tPointerToRelocations : 0x%X\r\n", pSection->PointerToRelocations);
- OUTPUT("\t\tPointerToLinenumbers : 0x%X\r\n", pSection->PointerToLinenumbers);
- OUTPUT("\t\tNumberOfRelocations : 0x%X\r\n", pSection->NumberOfRelocations);
- OUTPUT("\t\tNumberOfLinenumbers : 0x%X\r\n", pSection->NumberOfLinenumbers);
- OUTPUT("\t\tCharacteristics : 0x%X %s\r\n\r\n",
- pSection->Characteristics,
- PEHelpers::GetSectionProtection(pSection->Characteristics).c_str());
- }
- ShowProgress(60);
- // Analyze Imports
- // Then modify the Import section like this:
- const auto& importDir = pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
- if (importDir.VirtualAddress && importDir.Size) {
- OUTPUT("\n[+] IMPORTED DLLS AND FUNCTIONS\r\n");
- auto pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)PEHelpers::GetRvaPtr(
- importDir.VirtualAddress,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- bool is64Bit = Is64BitPE(pImageNtHeaders);
- while (pImportDesc && pImportDesc->Name != 0) {
- const char* dllName = (const char*)PEHelpers::GetRvaPtr(
- pImportDesc->Name,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (dllName) {
- std::vector<wchar_t> wideDllName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, dllName, -1, wideDllName.data(), MAX_PATH);
- OUTPUT("\n\tDLL NAME : %s\r\n", wideDllName.data());
- OUTPUT("\tCharacteristics : 0x%X\r\n", pImportDesc->Characteristics);
- OUTPUT("\tOriginalFirstThunk : 0x%X\r\n", pImportDesc->OriginalFirstThunk);
- OUTPUT("\tTimeDateStamp : 0x%X\r\n", pImportDesc->TimeDateStamp);
- OUTPUT("\tForwarderChain : 0x%X\r\n", pImportDesc->ForwarderChain);
- OUTPUT("\tFirstThunk : 0x%X\r\n", pImportDesc->FirstThunk);
- OUTPUT("\n\tImported Functions :\r\n\r\n");
- ULONGLONG ordinalFlag = is64Bit ? IMAGE_ORDINAL_FLAG64 : IMAGE_ORDINAL_FLAG32;
- if (is64Bit) {
- auto pThunk = (PIMAGE_THUNK_DATA64)PEHelpers::GetRvaPtr(
- pImportDesc->OriginalFirstThunk ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- while (pThunk && pThunk->u1.AddressOfData) {
- if (!(pThunk->u1.Ordinal & ordinalFlag)) {
- auto pImportByName = (PIMAGE_IMPORT_BY_NAME)PEHelpers::GetRvaPtr(
- (DWORD)pThunk->u1.AddressOfData,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pImportByName && !IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
- std::vector<wchar_t> wideFuncName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, (char*)pImportByName->Name, -1,
- wideFuncName.data(), MAX_PATH);
- OUTPUT("\t\t%s\r\n", wideFuncName.data());
- }
- }
- else {
- OUTPUT("\t\tOrdinal: %lld\r\n", pThunk->u1.Ordinal & 0xFFFF);
- }
- pThunk++;
- }
- }
- else {
- auto pThunk = (PIMAGE_THUNK_DATA32)PEHelpers::GetRvaPtr(
- pImportDesc->OriginalFirstThunk ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- while (pThunk && pThunk->u1.AddressOfData) {
- if (!(pThunk->u1.Ordinal & ordinalFlag)) {
- auto pImportByName = (PIMAGE_IMPORT_BY_NAME)PEHelpers::GetRvaPtr(
- pThunk->u1.AddressOfData,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pImportByName && !IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
- std::vector<wchar_t> wideFuncName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, (char*)pImportByName->Name, -1,
- wideFuncName.data(), MAX_PATH);
- OUTPUT("\t\t%s\r\n", wideFuncName.data());
- }
- }
- else {
- OUTPUT("\t\tOrdinal: %d\r\n", pThunk->u1.Ordinal & 0xFFFF);
- }
- pThunk++;
- }
- }
- }
- pImportDesc++;
- }
- }
- ShowProgress(70);
- // In your AnalyzePEFile function, add this code after the imports section (before the cleanup label):
- // Handle Exports
- const auto& exportDir = pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
- if (exportDir.VirtualAddress && exportDir.Size) {
- OUTPUT("\n[+] EXPORTED FUNCTIONS\n");
- auto pExportDir = (PIMAGE_EXPORT_DIRECTORY)PEHelpers::GetRvaPtr(
- exportDir.VirtualAddress,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pExportDir) {
- // ... (existing code)
- auto pFunctions = (PDWORD)PEHelpers::GetRvaPtr(
- pExportDir->AddressOfFunctions,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- auto pNames = (PDWORD)PEHelpers::GetRvaPtr(
- pExportDir->AddressOfNames,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- auto pNameOrdinals = (PWORD)PEHelpers::GetRvaPtr(
- pExportDir->AddressOfNameOrdinals,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pNames && pNameOrdinals && pFunctions) {
- for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {
- const char* functionName = (const char*)PEHelpers::GetRvaPtr(
- pNames[i],
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (functionName) {
- WORD ordinal = pNameOrdinals[i];
- DWORD functionRva = pFunctions[ordinal];
- std::vector<wchar_t> wideFuncName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, functionName, -1,
- wideFuncName.data(), MAX_PATH);
- // Check if it's a forwarded export
- if (functionRva >= exportDir.VirtualAddress &&
- functionRva < (exportDir.VirtualAddress + exportDir.Size)) {
- // This is a forwarded export
- const char* forwardName = (const char*)PEHelpers::GetRvaPtr(
- functionRva,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (forwardName) {
- std::vector<wchar_t> wideForwardName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, forwardName, -1,
- wideForwardName.data(), MAX_PATH);
- OUTPUT("\t\t%s (Ordinal: %d) -> Forward to: %s\n",
- wideFuncName.data(),
- ordinal + pExportDir->Base,
- wideForwardName.data());
- }
- }
- else {
- OUTPUT("\t\t%s (Ordinal: %d, RVA: 0x%08X)\n",
- wideFuncName.data(),
- ordinal + pExportDir->Base,
- functionRva);
- }
- }
- }
- // Check for exports by ordinal only (no names)
- for (DWORD i = 0; i < pExportDir->NumberOfFunctions; i++) {
- if (pFunctions[i] != 0) {
- bool hasName = false;
- for (DWORD j = 0; j < pExportDir->NumberOfNames; j++) {
- if (pNameOrdinals[j] == i) {
- hasName = true;
- break;
- }
- }
- if (!hasName) {
- DWORD functionRva = pFunctions[i];
- if (functionRva >= exportDir.VirtualAddress &&
- functionRva < (exportDir.VirtualAddress + exportDir.Size)) {
- // This is a forwarded export
- const char* forwardName = (const char*)PEHelpers::GetRvaPtr(
- functionRva,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (forwardName) {
- std::vector<wchar_t> wideForwardName(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, forwardName, -1,
- wideForwardName.data(), MAX_PATH);
- OUTPUT("\t\tOrdinal: %d -> Forward to: %s\n",
- i + pExportDir->Base,
- wideForwardName.data());
- }
- }
- else {
- OUTPUT("\t\tOrdinal: %d (RVA: 0x%08X)\n",
- i + pExportDir->Base,
- functionRva);
- }
- }
- }
- }
- }
- }
- }
- ShowProgress(80);
- // Add after export directory analysis and before ShowProgress(100)
- // Resource Directory Analysis
- const auto& resourceDir = pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
- if (resourceDir.VirtualAddress && resourceDir.Size) {
- OUTPUT("\n[+] RESOURCE DIRECTORY\n");
- auto pResourceDir = (PIMAGE_RESOURCE_DIRECTORY)PEHelpers::GetRvaPtr(
- resourceDir.VirtualAddress,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (pResourceDir && !IsBadReadPtr(pResourceDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
- OUTPUT("\tCharacteristics: 0x%X\n", pResourceDir->Characteristics);
- OUTPUT("\tTimeDateStamp: 0x%X\n", pResourceDir->TimeDateStamp);
- OUTPUT("\tMajorVersion: %d\n", pResourceDir->MajorVersion);
- OUTPUT("\tMinorVersion: %d\n", pResourceDir->MinorVersion);
- OUTPUT("\tNumberOfNamedEntries: %d\n", pResourceDir->NumberOfNamedEntries);
- OUTPUT("\tNumberOfIdEntries: %d\n\n", pResourceDir->NumberOfIdEntries);
- const wchar_t* resourceTypes[] = {
- L"Unknown", L"Cursor", L"Bitmap", L"Icon",
- L"Menu", L"Dialog", L"String", L"FontDir",
- L"Font", L"Accelerator", L"RCData", L"MessageTable",
- L"GroupCursor", L"GroupIcon", L"Version", L"DlgInclude"
- };
- auto ProcessResourceDirectory = [&](PIMAGE_RESOURCE_DIRECTORY resDir, int level, const wchar_t* type = nullptr) {
- if (IsBadReadPtr(resDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
- return;
- }
- auto entry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resDir + 1);
- WORD totalEntries = resDir->NumberOfNamedEntries + resDir->NumberOfIdEntries;
- for (WORD i = 0; i < totalEntries; i++) {
- if (IsBadReadPtr(entry + i, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))) {
- break;
- }
- for (int indent = 0; indent < level; indent++) {
- OUTPUT("\t");
- }
- if (entry[i].NameIsString) {
- auto nameEntry = (PIMAGE_RESOURCE_DIR_STRING_U)((BYTE*)pResourceDir + entry[i].NameOffset);
- if (!IsBadReadPtr(nameEntry, sizeof(IMAGE_RESOURCE_DIR_STRING_U))) {
- std::vector<wchar_t> resourceName(nameEntry->Length + 1);
- wcsncpy_s(resourceName.data(), nameEntry->Length + 1,
- nameEntry->NameString, nameEntry->Length);
- resourceName[nameEntry->Length] = L'\0';
- if (level == 0) {
- OUTPUT("Resource Type: Custom (%s)\n", resourceName.data());
- }
- else {
- OUTPUT("Name: %s\n", resourceName.data());
- }
- }
- }
- else {
- if (level == 0) {
- DWORD resourceType = entry[i].Id;
- if (resourceType < 16) {
- OUTPUT("Resource Type: %s (ID: %d)\n", resourceTypes[resourceType], resourceType);
- }
- else {
- OUTPUT("Resource Type: Custom (ID: %d)\n", resourceType);
- }
- }
- else {
- OUTPUT("ID: %d\n", entry[i].Id);
- }
- }
- if (entry[i].DataIsDirectory) {
- auto nextDir = (PIMAGE_RESOURCE_DIRECTORY)((BYTE*)pResourceDir + entry[i].OffsetToDirectory);
- if (!IsBadReadPtr(nextDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
- ProcessResourceDirectory(nextDir, level + 1,
- level == 0 ? resourceTypes[min(entry[i].Id, 15)] : type);
- }
- }
- else {
- auto dataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((BYTE*)pResourceDir + entry[i].OffsetToData);
- if (!IsBadReadPtr(dataEntry, sizeof(IMAGE_RESOURCE_DATA_ENTRY))) {
- for (int indent = 0; indent < level + 1; indent++) {
- OUTPUT("\t");
- }
- OUTPUT("Size: %d bytes, RVA: 0x%X\n",
- dataEntry->Size, dataEntry->OffsetToData);
- // For Version Info resources, we can extract more details
- if (type && wcscmp(type, L"Version") == 0) {
- auto versionData = (BYTE*)PEHelpers::GetRvaPtr(
- dataEntry->OffsetToData,
- IMAGE_FIRST_SECTION(pImageNtHeaders),
- pImageNtHeaders->FileHeader.NumberOfSections,
- lpFileContent);
- if (versionData && !IsBadReadPtr(versionData, sizeof(VS_FIXEDFILEINFO))) {
- auto versionInfo = (VS_FIXEDFILEINFO*)(versionData + 40); // Skip VS_VERSION_INFO header
- if (versionInfo->dwSignature == 0xFEEF04BD) {
- for (int indent = 0; indent < level + 2; indent++) {
- OUTPUT("\t");
- }
- OUTPUT("File Version: %d.%d.%d.%d\n",
- HIWORD(versionInfo->dwFileVersionMS),
- LOWORD(versionInfo->dwFileVersionMS),
- HIWORD(versionInfo->dwFileVersionLS),
- LOWORD(versionInfo->dwFileVersionLS));
- }
- }
- }
- }
- }
- }
- };
- ProcessResourceDirectory(pResourceDir, 0);
- }
- else {
- OUTPUT("[-] Invalid or corrupted resource directory\n");
- }
- }
- ShowProgress(90);
- // Debug Directory Analysis
- const auto& debugDir = pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
- if (debugDir.VirtualAddress && debugDir.Size) {
- OUTPUT("\n[+] DEBUG DIRECTORY\n");
- auto pSection = IMAGE_FIRST_SECTION(pImageNtHeaders);
- PIMAGE_SECTION_HEADER pDebugSection = nullptr;
- // Find the section containing the debug directory
- for (WORD i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++, pSection++) {
- if (debugDir.VirtualAddress >= pSection->VirtualAddress &&
- debugDir.VirtualAddress < (pSection->VirtualAddress + pSection->Misc.VirtualSize)) {
- pDebugSection = pSection;
- break;
- }
- }
- if (!pDebugSection) {
- OUTPUT("[-] Could not find debug section\n");
- }
- else {
- // Calculate the correct offset for both 32-bit and 64-bit PE files
- DWORD debugDirOffset = pDebugSection->PointerToRawData +
- (debugDir.VirtualAddress - pDebugSection->VirtualAddress);
- auto pDebugDirectory = reinterpret_cast<PIMAGE_DEBUG_DIRECTORY>(
- (BYTE*)lpFileContent + debugDirOffset);
- // Safely process debug entries
- DWORD numEntries = min(debugDir.Size / sizeof(IMAGE_DEBUG_DIRECTORY), 16); // Limit entries to prevent overflow
- for (DWORD i = 0; i < numEntries; i++) {
- if (IsBadReadPtr(pDebugDirectory + i, sizeof(IMAGE_DEBUG_DIRECTORY))) {
- OUTPUT("[-] Invalid debug directory entry detected\n");
- break;
- }
- OUTPUT("\tCharacteristics: 0x%X\n", pDebugDirectory[i].Characteristics);
- OUTPUT("\tTimeDateStamp: 0x%X\n", pDebugDirectory[i].TimeDateStamp);
- OUTPUT("\tMajorVersion: %d\n", pDebugDirectory[i].MajorVersion);
- OUTPUT("\tMinorVersion: %d\n", pDebugDirectory[i].MinorVersion);
- OUTPUT("\tType: 0x%X", pDebugDirectory[i].Type);
- // Process debug type
- switch (pDebugDirectory[i].Type) {
- case IMAGE_DEBUG_TYPE_COFF:
- OUTPUT(" (COFF)\n"); break;
- case IMAGE_DEBUG_TYPE_CODEVIEW:
- OUTPUT(" (CodeView)\n"); break;
- case IMAGE_DEBUG_TYPE_FPO:
- OUTPUT(" (FPO)\n"); break;
- case IMAGE_DEBUG_TYPE_MISC:
- OUTPUT(" (Misc)\n"); break;
- case IMAGE_DEBUG_TYPE_EXCEPTION:
- OUTPUT(" (Exception)\n"); break;
- default:
- OUTPUT(" (Unknown)\n"); break;
- }
- OUTPUT("\tSizeOfData: 0x%X\n", pDebugDirectory[i].SizeOfData);
- OUTPUT("\tAddressOfRawData: 0x%X\n", pDebugDirectory[i].AddressOfRawData);
- OUTPUT("\tPointerToRawData: 0x%X\n\n", pDebugDirectory[i].PointerToRawData);
- // Process CodeView information if available
- if (pDebugDirectory[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW &&
- pDebugDirectory[i].PointerToRawData != 0 &&
- pDebugDirectory[i].SizeOfData >= 24) { // Minimum size for CodeView data
- auto pCVHeader = reinterpret_cast<DWORD*>(
- (BYTE*)lpFileContent + pDebugDirectory[i].PointerToRawData);
- if (!IsBadReadPtr(pCVHeader, sizeof(DWORD)) && *pCVHeader == 0x53445352) {
- auto pCVData = reinterpret_cast<char*>(pCVHeader + 1);
- if (!IsBadReadPtr(pCVData + 16, 1)) {
- std::vector<wchar_t> pdbPath(MAX_PATH);
- MultiByteToWideChar(CP_ACP, 0, pCVData + 16, -1,
- pdbPath.data(), MAX_PATH);
- OUTPUT("\tPDB Path: %s\n\n", pdbPath.data());
- }
- }
- }
- }
- }
- }
- // Continue with ShowProgress(100)...
- // In your AnalyzePEFile function, at the end:
- ShowProgress(100);
- SetStatusText(L"Analysis complete");
- ShowWindow(g_hProgressBar, SW_HIDE); // Optional: hide progress bar when done
- cleanup:
- if (lpFileContent) {
- UnmapViewOfFile(lpFileContent);
- }
- if (hFileMapping) {
- CloseHandle(hFileMapping);
- }
- if (hFile) {
- CloseHandle(hFile);
- }
- UpdateEditControl();
- }*/
- /*
- //use below vv ALWAYS
- void AnalyzePEFile(const wchar_t* filePathW) {
- OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
- LPVOID lpFileContent = GetFileContent(filePathW);
- if (!lpFileContent) {
- OUTPUT("[-] Failed to read file content!\n");
- return;
- }
- const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileContent);
- if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
- OUTPUT("[-] Invalid DOS signature!\n");
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- return;
- }
- const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>((DWORD_PTR)lpFileContent + pImageDosHeader->e_lfanew);
- if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
- OUTPUT("[-] Invalid NT signature!\n");
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- return;
- }
- //UpdateEditControl(); //added just now remove line!
- OUTPUT("[+] PE FILE HEADER\n");
- OUTPUT("\tMachine : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.Machine);
- OUTPUT("\tNumberOfSections : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSections);
- OUTPUT("\tTimeDateStamp : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.TimeDateStamp);
- OUTPUT("\tPointerToSymbolTable : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.PointerToSymbolTable);
- OUTPUT("\tNumberOfSymbols : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSymbols);
- OUTPUT("\tSizeOfOptionalHeader : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.SizeOfOptionalHeader);
- OUTPUT("\tCharacteristics : 0x%X %s\n\n", (uintptr_t)pImageNtHeaders->FileHeader.Characteristics, GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics));
- OUTPUT("[+] PE OPTIONAL HEADER\n");
- OUTPUT("\tMagic : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Magic);
- OUTPUT("\tAddressOfEntryPoint : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
- OUTPUT("\tImageBase : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.ImageBase);
- OUTPUT("\tSectionAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SectionAlignment);
- OUTPUT("\tFileAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.FileAlignment);
- OUTPUT("\tMajorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
- OUTPUT("\tMinorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
- OUTPUT("\tMajorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorImageVersion);
- OUTPUT("\tMinorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorImageVersion);
- OUTPUT("\tMajorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorSubsystemVersion);
- OUTPUT("\tMinorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorSubsystemVersion);
- OUTPUT("\tWin32VersionValue : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Win32VersionValue);
- OUTPUT("\tSizeOfImage : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfImage);
- OUTPUT("\tSizeOfHeaders : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeaders);
- OUTPUT("\tCheckSum : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.CheckSum);
- OUTPUT("\tSubsystem : 0x%X %s\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Subsystem, GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem));
- OUTPUT("\tDllCharacteristics : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.DllCharacteristics);
- OUTPUT("\tSizeOfStackReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackReserve);
- OUTPUT("\tSizeOfStackCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackCommit);
- OUTPUT("\tSizeOfHeapReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapReserve);
- OUTPUT("\tSizeOfHeapCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapCommit);
- OUTPUT("\tLoaderFlags : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.LoaderFlags);
- OUTPUT("\tNumberOfRvaAndSizes : 0x%X\n\n", (uintptr_t)pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes);
- //UpdateEditControl(); //added just now remove line!
- GetDataDirectories(&pImageNtHeaders->OptionalHeader.DataDirectory[0]);
- const auto pImageSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>((DWORD_PTR)pImageNtHeaders + sizeof(IMAGE_NT_HEADERS));
- const auto pImageImportSection = GetSections(pImageSectionHeader, pImageNtHeaders->FileHeader.NumberOfSections, pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress);
- if (!pImageImportSection) {
- OUTPUT("[-] Error: Could not find import section!\n");
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- return;
- }
- const auto pImageImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>((DWORD_PTR)lpFileContent + pImageImportSection->PointerToRawData);
- if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
- GetImports32(pImageImportDescriptor, (DWORD)lpFileContent + pImageImportSection->PointerToRawData, pImageImportSection);
- }
- else if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) {
- GetImports64(pImageImportDescriptor, (DWORD)lpFileContent + pImageImportSection->PointerToRawData, pImageImportSection);
- }
- else {
- OUTPUT("[-] Unsupported architecture!\n");
- }
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- UpdateEditControl();
- }
- void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory) {
- OUTPUT("[+] PE DATA DIRECTORIES\n");
- for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i, ++pImageDataDirectory) {
- if (pImageDataDirectory->VirtualAddress == 0) continue;
- OUTPUT("\tDataDirectory (%s) VirtualAddress : 0x%X\n", GetDataDirectoryName(i), (uintptr_t)pImageDataDirectory->VirtualAddress);
- OUTPUT("\tDataDirectory (%s) Size : 0x%X\n\n", GetDataDirectoryName(i), (uintptr_t)pImageDataDirectory->Size);
- }
- }
- PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader, int NumberOfSections, DWORD dImportAddress) {
- PIMAGE_SECTION_HEADER pImageImportHeader = nullptr;
- OUTPUT("\n[+] PE IMAGE SECTIONS\n");
- for (int i = 0; i < NumberOfSections; ++i) {
- const auto pCurrentSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>((DWORD_PTR)pImageSectionHeader + i * sizeof(IMAGE_SECTION_HEADER));
- OUTPUT("\n\tSECTION : %s\n", (wchar_t*)pCurrentSectionHeader->Name);
- OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\n", (uintptr_t)pCurrentSectionHeader->Misc.PhysicalAddress);
- OUTPUT("\t\tMisc (VirtualSize) : 0x%X\n", (uintptr_t)pCurrentSectionHeader->Misc.VirtualSize);
- OUTPUT("\t\tVirtualAddress : 0x%X\n", (uintptr_t)pCurrentSectionHeader->VirtualAddress);
- OUTPUT("\t\tSizeOfRawData : 0x%X\n", (uintptr_t)pCurrentSectionHeader->SizeOfRawData);
- OUTPUT("\t\tPointerToRawData : 0x%X\n", (uintptr_t)pCurrentSectionHeader->PointerToRawData);
- OUTPUT("\t\tCharacteristics : 0x%X %s\n", (uintptr_t)pCurrentSectionHeader->Characteristics, GetSectionProtection(pCurrentSectionHeader->Characteristics));
- if (dImportAddress >= pCurrentSectionHeader->VirtualAddress && dImportAddress < pCurrentSectionHeader->VirtualAddress + pCurrentSectionHeader->Misc.VirtualSize) {
- pImageImportHeader = pCurrentSectionHeader;
- }
- }
- return pImageImportHeader;
- }
- void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor, DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection) {
- OUTPUT("\n[+] IMPORTED DLL\n");
- while (pImageImportDescriptor->Name != 0) {
- OUTPUT("\n\tDLL NAME : %s\n", (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
- if (pImageImportDescriptor->OriginalFirstThunk == 0) {
- ++pImageImportDescriptor;
- continue;
- }
- auto pOriginalFirstThunk = reinterpret_cast<PIMAGE_THUNK_DATA32>(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
- while (pOriginalFirstThunk->u1.AddressOfData != 0) {
- const auto pImageImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(dRawOffset + (pOriginalFirstThunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
- if (pImageImportByName) {
- OUTPUT("\t\tFunction: %s\n", (char*)pImageImportByName->Name);
- }
- pOriginalFirstThunk++;
- }
- pImageImportDescriptor++;
- }
- }
- void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor, DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection) {
- OUTPUT("\n[+] IMPORTED DLL\n");
- while (pImageImportDescriptor->Name != 0) {
- OUTPUT("\n\tDLL NAME : %s\n", (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
- if (pImageImportDescriptor->OriginalFirstThunk == 0) {
- ++pImageImportDescriptor;
- continue;
- }
- auto pOriginalFirstThunk = reinterpret_cast<PIMAGE_THUNK_DATA64>(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
- while (pOriginalFirstThunk->u1.AddressOfData != 0) {
- const auto pImageImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(dRawOffset + (pOriginalFirstThunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
- if (pImageImportByName) {
- OUTPUT("\t\tFunction: %s\n", (char*)pImageImportByName->Name);
- }
- pOriginalFirstThunk++;
- }
- pImageImportDescriptor++;
- }
- }
- //use above ^^ ALWAYS
- */
- /*
- // older-orig-deprecated vv
- // Main PE Analysis function
- void AnalyzePEFile(const wchar_t* filePathW)
- {
- //WCHAR filePathW[MAX_PATH];
- //MultiByteToWideChar(CP_ACP, 0, filePathA, -1, filePathW, MAX_PATH);
- OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
- //AppendToOutput(L"[+] Starting PE Analysis for: %ls\n\n", filePathW);
- // Get file content
- LPVOID lpFileContent = GetFileContent(filePathW);
- if (!lpFileContent)
- {
- OUTPUT("[-] Failed to read file content!\n");
- return;
- }
- // Get DOS header
- const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileContent);
- if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
- {
- OUTPUT("[-] Invalid DOS signature!\n");
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- return;
- }
- // Get NT headers
- const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>((DWORD_PTR)lpFileContent + pImageDosHeader->e_lfanew);
- if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE)
- {
- OUTPUT("[-] Invalid NT signature!\n");
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- return;
- }
- // Display File Header information
- OUTPUT("[+] PE FILE HEADER\n");
- OUTPUT("\tMachine : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.Machine);
- OUTPUT("\tNumberOfSections : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSections);
- OUTPUT("\tTimeDateStamp : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.TimeDateStamp);
- OUTPUT("\tPointerToSymbolTable : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.PointerToSymbolTable);
- OUTPUT("\tNumberOfSymbols : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSymbols);
- OUTPUT("\tSizeOfOptionalHeader : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.SizeOfOptionalHeader);
- OUTPUT("\tCharacteristics : 0x%X %s\n\n",
- (uintptr_t)pImageNtHeaders->FileHeader.Characteristics,
- GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics));
- // Display Optional Header information
- OUTPUT("[+] PE OPTIONAL HEADER\n");
- OUTPUT("\tMagic : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Magic);
- OUTPUT("\tAddressOfEntryPoint : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
- OUTPUT("\tImageBase : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.ImageBase);
- OUTPUT("\tSectionAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SectionAlignment);
- OUTPUT("\tFileAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.FileAlignment);
- OUTPUT("\tMajorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
- OUTPUT("\tMinorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
- OUTPUT("\tMajorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorImageVersion);
- OUTPUT("\tMinorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorImageVersion);
- OUTPUT("\tMajorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorSubsystemVersion);
- OUTPUT("\tMinorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorSubsystemVersion);
- OUTPUT("\tWin32VersionValue : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Win32VersionValue);
- OUTPUT("\tSizeOfImage : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfImage);
- OUTPUT("\tSizeOfHeaders : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeaders);
- OUTPUT("\tCheckSum : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.CheckSum);
- OUTPUT("\tSubsystem : 0x%X %s\n",
- (uintptr_t)pImageNtHeaders->OptionalHeader.Subsystem,
- GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem));
- OUTPUT("\tDllCharacteristics : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.DllCharacteristics);
- OUTPUT("\tSizeOfStackReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackReserve);
- OUTPUT("\tSizeOfStackCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackCommit);
- OUTPUT("\tSizeOfHeapReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapReserve);
- OUTPUT("\tSizeOfHeapCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapCommit);
- OUTPUT("\tLoaderFlags : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.LoaderFlags);
- OUTPUT("\tNumberOfRvaAndSizes : 0x%X\n\n", (uintptr_t)pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes);
- // Get Data Directories
- GetDataDirectories(&pImageNtHeaders->OptionalHeader.DataDirectory[0]);
- // Get the import section
- const auto pImageSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(
- (DWORD_PTR)pImageNtHeaders + sizeof(IMAGE_NT_HEADERS));
- const auto pImageImportSection = GetSections(
- pImageSectionHeader,
- pImageNtHeaders->FileHeader.NumberOfSections,
- pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress);
- if (!pImageImportSection)
- {
- OUTPUT("[-] Error: Could not find import section!\n");
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- return;
- }
- // Get imports based on architecture
- const auto pImageImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
- (DWORD_PTR)lpFileContent + pImageImportSection->PointerToRawData);
- if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
- {
- GetImports32(
- pImageImportDescriptor,
- (DWORD)lpFileContent + pImageImportSection->PointerToRawData,
- pImageImportSection);
- }
- else if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
- {
- GetImports64(
- pImageImportDescriptor,
- (DWORD)lpFileContent + pImageImportSection->PointerToRawData,
- pImageImportSection);
- }
- else
- {
- OUTPUT("[-] Unsupported architecture!\n");
- }
- // Cleanup
- HeapFree(GetProcessHeap(), 0, lpFileContent);
- // Update the GUI with the analysis results
- UpdateEditControl();
- }
- void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory)
- {
- OUTPUT("[+] PE DATA DIRECTORIES\n");
- for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i, ++pImageDataDirectory)
- {
- if (pImageDataDirectory->VirtualAddress == 0)
- continue;
- OUTPUT("\tDataDirectory (%s) VirtualAddress : 0x%X\n",
- GetDataDirectoryName(i),
- (uintptr_t)pImageDataDirectory->VirtualAddress);
- OUTPUT("\tDataDirectory (%s) Size : 0x%X\n\n",
- GetDataDirectoryName(i),
- (uintptr_t)pImageDataDirectory->Size);
- }
- }
- PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader,
- int NumberOfSections, DWORD dImportAddress)
- {
- PIMAGE_SECTION_HEADER pImageImportHeader = nullptr;
- OUTPUT("\n[+] PE IMAGE SECTIONS\n");
- for (int i = 0; i < NumberOfSections; ++i)
- {
- const auto pCurrentSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageSectionHeader +
- i * sizeof(IMAGE_SECTION_HEADER));
- OUTPUT("\n\tSECTION : %s\n", (wchar_t*)pCurrentSectionHeader->Name);
- OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->Misc.PhysicalAddress);
- OUTPUT("\t\tMisc (VirtualSize) : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->Misc.VirtualSize);
- OUTPUT("\t\tVirtualAddress : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->VirtualAddress);
- OUTPUT("\t\tSizeOfRawData : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->SizeOfRawData);
- OUTPUT("\t\tPointerToRawData : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->PointerToRawData);
- OUTPUT("\t\tPointerToRelocations : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->PointerToRelocations);
- OUTPUT("\t\tPointerToLinenumbers : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->PointerToLinenumbers);
- OUTPUT("\t\tNumberOfRelocations : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->NumberOfRelocations);
- OUTPUT("\t\tNumberOfLinenumbers : 0x%X\n",
- (uintptr_t)pCurrentSectionHeader->NumberOfLinenumbers);
- OUTPUT("\t\tCharacteristics : 0x%X %s\n",
- (uintptr_t)pCurrentSectionHeader->Characteristics,
- GetSectionProtection(pCurrentSectionHeader->Characteristics));
- if (dImportAddress >= pCurrentSectionHeader->VirtualAddress &&
- dImportAddress < pCurrentSectionHeader->VirtualAddress +
- pCurrentSectionHeader->Misc.VirtualSize)
- {
- pImageImportHeader = pCurrentSectionHeader;
- }
- }
- return pImageImportHeader;
- }
- void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
- DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection)
- {
- OUTPUT("\n[+] IMPORTED DLL\n");
- while (pImageImportDescriptor->Name != 0)
- {
- OUTPUT("\n\tDLL NAME : %s\n",
- (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
- OUTPUT("\tCharacteristics : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->Characteristics - pImageImportSection->VirtualAddress)));
- OUTPUT("\tOriginalFirstThunk : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress)));
- OUTPUT("\tTimeDateStamp : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->TimeDateStamp - pImageImportSection->VirtualAddress)));
- OUTPUT("\tForwarderChain : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->ForwarderChain - pImageImportSection->VirtualAddress)));
- OUTPUT("\tFirstThunk : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->FirstThunk - pImageImportSection->VirtualAddress)));
- if (pImageImportDescriptor->OriginalFirstThunk == 0)
- {
- ++pImageImportDescriptor;
- continue;
- }
- auto pOriginalFirstThrunk = (PIMAGE_THUNK_DATA32)(dRawOffset +
- (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
- OUTPUT("\n\tImported Functions : \n\n");
- while (pOriginalFirstThrunk->u1.AddressOfData != 0)
- {
- if (pOriginalFirstThrunk->u1.AddressOfData >= IMAGE_ORDINAL_FLAG32)
- {
- ++pOriginalFirstThrunk;
- continue;
- }
- const auto pImageImportByName = (PIMAGE_IMPORT_BY_NAME)(dRawOffset +
- (pOriginalFirstThrunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
- if (pImageImportByName == nullptr)
- {
- ++pOriginalFirstThrunk;
- continue;
- }
- if (pOriginalFirstThrunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
- {
- OUTPUT("\t\t0x%X (Ordinal) : %s\n",
- (uintptr_t)pOriginalFirstThrunk->u1.AddressOfData,
- (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
- }
- else
- {
- OUTPUT("\t\t%s\n",
- (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
- }
- ++pOriginalFirstThrunk;
- }
- ++pImageImportDescriptor;
- }
- }
- void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
- DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection)
- {
- OUTPUT("\n[+] IMPORTED DLL\n");
- while (pImageImportDescriptor->Name != 0)
- {
- OUTPUT("\n\tDLL NAME : %s\n",
- (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
- OUTPUT("\tCharacteristics : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->Characteristics - pImageImportSection->VirtualAddress)));
- OUTPUT("\tOriginalFirstThunk : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress)));
- OUTPUT("\tTimeDateStamp : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->TimeDateStamp - pImageImportSection->VirtualAddress)));
- OUTPUT("\tForwarderChain : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->ForwarderChain - pImageImportSection->VirtualAddress)));
- OUTPUT("\tFirstThunk : 0x%X\n",
- (uintptr_t)(dRawOffset + (pImageImportDescriptor->FirstThunk - pImageImportSection->VirtualAddress)));
- if (pImageImportDescriptor->OriginalFirstThunk == 0)
- {
- ++pImageImportDescriptor;
- continue;
- }
- auto pOriginalFirstThrunk = (PIMAGE_THUNK_DATA64)(dRawOffset +
- (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
- OUTPUT("\n\tImported Functions : \n\n");
- while (pOriginalFirstThrunk->u1.AddressOfData != 0)
- {
- if (pOriginalFirstThrunk->u1.AddressOfData >= IMAGE_ORDINAL_FLAG64)
- {
- ++pOriginalFirstThrunk;
- continue;
- }
- const auto pImageImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)dRawOffset +
- (pOriginalFirstThrunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
- if (pImageImportByName == nullptr)
- {
- ++pOriginalFirstThrunk;
- continue;
- }
- if (pOriginalFirstThrunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
- {
- OUTPUT("\t\t0x%llX (Ordinal) : %s\n",
- pOriginalFirstThrunk->u1.AddressOfData,
- (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
- }
- else
- {
- OUTPUT("\t\t%s\n",
- (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
- }
- ++pOriginalFirstThrunk;
- }
- ++pImageImportDescriptor;
- }
- }
- // older-orig-deprecated ^^
- */
- //filePathW
- //lpFilePath
- HANDLE GetFileContent(const wchar_t* lpFilePath) {
- HANDLE hFile = CreateFileW(lpFilePath, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
- if (hFile == INVALID_HANDLE_VALUE) return nullptr;
- DWORD fileSize = GetFileSize(hFile, nullptr);
- auto lpFileContent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, fileSize);
- DWORD bytesRead;
- ReadFile(hFile, lpFileContent, fileSize, &bytesRead, nullptr);
- CloseHandle(hFile);
- return lpFileContent;
- }
- void UpdateEditControl() {
- SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
- SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
- SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
- }
Add Comment
Please, Sign In to add comment