alien_fx_fiend

PE-Explorer GUI (Non-Focus Scrolling) *FINAL RELEASE 4.2*

Nov 28th, 2024 (edited)
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 64.21 KB | Source Code | 0 0
  1. ==++ Here's the full source code for (file 1/1) "main.cpp":: ++==
  2. #define STRICT
  3. #define WIN32_LEAN_AND_MEAN
  4. #include <Windows.h>
  5. #include <winternl.h>
  6. #include <CommCtrl.h>
  7. #include <commdlg.h>
  8. #include <string>
  9. #include <strsafe.h>
  10. #include <sstream>
  11. #include <iomanip>
  12. #include <stdio.h>
  13. #include <vector>
  14. #include <shellapi.h>
  15. //#include "helpers.h"
  16. #include "resource.h"
  17. #pragma comment(lib, "comctl32.lib")
  18.  
  19. namespace PEHelpers {
  20.    std::wstring GetImageCharacteristics(DWORD characteristics) {
  21.        if (characteristics & IMAGE_FILE_DLL) return L"(DLL)";
  22.        if (characteristics & IMAGE_FILE_SYSTEM) return L"(DRIVER)";
  23.        if (characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) return L"(EXE)";
  24.        return L"(UNKNOWN)";
  25.    }
  26.  
  27.    std::wstring GetSubsystem(WORD subsystem) {
  28.        switch (subsystem) {
  29.        case IMAGE_SUBSYSTEM_NATIVE: return L"(NATIVE/DRIVER)";
  30.        case IMAGE_SUBSYSTEM_WINDOWS_GUI: return L"(GUI)";
  31.        case IMAGE_SUBSYSTEM_WINDOWS_CUI: return L"(CONSOLE)";
  32.        default: return L"(UNKNOWN)";
  33.        }
  34.    }
  35.  
  36.    std::wstring GetDataDirectoryName(int DirectoryNumber) {
  37.        switch (DirectoryNumber) {
  38.        case 0: return L"Export Table";
  39.        case 1: return L"Import Table";
  40.        case 2: return L"Resource Table";
  41.        case 3: return L"Exception Entry";
  42.        case 4: return L"Security Entry";
  43.        case 5: return L"Relocation Table";
  44.        case 6: return L"Debug Entry";
  45.        case 7: return L"Copyright Entry";
  46.        case 8: return L"Global PTR Entry";
  47.        case 9: return L"TLS Entry";
  48.        case 10: return L"Configuration Entry";
  49.        case 11: return L"Bound Import Entry";
  50.        case 12: return L"IAT";
  51.        case 13: return L"Delay Import Descriptor";
  52.        case 14: return L"COM Descriptor";
  53.        default: return L"Unknown";
  54.        }
  55.    }
  56.  
  57.    std::wstring GetSectionProtection(DWORD characteristics) {
  58.        std::wstring protection = L"(";
  59.        bool needsSeparator = false;
  60.  
  61.        if (characteristics & IMAGE_SCN_MEM_EXECUTE) {
  62.            protection += L"EXECUTE";
  63.            needsSeparator = true;
  64.        }
  65.  
  66.        if (characteristics & IMAGE_SCN_MEM_READ) {
  67.            if (needsSeparator) protection += L" | ";
  68.            protection += L"READ";
  69.            needsSeparator = true;
  70.        }
  71.  
  72.        if (characteristics & IMAGE_SCN_MEM_WRITE) {
  73.            if (needsSeparator) protection += L" | ";
  74.            protection += L"WRITE";
  75.        }
  76.  
  77.        protection += L")";
  78.        return protection;
  79.    }
  80.  
  81.    PIMAGE_SECTION_HEADER GetExportSection(const PIMAGE_SECTION_HEADER pImageSectionHeader,
  82.        const int NumberOfSections,
  83.        const DWORD_PTR dExportAddress) {
  84.        for (int i = 0; i < NumberOfSections; ++i) {
  85.            const auto pCurrentSectionHeader =
  86.                (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageSectionHeader + i * sizeof(IMAGE_SECTION_HEADER));
  87.  
  88.            if (dExportAddress >= pCurrentSectionHeader->VirtualAddress &&
  89.                dExportAddress < pCurrentSectionHeader->VirtualAddress + pCurrentSectionHeader->Misc.VirtualSize)
  90.                return pCurrentSectionHeader;
  91.        }
  92.        return nullptr;
  93.    }
  94. }
  95.  
  96. using namespace std;
  97.  
  98. // At the top of your file, change the window class name to wide string
  99. #define WINDOW_CLASS_NAME L"PEAnalyzerWindow"
  100. //const wchar_t* const WINDOW_CLASS_NAME = L"PEAnalyzerWindow";
  101.  
  102. // Use ANSI versions explicitly
  103. //#undef CreateWindow
  104. //#undef CreateWindowEx
  105. //#define CreateWindow  CreateWindowW
  106. //#define CreateWindowEx CreateWindowExW
  107.  
  108. // Helper function to replace printf with GUI output
  109. #define OUTPUT(format, ...) AppendToOutput(L##format, ##__VA_ARGS__)
  110. //#define OUTPUT(format, ...) AppendToOutput(format, ##__VA_ARGS__)
  111. //#define printf(format, ...) AppendToOutput(format, ##__VA_ARGS__)
  112.  
  113. // Window dimensions
  114. #define WINDOW_WIDTH    1024
  115. #define WINDOW_HEIGHT   768
  116. #define EDIT_MARGIN    10
  117.  
  118. // Global variables
  119. HWND g_hMainWindow = NULL;
  120. HWND g_hEditControl = NULL;
  121. HFONT g_hFont = NULL;
  122. std::wstringstream g_OutputText;
  123. WCHAR filePathW[MAX_PATH];
  124. std::vector<wchar_t> g_OutputBuffer;
  125. std::wstring tempBuffer; // Declare tempBuffer globally
  126. HWND g_hStatusBar = NULL;
  127. HWND g_hProgressBar = NULL;  // Add this with your other global variables
  128. //int virtualHeight = 100;  // Initialize with an appropriate value
  129.  
  130. // Function declarations
  131. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  132. LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
  133. void CreateMainWindow(HINSTANCE hInstance);
  134. void InitializeControls(HWND hwnd);
  135. void AddMenus(HWND hwnd);
  136. void OpenFileDialog(HWND hwnd);
  137. //void AnalyzePEFile(const WCHAR* filePathW);
  138. void AnalyzePEFile(const wchar_t* filePathW);
  139. HANDLE GetFileContent(const wchar_t* lpFilePath);
  140. /*void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory);
  141. PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader,
  142.    int NumberOfSections, DWORD dImportAddress);
  143. void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
  144.    DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection);
  145. void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
  146.    DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection);*/
  147. void AppendToOutput(const wchar_t* format, ...);
  148. void UpdateEditControl();
  149.  
  150. // Main window class name
  151. //const char* const WINDOW_CLASS_NAME = "PEAnalyzerWindow";
  152.  
  153. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  154.    INITCOMMONCONTROLSEX icc = { sizeof(INITCOMMONCONTROLSEX), ICC_WIN95_CLASSES };
  155.    InitCommonControlsEx(&icc);
  156.  
  157.    // Get command line parameters in Unicode
  158.    int argc;
  159.    LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
  160.  
  161.    CreateMainWindow(hInstance);
  162.    if (!g_hMainWindow) {
  163.        LocalFree(argv);
  164.        return -1;
  165.    }
  166.  
  167.    ShowWindow(g_hMainWindow, nCmdShow);
  168.    UpdateWindow(g_hMainWindow);
  169.  
  170.    // If there's a command line parameter, process it
  171.     if (argc > 1) {
  172.         // Process the first parameter as file path
  173.         SetWindowTextW(g_hEditControl, L"");
  174.         g_OutputText.str(L"");
  175.         g_OutputText.clear();
  176.         AnalyzePEFile(argv[1]);
  177.         UpdateEditControl();
  178.     }
  179.  
  180.     LocalFree(argv);
  181.  
  182.     MSG msg = {};
  183.     while (GetMessage(&msg, NULL, 0, 0)) {
  184.         TranslateMessage(&msg);
  185.         DispatchMessage(&msg);
  186.     }
  187.  
  188.     if (g_hFont) DeleteObject(g_hFont);
  189.     return (int)msg.wParam;
  190. }
  191.  
  192. void CreateMainWindow(HINSTANCE hInstance) {
  193.     WNDCLASSEXW wc = { sizeof(WNDCLASSEXW), 0, WindowProc, 0, 0, hInstance,
  194.         LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)),
  195.         LoadCursor(NULL, IDC_ARROW),
  196.         (HBRUSH)(COLOR_WINDOW + 1),
  197.         NULL, WINDOW_CLASS_NAME,
  198.         LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)) };
  199.     RegisterClassExW(&wc);
  200.  
  201.     // Get screen dimensions
  202.     int screenWidth = GetSystemMetrics(SM_CXSCREEN);
  203.     int screenHeight = GetSystemMetrics(SM_CYSCREEN);
  204.  
  205.     // Calculate center position
  206.     int windowX = (screenWidth - WINDOW_WIDTH) / 2;
  207.     int windowY = (screenHeight - WINDOW_HEIGHT) / 2;
  208.  
  209.     // Remove WS_MAXIMIZEBOX and WS_THICKFRAME from the window style
  210.     DWORD style = (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX) & ~WS_THICKFRAME;
  211.     //WS_OVERLAPPEDWINDOW ~~> style
  212.     g_hMainWindow = CreateWindowExW(0, WINDOW_CLASS_NAME, L"PE File Analyzer",
  213.         style, windowX, windowY, WINDOW_WIDTH, WINDOW_HEIGHT,
  214.         nullptr, nullptr, hInstance, nullptr);
  215. }
  216.  
  217. void InitializeControls(HWND hwnd) {
  218.     // Create status bar
  219.     g_hStatusBar = CreateWindowEx(0, STATUSCLASSNAME, NULL,
  220.         WS_CHILD | WS_VISIBLE,
  221.         0, 0, 0, 0, hwnd, NULL,
  222.         (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
  223.  
  224.     // Set up status bar parts
  225.     RECT rcClient;
  226.     GetClientRect(hwnd, &rcClient);
  227.     int statusParts[2] = { 150, rcClient.right };
  228.     SendMessage(g_hStatusBar, SB_SETPARTS, 2, (LPARAM)statusParts);
  229.  
  230.     // Create progress bar in the second part of status bar
  231.     RECT rcPart;
  232.     SendMessage(g_hStatusBar, SB_GETRECT, 1, (LPARAM)&rcPart);
  233.  
  234.     g_hProgressBar = CreateWindowEx(0, PROGRESS_CLASS, NULL,
  235.         WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
  236.         rcPart.left + 5, rcPart.top + 2,
  237.         rcPart.right - rcPart.left - 10, rcPart.bottom - rcPart.top - 4,
  238.         g_hStatusBar, NULL,
  239.         (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
  240.  
  241.     // Set blue color and range
  242.     SendMessage(g_hProgressBar, PBM_SETBARCOLOR, 0, (LPARAM)RGB(0, 120, 215));  // Windows 10 blue
  243.     SendMessage(g_hProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
  244.     SendMessage(g_hProgressBar, PBM_SETSTEP, 1, 0);
  245.  
  246.     // Get status bar height for edit control positioning
  247.     RECT rcStatus;
  248.     GetWindowRect(g_hStatusBar, &rcStatus);
  249.     int statusHeight = rcStatus.bottom - rcStatus.top;
  250.  
  251.     // Create edit control
  252.     g_hEditControl = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"",
  253.         WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL |
  254.         ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
  255.         EDIT_MARGIN, EDIT_MARGIN,
  256.         rcClient.right - (2 * EDIT_MARGIN),
  257.         rcClient.bottom - statusHeight - (2 * EDIT_MARGIN),
  258.         hwnd, nullptr,
  259.         (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), nullptr);
  260.  
  261.     // Create and set font
  262.     g_hFont = CreateFont(-14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
  263.         ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  264.         DEFAULT_QUALITY, DEFAULT_PITCH | FF_MODERN, L"Consolas");
  265.  
  266.     if (g_hFont)
  267.         SendMessage(g_hEditControl, WM_SETFONT, (WPARAM)g_hFont, TRUE);
  268.  
  269.     SetWindowSubclass(g_hEditControl, EditSubclassProc, 0, 0);
  270. }
  271.  
  272. void AddMenus(HWND hwnd) {
  273.     HMENU hMenuBar = CreateMenu();
  274.     HMENU hFileMenu = CreateMenu();
  275.     AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hFileMenu, L"&File");
  276.     AppendMenu(hFileMenu, MF_STRING, 1, L"&Open\tCtrl+O");  // Updated to show shortcut
  277.     AppendMenu(hFileMenu, MF_STRING, 2, L"E&xit");
  278.     SetMenu(hwnd, hMenuBar);
  279. }
  280.  
  281. /*LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
  282.     if (uMsg == WM_KEYDOWN) {
  283.         // Check for Ctrl+O
  284.         if ((GetKeyState(VK_CONTROL) & 0x8000) && wParam == 'O') {
  285.             SendMessage(GetParent(hwnd), WM_COMMAND, 1, 0);  // Send the Open command
  286.             return 0;
  287.         }
  288.  
  289.         // Existing cases
  290.         switch (wParam) {
  291.         case VK_F1:
  292.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_F1, 0);
  293.             return 0;
  294.         case VK_ESCAPE:
  295.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_ESCAPE, 0);
  296.             return 0;
  297.         case VK_PRIOR:  // Page Up
  298.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_PRIOR, 0);
  299.             return 0;
  300.         case VK_NEXT:  // Page Down
  301.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_NEXT, 0);
  302.             return 0;
  303.         }
  304.     }
  305.     else if (uMsg == WM_MOUSEWHEEL) {
  306.         int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
  307.         if (zDelta > 0) {
  308.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_PRIOR, 0);  // Mouse Wheel Up
  309.         }
  310.         else if (zDelta < 0) {
  311.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_NEXT, 0);  // Mouse Wheel Down
  312.         }
  313.         return 0;
  314.     }
  315.     return DefSubclassProc(hwnd, uMsg, wParam, lParam);
  316. }*/
  317.  
  318.  
  319. LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
  320.     if (uMsg == WM_KEYDOWN) {
  321.         if ((GetKeyState(VK_CONTROL) & 0x8000) && wParam == 'O') {
  322.             SendMessage(GetParent(hwnd), WM_COMMAND, 1, 0);
  323.             return 0;
  324.         }
  325.         switch (wParam) {
  326.         case VK_F1:
  327.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_F1, 0);
  328.             return 0;
  329.         case VK_ESCAPE:
  330.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_ESCAPE, 0);
  331.             return 0;
  332.         case VK_PRIOR:
  333.             // Scroll up
  334.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
  335.             return 0;
  336.         case VK_NEXT:
  337.             // Scroll down
  338.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
  339.             return 0;
  340.         case VK_UP:
  341.             // Scroll one line up
  342.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0);
  343.             return 0;
  344.         case VK_DOWN:
  345.             // Scroll one line down
  346.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0);
  347.             return 0;
  348.         }
  349.     }
  350.     if (uMsg == WM_MOUSEWHEEL) {
  351.         int delta = GET_WHEEL_DELTA_WPARAM(wParam);
  352.         if (delta > 0) {
  353.             // Scroll up
  354.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
  355.         }
  356.         else {
  357.             // Scroll down
  358.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
  359.         }
  360.         return 0;
  361.     }
  362.     return DefSubclassProc(hwnd, uMsg, wParam, lParam);
  363. }
  364.  
  365. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  366.     switch (uMsg) {
  367.     case WM_CREATE: InitializeControls(hwnd); AddMenus(hwnd); return 0;
  368.     case WM_SIZE:
  369.     {
  370.         RECT rcClient;
  371.         GetClientRect(hwnd, &rcClient);
  372.  
  373.         // Resize status bar
  374.         SendMessage(g_hStatusBar, WM_SIZE, 0, 0);
  375.  
  376.         // Recalculate status bar parts
  377.         int statusParts[2] = { 150, rcClient.right };
  378.         SendMessage(g_hStatusBar, SB_SETPARTS, 2, (LPARAM)statusParts);
  379.  
  380.         // Reposition progress bar
  381.         RECT rcPart;
  382.         SendMessage(g_hStatusBar, SB_GETRECT, 1, (LPARAM)&rcPart);
  383.         SetWindowPos(g_hProgressBar, NULL,
  384.             rcPart.left + 5, rcPart.top + 2,
  385.             rcPart.right - rcPart.left - 10, rcPart.bottom - rcPart.top - 4,
  386.             SWP_NOZORDER);
  387.  
  388.         // Get status bar height
  389.         RECT rcStatus;
  390.         GetWindowRect(g_hStatusBar, &rcStatus);
  391.         int statusHeight = rcStatus.bottom - rcStatus.top;
  392.  
  393.         // Resize edit control
  394.         SetWindowPos(g_hEditControl, NULL,
  395.             EDIT_MARGIN,
  396.             EDIT_MARGIN,
  397.             rcClient.right - (2 * EDIT_MARGIN),
  398.             rcClient.bottom - statusHeight - (2 * EDIT_MARGIN),
  399.             SWP_NOZORDER);
  400.         return 0;
  401.     }
  402.     /*case WM_KEYDOWN:
  403.     {
  404.         // Check if Ctrl is pressed
  405.         if (GetKeyState(VK_CONTROL) & 0x8000) {
  406.             switch (wParam) {
  407.             case 'O':  // Ctrl+O
  408.                 OpenFileDialog(hwnd);
  409.                 return 0;
  410.             }
  411.         }
  412.  
  413.         // Handle Page Up/Page Down
  414.         switch (wParam) {
  415.         case VK_PRIOR:  // Page Up
  416.             ScrollWindow(hwnd, 0, -virtualHeight, NULL, NULL);
  417.             UpdateWindow(hwnd);
  418.             return 0;
  419.         case VK_NEXT:  // Page Down
  420.             ScrollWindow(hwnd, 0, virtualHeight, NULL, NULL);
  421.             UpdateWindow(hwnd);
  422.             return 0;
  423.         case VK_F1:
  424.             MessageBoxW(hwnd,
  425.                 L"PE Header Parser 2.9 GUI-based Programmed in C++ Win32 API (1369 lines of code) by Entisoft Software(c) Evans Thorpemorton",
  426.                 L"About",
  427.                 MB_OK | MB_ICONINFORMATION);
  428.             return 0;
  429.         case VK_ESCAPE:
  430.             PostQuitMessage(0);
  431.             return 0;
  432.         }
  433.     }
  434.     break;
  435.  
  436.     case WM_MOUSEWHEEL:
  437.     {
  438.         int zDelta = GET_WHEEL_DELTA_WPARAM(wParam);
  439.         if (zDelta > 0) {
  440.             ScrollWindow(hwnd, 0, -virtualHeight, NULL, NULL);  // Mouse Wheel Up
  441.         }
  442.         else if (zDelta < 0) {
  443.             ScrollWindow(hwnd, 0, virtualHeight, NULL, NULL);  // Mouse Wheel Down
  444.         }
  445.         UpdateWindow(hwnd);
  446.         return 0;
  447.     }*/
  448.  
  449.     case WM_KEYDOWN:
  450.     {
  451.         if (GetKeyState(VK_CONTROL) & 0x8000) {
  452.             switch (wParam) {
  453.             case 'O':
  454.                 OpenFileDialog(hwnd);
  455.                 return 0;
  456.             }
  457.         }
  458.         switch (wParam) {
  459.         case VK_F1:
  460.             MessageBoxW(hwnd,
  461.                 L"PE Header Parser 4.3 GUI-based Programmed in C++ Win32 API (1546 lines of code) by Entisoft Software(c) Evans Thorpemorton",
  462.                 L"About",
  463.                 MB_OK | MB_ICONINFORMATION);
  464.             return 0;
  465.         case VK_ESCAPE:
  466.             PostQuitMessage(0);
  467.             return 0;
  468.         case VK_PRIOR:
  469.             // Scroll up
  470.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
  471.             return 0;
  472.         case VK_NEXT:
  473.             // Scroll down
  474.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
  475.             return 0;
  476.         case VK_UP:
  477.             // Scroll one line up
  478.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0);
  479.             return 0;
  480.         case VK_DOWN:
  481.             // Scroll one line down
  482.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0);
  483.             return 0;
  484.         }
  485.         break;
  486.     }
  487.     case WM_MOUSEWHEEL:
  488.     {
  489.         int delta = GET_WHEEL_DELTA_WPARAM(wParam);
  490.         if (delta > 0) {
  491.             // Scroll up
  492.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
  493.         }
  494.         else {
  495.             // Scroll down
  496.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
  497.         }
  498.         return 0;
  499.     }
  500.     case WM_COMMAND: if (LOWORD(wParam) == 1) OpenFileDialog(hwnd); if (LOWORD(wParam) == 2) PostQuitMessage(0); return 0;
  501.     case WM_DESTROY:
  502.         if (g_hStatusBar) DestroyWindow(g_hStatusBar);
  503.         PostQuitMessage(0);
  504.         return 0;
  505.     }
  506.     return DefWindowProc(hwnd, uMsg, wParam, lParam);
  507. }
  508.  
  509. void SetStatusText(const wchar_t* text) {
  510.     SendMessage(g_hStatusBar, SB_SETTEXT, 0, (LPARAM)text);
  511. }
  512.  
  513. void ShowProgress(int percentage) {
  514.     // Update progress bar
  515.     SendMessage(g_hProgressBar, PBM_SETPOS, (WPARAM)percentage, 0);
  516.  
  517.     // Update status text in first part
  518.     wchar_t status[256];
  519.     swprintf_s(status, L"Analyzing... %d%%", percentage);
  520.     //swprintf_s(status, L"Analyzing...");
  521.     SetStatusText(status); //commented-out
  522.     SendMessage(g_hStatusBar, SB_SETTEXT, 0, (LPARAM)status);
  523. }
  524.  
  525. void OpenFileDialog(HWND hwnd) {
  526.     WCHAR fileName[MAX_PATH] = L"";
  527.     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 };
  528.     if (GetOpenFileNameW(&ofn)) {
  529.         SetWindowTextW(g_hEditControl, L"");
  530.         g_OutputText.str(L"");
  531.         g_OutputText.clear();
  532.         AnalyzePEFile(ofn.lpstrFile);
  533.         UpdateEditControl();
  534.     }
  535. }
  536.  
  537. class FileMapper {
  538. private:
  539.     HANDLE hFile = INVALID_HANDLE_VALUE;
  540.     HANDLE hMapping = nullptr;
  541.     LPVOID lpView = nullptr;
  542.  
  543. public:
  544.     ~FileMapper() {
  545.         if (lpView) UnmapViewOfFile(lpView);
  546.         if (hMapping) CloseHandle(hMapping);
  547.         if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
  548.     }
  549.  
  550.     bool Initialize(const wchar_t* path) {
  551.         hFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, nullptr,
  552.             OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  553.         if (hFile == INVALID_HANDLE_VALUE) return false;
  554.  
  555.         hMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr);
  556.         if (!hMapping) return false;
  557.  
  558.         lpView = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
  559.         return lpView != nullptr;
  560.     }
  561.  
  562.     LPVOID GetView() const { return lpView; }
  563. };
  564.  
  565. // Modified AppendToOutput to handle newlines properly:
  566. void AppendToOutput(const wchar_t* format, ...) {
  567.     std::vector<wchar_t> buffer(1024);
  568.     va_list args;
  569.     va_start(args, format);
  570.  
  571.     while (true) {
  572.         int result = _vsnwprintf(buffer.data(), buffer.size(), format, args);
  573.         if (result >= 0) break;
  574.         buffer.resize(buffer.size() * 2);
  575.     }
  576.     va_end(args);
  577.  
  578.     // Convert \n to \r\n
  579.     std::wstring output = buffer.data();
  580.     size_t pos = 0;
  581.     while ((pos = output.find(L'\n', pos)) != std::wstring::npos) {
  582.         if (pos == 0 || output[pos - 1] != L'\r') {
  583.             output.insert(pos, L"\r");
  584.             pos += 2;
  585.         }
  586.         else {
  587.             pos++;
  588.         }
  589.     }
  590.  
  591.     g_OutputText << output;
  592.     UpdateEditControl();
  593. }
  594.  
  595. /*
  596. void AppendToOutput(const wchar_t* format, ...) {
  597.     wchar_t buffer[16384]; // Ensure sufficient buffer size
  598.     va_list args;
  599.     va_start(args, format);
  600.     StringCchVPrintfW(buffer, ARRAYSIZE(buffer), format, args);
  601.     va_end(args);
  602.  
  603.     tempBuffer += buffer;
  604.  
  605.     // Update Edit Control periodically to improve performance
  606.     if (tempBuffer.size() > 8000) {
  607.         g_OutputText << tempBuffer;
  608.         tempBuffer.clear();
  609.  
  610.         SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  611.         SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  612.         SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  613.     }
  614. }
  615.  
  616.  
  617. // Final update to flush any remaining content
  618. void FlushOutput() {
  619.     if (!tempBuffer.empty()) {
  620.         g_OutputText << tempBuffer;
  621.         tempBuffer.clear();
  622.  
  623.         SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  624.         SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  625.         SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  626.     }
  627. }
  628. */
  629.  
  630.  
  631. /*
  632. //use below ^^ ALWAYS
  633. void AppendToOutput(const wchar_t* format, ...) {
  634.     va_list args;
  635.     va_start(args, format);
  636.  
  637.     // Use a vector as a dynamically resizable buffer
  638.     std::vector<wchar_t> buffer(16384); // Start with an initial size
  639.     int result = -1;
  640.  
  641.     while (true) {
  642.         // Attempt to format the string
  643.         result = _vsnwprintf(buffer.data(), buffer.size(), format, args);
  644.  
  645.         if (result >= 0 && static_cast<size_t>(result) < buffer.size()) {
  646.             // Successfully formatted within the current buffer size
  647.             break;
  648.         }
  649.  
  650.         // Resize the buffer and try again
  651.         buffer.resize(buffer.size() * 2);
  652.     }
  653.     va_end(args);
  654.  
  655.     // Convert `\n` to `\r\n` for proper display in the EditBox
  656.     std::wstring formattedOutput(buffer.data());
  657.     size_t pos = 0;
  658.     while ((pos = formattedOutput.find(L'\n', pos)) != std::wstring::npos) {
  659.         formattedOutput.replace(pos, 1, L"\r\n");
  660.         pos += 2; // Move past the replacement
  661.     }
  662.  
  663.     // Append to the global output buffer
  664.     g_OutputText << formattedOutput;
  665.  
  666.     // Update the EditBox periodically to prevent overloading
  667.     if (g_OutputText.str().size() > 8000) {
  668.         SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  669.         SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  670.         SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  671.     }
  672. }
  673. //use above ^^ ALWAYS
  674. */
  675.  
  676. //currentlatest
  677. /*void AppendToOutput(const wchar_t* format, ...) {
  678.     wchar_t buffer[4096];
  679.     va_list args;
  680.     va_start(args, format);
  681.     StringCchVPrintfW(buffer, ARRAYSIZE(buffer), format, args);
  682.     va_end(args);
  683.     g_OutputText << buffer;
  684.     SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  685.     SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  686.     SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  687. }
  688. */
  689.  
  690. //use-below-basic-failsafe-working vv
  691. //basic test function
  692. /*void AnalyzePEFile(const wchar_t* filePathW) {
  693.     OUTPUT("[+] Analyzing file: %s\n", filePathW);
  694.     LPVOID lpFileContent = GetFileContent(filePathW);
  695.     if (!lpFileContent) { OUTPUT("[-] Could not read file.\n"); return; }
  696.     PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileContent;
  697.     if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) { OUTPUT("[-] Invalid DOS signature.\n"); HeapFree(GetProcessHeap(), 0, lpFileContent); return; }
  698.     PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)lpFileContent + dosHeader->e_lfanew);
  699.     if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) { OUTPUT("[-] Invalid NT signature.\n"); HeapFree(GetProcessHeap(), 0, lpFileContent); return; }
  700.     OUTPUT("[+] PE file analyzed successfully.\n");
  701.     HeapFree(GetProcessHeap(), 0, lpFileContent);
  702.     UpdateEditControl();
  703. }*/
  704. //use-above-basic-failsafe-working vv
  705.  
  706. //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
  707.  
  708. void AnalyzePEFile(const wchar_t* filePathW) {
  709.     OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
  710.  
  711.     FileMapper mapper;
  712.     if (!mapper.Initialize(filePathW)) {
  713.         SetStatusText(L"Failed to open file!");
  714.         OUTPUT("[-] Failed to open file! Error: %d\r\n", GetLastError());
  715.         return;
  716.     }
  717.  
  718.     ShowProgress(20);  // After initial file opening
  719.  
  720.  
  721.     // Open and read file
  722.     HANDLE hFile = CreateFileW(filePathW, GENERIC_READ, FILE_SHARE_READ, nullptr,
  723.         OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  724.     if (hFile == INVALID_HANDLE_VALUE) {
  725.         OUTPUT("[-] Failed to open file! Error: %d\n", GetLastError());
  726.         return;
  727.     }
  728.  
  729.     DWORD fileSize = GetFileSize(hFile, nullptr);
  730.     if (fileSize == INVALID_FILE_SIZE) {
  731.         CloseHandle(hFile);
  732.         OUTPUT("[-] Failed to get file size! Error: %d\n", GetLastError());
  733.         return;
  734.     }
  735.  
  736.     HANDLE hFileMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr);
  737.     if (!hFileMapping) {
  738.         CloseHandle(hFile);
  739.         OUTPUT("[-] Failed to create file mapping! Error: %d\n", GetLastError());
  740.         return;
  741.     }
  742.  
  743.     LPVOID lpFileContent = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
  744.     if (!lpFileContent) {
  745.         CloseHandle(hFileMapping);
  746.         CloseHandle(hFile);
  747.         OUTPUT("[-] Failed to map view of file! Error: %d\n", GetLastError());
  748.         return;
  749.     }
  750.  
  751.     const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(mapper.GetView());
  752.     if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
  753.         OUTPUT("[-] Invalid DOS signature!\r\n");
  754.         return;
  755.     }
  756.  
  757.     ShowProgress(40);
  758.  
  759.     const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
  760.         static_cast<BYTE*>(mapper.GetView()) + pImageDosHeader->e_lfanew);
  761.     if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
  762.         OUTPUT("[-] Invalid NT signature!\r\n");
  763.         return;
  764.     }
  765.  
  766.     ShowProgress(60);
  767.  
  768.     // Print File Header Information
  769.     OUTPUT("[+] PE FILE HEADER\n");
  770.     OUTPUT("\tMachine: 0x%X\n", pImageNtHeaders->FileHeader.Machine);
  771.     OUTPUT("\tNumberOfSections: 0x%X\n", pImageNtHeaders->FileHeader.NumberOfSections);
  772.     OUTPUT("\tTimeDateStamp: 0x%X\n", pImageNtHeaders->FileHeader.TimeDateStamp);
  773.     OUTPUT("\tPointerToSymbolTable: 0x%X\r\n",
  774.         static_cast<DWORD>(pImageNtHeaders->FileHeader.PointerToSymbolTable));
  775.     OUTPUT("\tNumberOfSymbols: 0x%X\r\n",
  776.         static_cast<DWORD>(pImageNtHeaders->FileHeader.NumberOfSymbols));
  777.     OUTPUT("\tSizeOfOptionalHeader: 0x%X\r\n",
  778.         static_cast<DWORD>(pImageNtHeaders->FileHeader.SizeOfOptionalHeader));
  779.     OUTPUT("\tCharacteristics: 0x%X %s\n\n",
  780.         pImageNtHeaders->FileHeader.Characteristics,
  781.         PEHelpers::GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics).c_str());
  782.  
  783.     // Print Optional Header Information
  784.     OUTPUT("[+] PE OPTIONAL HEADER\n");
  785.     OUTPUT("\tMagic: 0x%X\n", pImageNtHeaders->OptionalHeader.Magic);
  786.     OUTPUT("\tAddressOfEntryPoint: 0x%X\n", pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
  787.     OUTPUT("\tImageBase: 0x%llX\n", (ULONGLONG)pImageNtHeaders->OptionalHeader.ImageBase);
  788.     OUTPUT("\tSectionAlignment: 0x%X\n", pImageNtHeaders->OptionalHeader.SectionAlignment);
  789.     OUTPUT("\tFileAlignment: 0x%X\n", pImageNtHeaders->OptionalHeader.FileAlignment);
  790.  
  791.     // Added missing Optional Header fields
  792.     OUTPUT("\tMajorOperatingSystemVersion: 0x%X\r\n",
  793.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion));
  794.     OUTPUT("\tMinorOperatingSystemVersion: 0x%X\r\n",
  795.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion));
  796.     OUTPUT("\tMajorImageVersion: 0x%X\r\n",
  797.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorImageVersion));
  798.     OUTPUT("\tMinorImageVersion: 0x%X\r\n",
  799.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorImageVersion));
  800.     OUTPUT("\tMajorSubsystemVersion: 0x%X\r\n",
  801.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorSubsystemVersion));
  802.     OUTPUT("\tMinorSubsystemVersion: 0x%X\r\n",
  803.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorSubsystemVersion));
  804.     OUTPUT("\tWin32VersionValue: 0x%X\r\n",
  805.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.Win32VersionValue));
  806.     OUTPUT("\tSizeOfImage: 0x%X\r\n",
  807.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.SizeOfImage));
  808.     OUTPUT("\tSizeOfHeaders: 0x%X\r\n",
  809.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.SizeOfHeaders));
  810.     OUTPUT("\tCheckSum: 0x%X\r\n",
  811.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.CheckSum));
  812.     OUTPUT("\tSubsystem: 0x%X %s\r\n",
  813.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.Subsystem),
  814.         PEHelpers::GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem).c_str());
  815.     OUTPUT("\tDllCharacteristics: 0x%X\r\n",
  816.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.DllCharacteristics));
  817.     OUTPUT("\tSizeOfStackReserve: 0x%llX\r\n",
  818.         static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfStackReserve));
  819.     OUTPUT("\tSizeOfStackCommit: 0x%llX\r\n",
  820.         static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfStackCommit));
  821.     OUTPUT("\tSizeOfHeapReserve: 0x%llX\r\n",
  822.         static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfHeapReserve));
  823.     OUTPUT("\tSizeOfHeapCommit: 0x%llX\r\n",
  824.         static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfHeapCommit));
  825.     OUTPUT("\tLoaderFlags: 0x%X\r\n",
  826.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.LoaderFlags));
  827.     OUTPUT("\tNumberOfRvaAndSizes: 0x%X\r\n\r\n",
  828.         static_cast<DWORD>(pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes));
  829.  
  830.     OUTPUT("\tSubsystem: 0x%X %s\n\n",
  831.         pImageNtHeaders->OptionalHeader.Subsystem,
  832.         PEHelpers::GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem).c_str());
  833.  
  834.     // Print Data Directories
  835.     OUTPUT("[+] PE DATA DIRECTORIES\n");
  836.     for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
  837.         const auto& dir = pImageNtHeaders->OptionalHeader.DataDirectory[i];
  838.         if (dir.VirtualAddress != 0) {
  839.             OUTPUT("\t%s:\n", PEHelpers::GetDataDirectoryName(i).c_str());
  840.             OUTPUT("\t\tVirtualAddress: 0x%X\n", dir.VirtualAddress);
  841.             OUTPUT("\t\tSize: 0x%X\n", dir.Size);
  842.         }
  843.     }
  844.  
  845.     // Analyze Sections
  846.     OUTPUT("\n[+] PE IMAGE SECTIONS\r\n");
  847.     auto pSection = IMAGE_FIRST_SECTION(pImageNtHeaders);
  848.     for (WORD i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++, pSection++) {
  849.         // Create a null-terminated string from the section name
  850.         char sectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
  851.         memcpy(sectionName, pSection->Name, IMAGE_SIZEOF_SHORT_NAME);
  852.  
  853.         // Remove any non-printable characters
  854.         for (int j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) {
  855.             if (!isprint(static_cast<unsigned char>(sectionName[j]))) {
  856.                 sectionName[j] = '\0';
  857.             }
  858.         }
  859.  
  860.         // Convert to wide string
  861.         wchar_t wideSectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
  862.         MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  863.             sectionName, -1,
  864.             wideSectionName, IMAGE_SIZEOF_SHORT_NAME + 1);
  865.  
  866.         OUTPUT("\tSECTION : %s\r\n", wideSectionName);
  867.         OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\r\n", pSection->Misc.PhysicalAddress);
  868.         OUTPUT("\t\tMisc (VirtualSize) : 0x%X\r\n", pSection->Misc.VirtualSize);
  869.         OUTPUT("\t\tVirtualAddress : 0x%X\r\n", pSection->VirtualAddress);
  870.         OUTPUT("\t\tSizeOfRawData : 0x%X\r\n", pSection->SizeOfRawData);
  871.         OUTPUT("\t\tPointerToRawData : 0x%X\r\n", pSection->PointerToRawData);
  872.         OUTPUT("\t\tPointerToRelocations : 0x%X\r\n", pSection->PointerToRelocations);
  873.         OUTPUT("\t\tPointerToLinenumbers : 0x%X\r\n", pSection->PointerToLinenumbers);
  874.         OUTPUT("\t\tNumberOfRelocations : 0x%X\r\n", pSection->NumberOfRelocations);
  875.         OUTPUT("\t\tNumberOfLinenumbers : 0x%X\r\n", pSection->NumberOfLinenumbers);
  876.         OUTPUT("\t\tCharacteristics : 0x%X %s\r\n\r\n",
  877.             pSection->Characteristics,
  878.             PEHelpers::GetSectionProtection(pSection->Characteristics).c_str());
  879.     }
  880.  
  881.     ShowProgress(80);
  882.  
  883.     // Analyze Imports
  884.     const auto& importDir = pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
  885.     if (importDir.VirtualAddress && importDir.Size) {
  886.         OUTPUT("\n[+] IMPORTED DLLS AND FUNCTIONS\r\n");
  887.  
  888.         // Find the section containing imports
  889.         auto pSection = IMAGE_FIRST_SECTION(pImageNtHeaders);
  890.         PIMAGE_SECTION_HEADER pImportSection = nullptr;
  891.  
  892.         // Find the import section
  893.         for (WORD i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++, pSection++) {
  894.             if (importDir.VirtualAddress >= pSection->VirtualAddress &&
  895.                 importDir.VirtualAddress < (pSection->VirtualAddress + pSection->Misc.VirtualSize)) {
  896.                 pImportSection = pSection;
  897.                 break;
  898.             }
  899.         }
  900.  
  901.         if (!pImportSection) {
  902.             OUTPUT("[-] Could not find import section\r\n");
  903.             return;
  904.         }
  905.  
  906.         // Get the import descriptor
  907.         auto pImportDesc = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
  908.             (BYTE*)lpFileContent +
  909.             pImportSection->PointerToRawData +
  910.             (importDir.VirtualAddress - pImportSection->VirtualAddress));
  911.  
  912.         // Process all DLLs
  913.         while (pImportDesc && pImportDesc->Name != 0) {
  914.             // Get DLL name
  915.             const char* dllName = reinterpret_cast<const char*>(
  916.                 (BYTE*)lpFileContent +
  917.                 pImportSection->PointerToRawData +
  918.                 (pImportDesc->Name - pImportSection->VirtualAddress));
  919.  
  920.             if (!IsBadReadPtr(dllName, 1)) {
  921.                 std::vector<wchar_t> wideDllName(MAX_PATH);
  922.                 MultiByteToWideChar(CP_ACP, 0, dllName, -1,
  923.                     wideDllName.data(), MAX_PATH);
  924.  
  925.                 // Print DLL information
  926.                 OUTPUT("\n\tDLL NAME : %s\r\n", wideDllName.data());
  927.                 OUTPUT("\tCharacteristics : 0x%X\r\n", pImportDesc->Characteristics);
  928.                 OUTPUT("\tOriginalFirstThunk : 0x%X\r\n", pImportDesc->OriginalFirstThunk);
  929.                 OUTPUT("\tTimeDateStamp : 0x%X\r\n", pImportDesc->TimeDateStamp);
  930.                 OUTPUT("\tForwarderChain : 0x%X\r\n", pImportDesc->ForwarderChain);
  931.                 OUTPUT("\tFirstThunk : 0x%X\r\n", pImportDesc->FirstThunk);
  932.  
  933.                 OUTPUT("\n\tImported Functions :\r\n\r\n");
  934.  
  935.                 // Process functions using OriginalFirstThunk
  936.                 if (pImportDesc->OriginalFirstThunk) {
  937.                     auto pThunk = reinterpret_cast<PIMAGE_THUNK_DATA>(
  938.                         (BYTE*)lpFileContent +
  939.                         pImportSection->PointerToRawData +
  940.                         (pImportDesc->OriginalFirstThunk - pImportSection->VirtualAddress));
  941.  
  942.                     // Process all functions for this DLL
  943.                     while (pThunk && pThunk->u1.AddressOfData) {
  944.                         if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)) {
  945.                             auto pImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(
  946.                                 (BYTE*)lpFileContent +
  947.                                 pImportSection->PointerToRawData +
  948.                                 (pThunk->u1.AddressOfData - pImportSection->VirtualAddress));
  949.  
  950.                             if (!IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
  951.                                 std::vector<wchar_t> wideFuncName(MAX_PATH);
  952.                                 MultiByteToWideChar(CP_ACP, 0,
  953.                                     reinterpret_cast<const char*>(pImportByName->Name),
  954.                                     -1, wideFuncName.data(), MAX_PATH);
  955.  
  956.                                 OUTPUT("\t\t%s\r\n", wideFuncName.data());
  957.                             }
  958.                         }
  959.                         pThunk++;
  960.                     }
  961.                 }
  962.             }
  963.             pImportDesc++;
  964.         }
  965.     }
  966.  
  967.     ShowProgress(90);
  968.  
  969.     // In your AnalyzePEFile function, add this code after the imports section (before the cleanup label):
  970.  
  971.     // Handle Exports
  972.     const auto& exportDir = pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
  973.     if (exportDir.VirtualAddress && exportDir.Size) {
  974.         OUTPUT("\n[+] EXPORTED FUNCTIONS\n");
  975.  
  976.         auto pSection = IMAGE_FIRST_SECTION(pImageNtHeaders);
  977.         PIMAGE_SECTION_HEADER pExportSection = PEHelpers::GetExportSection(
  978.             pSection,
  979.             pImageNtHeaders->FileHeader.NumberOfSections,
  980.             exportDir.VirtualAddress
  981.         );
  982.  
  983.         if (!pExportSection) {
  984.             OUTPUT("[-] Could not find export section\n");
  985.         }
  986.         else {
  987.             auto pExportDir = reinterpret_cast<PIMAGE_EXPORT_DIRECTORY>(
  988.                 (BYTE*)lpFileContent +
  989.                 pExportSection->PointerToRawData +
  990.                 (exportDir.VirtualAddress - pExportSection->VirtualAddress));
  991.  
  992.             const DWORD_PTR dRawOffset = reinterpret_cast<DWORD_PTR>(lpFileContent) +
  993.                 pExportSection->PointerToRawData;
  994.  
  995.             OUTPUT("\tNumber of Functions: %d\n", pExportDir->NumberOfFunctions);
  996.             OUTPUT("\tNumber of Names: %d\n", pExportDir->NumberOfNames);
  997.             OUTPUT("\tBase: %d\n", pExportDir->Base);
  998.  
  999.             // Fix for DLL name display
  1000.             const char* dllName = reinterpret_cast<const char*>(
  1001.                 (BYTE*)lpFileContent +
  1002.                 pExportSection->PointerToRawData +
  1003.                 (pExportDir->Name - pExportSection->VirtualAddress));
  1004.  
  1005.             std::vector<wchar_t> wideDllName(MAX_PATH);
  1006.             MultiByteToWideChar(CP_ACP, 0, dllName, -1,
  1007.                 wideDllName.data(), MAX_PATH);
  1008.             OUTPUT("\tName: %s\n\n", wideDllName.data());
  1009.  
  1010.             const auto pArrayOfFunctionsNames = reinterpret_cast<DWORD*>(
  1011.                 dRawOffset + (pExportDir->AddressOfNames - pExportSection->VirtualAddress));
  1012.  
  1013.             OUTPUT("\tExported Functions:\n\n");
  1014.             for (DWORD i = 0; i < pExportDir->NumberOfNames; ++i) {
  1015.                 const char* functionName = reinterpret_cast<const char*>(
  1016.                     dRawOffset + (pArrayOfFunctionsNames[i] - pExportSection->VirtualAddress));
  1017.  
  1018.                 std::vector<wchar_t> wideFuncName(MAX_PATH);
  1019.                 MultiByteToWideChar(CP_ACP, 0, functionName, -1,
  1020.                     wideFuncName.data(), MAX_PATH);
  1021.  
  1022.                 OUTPUT("\t\t%s\n", wideFuncName.data());
  1023.             }
  1024.         }
  1025.     }
  1026.  
  1027.     // In your AnalyzePEFile function, at the end:
  1028.     ShowProgress(100);
  1029.     SetStatusText(L"Analysis complete");
  1030.     ShowWindow(g_hProgressBar, SW_HIDE);  // Optional: hide progress bar when done
  1031.  
  1032. cleanup:
  1033.     if (lpFileContent) {
  1034.         UnmapViewOfFile(lpFileContent);
  1035.     }
  1036.     if (hFileMapping) {
  1037.         CloseHandle(hFileMapping);
  1038.     }
  1039.     if (hFile) {
  1040.         CloseHandle(hFile);
  1041.     }
  1042.  
  1043.     UpdateEditControl();
  1044. }
  1045.  
  1046. /*
  1047. //use below vv ALWAYS
  1048. void AnalyzePEFile(const wchar_t* filePathW) {
  1049.     OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
  1050.  
  1051.     LPVOID lpFileContent = GetFileContent(filePathW);
  1052.     if (!lpFileContent) {
  1053.         OUTPUT("[-] Failed to read file content!\n");
  1054.         return;
  1055.     }
  1056.  
  1057.     const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileContent);
  1058.     if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
  1059.         OUTPUT("[-] Invalid DOS signature!\n");
  1060.         HeapFree(GetProcessHeap(), 0, lpFileContent);
  1061.         return;
  1062.     }
  1063.  
  1064.     const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>((DWORD_PTR)lpFileContent + pImageDosHeader->e_lfanew);
  1065.     if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
  1066.         OUTPUT("[-] Invalid NT signature!\n");
  1067.         HeapFree(GetProcessHeap(), 0, lpFileContent);
  1068.         return;
  1069.     }
  1070.  
  1071.     //UpdateEditControl(); //added just now remove line!
  1072.  
  1073.     OUTPUT("[+] PE FILE HEADER\n");
  1074.     OUTPUT("\tMachine : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.Machine);
  1075.     OUTPUT("\tNumberOfSections : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSections);
  1076.     OUTPUT("\tTimeDateStamp : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.TimeDateStamp);
  1077.     OUTPUT("\tPointerToSymbolTable : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.PointerToSymbolTable);
  1078.     OUTPUT("\tNumberOfSymbols : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSymbols);
  1079.     OUTPUT("\tSizeOfOptionalHeader : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.SizeOfOptionalHeader);
  1080.     OUTPUT("\tCharacteristics : 0x%X %s\n\n", (uintptr_t)pImageNtHeaders->FileHeader.Characteristics, GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics));
  1081.  
  1082.     OUTPUT("[+] PE OPTIONAL HEADER\n");
  1083.     OUTPUT("\tMagic : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Magic);
  1084.     OUTPUT("\tAddressOfEntryPoint : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
  1085.     OUTPUT("\tImageBase : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.ImageBase);
  1086.     OUTPUT("\tSectionAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SectionAlignment);
  1087.     OUTPUT("\tFileAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.FileAlignment);
  1088.     OUTPUT("\tMajorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
  1089.     OUTPUT("\tMinorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
  1090.     OUTPUT("\tMajorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorImageVersion);
  1091.     OUTPUT("\tMinorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorImageVersion);
  1092.     OUTPUT("\tMajorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorSubsystemVersion);
  1093.     OUTPUT("\tMinorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorSubsystemVersion);
  1094.     OUTPUT("\tWin32VersionValue : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Win32VersionValue);
  1095.     OUTPUT("\tSizeOfImage : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfImage);
  1096.     OUTPUT("\tSizeOfHeaders : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeaders);
  1097.     OUTPUT("\tCheckSum : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.CheckSum);
  1098.     OUTPUT("\tSubsystem : 0x%X %s\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Subsystem, GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem));
  1099.     OUTPUT("\tDllCharacteristics : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.DllCharacteristics);
  1100.     OUTPUT("\tSizeOfStackReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackReserve);
  1101.     OUTPUT("\tSizeOfStackCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackCommit);
  1102.     OUTPUT("\tSizeOfHeapReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapReserve);
  1103.     OUTPUT("\tSizeOfHeapCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapCommit);
  1104.     OUTPUT("\tLoaderFlags : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.LoaderFlags);
  1105.     OUTPUT("\tNumberOfRvaAndSizes : 0x%X\n\n", (uintptr_t)pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes);
  1106.  
  1107.     //UpdateEditControl(); //added just now remove line!
  1108.  
  1109.     GetDataDirectories(&pImageNtHeaders->OptionalHeader.DataDirectory[0]);
  1110.  
  1111.     const auto pImageSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>((DWORD_PTR)pImageNtHeaders + sizeof(IMAGE_NT_HEADERS));
  1112.     const auto pImageImportSection = GetSections(pImageSectionHeader, pImageNtHeaders->FileHeader.NumberOfSections, pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress);
  1113.  
  1114.     if (!pImageImportSection) {
  1115.         OUTPUT("[-] Error: Could not find import section!\n");
  1116.         HeapFree(GetProcessHeap(), 0, lpFileContent);
  1117.         return;
  1118.     }
  1119.  
  1120.     const auto pImageImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>((DWORD_PTR)lpFileContent + pImageImportSection->PointerToRawData);
  1121.     if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
  1122.         GetImports32(pImageImportDescriptor, (DWORD)lpFileContent + pImageImportSection->PointerToRawData, pImageImportSection);
  1123.     }
  1124.     else if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) {
  1125.         GetImports64(pImageImportDescriptor, (DWORD)lpFileContent + pImageImportSection->PointerToRawData, pImageImportSection);
  1126.     }
  1127.     else {
  1128.         OUTPUT("[-] Unsupported architecture!\n");
  1129.     }
  1130.  
  1131.     HeapFree(GetProcessHeap(), 0, lpFileContent);
  1132.     UpdateEditControl();
  1133. }
  1134.  
  1135. void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory) {
  1136.     OUTPUT("[+] PE DATA DIRECTORIES\n");
  1137.     for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i, ++pImageDataDirectory) {
  1138.         if (pImageDataDirectory->VirtualAddress == 0) continue;
  1139.         OUTPUT("\tDataDirectory (%s) VirtualAddress : 0x%X\n", GetDataDirectoryName(i), (uintptr_t)pImageDataDirectory->VirtualAddress);
  1140.         OUTPUT("\tDataDirectory (%s) Size : 0x%X\n\n", GetDataDirectoryName(i), (uintptr_t)pImageDataDirectory->Size);
  1141.     }
  1142. }
  1143.  
  1144. PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader, int NumberOfSections, DWORD dImportAddress) {
  1145.     PIMAGE_SECTION_HEADER pImageImportHeader = nullptr;
  1146.     OUTPUT("\n[+] PE IMAGE SECTIONS\n");
  1147.     for (int i = 0; i < NumberOfSections; ++i) {
  1148.         const auto pCurrentSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>((DWORD_PTR)pImageSectionHeader + i * sizeof(IMAGE_SECTION_HEADER));
  1149.         OUTPUT("\n\tSECTION : %s\n", (wchar_t*)pCurrentSectionHeader->Name);
  1150.         OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\n", (uintptr_t)pCurrentSectionHeader->Misc.PhysicalAddress);
  1151.         OUTPUT("\t\tMisc (VirtualSize) : 0x%X\n", (uintptr_t)pCurrentSectionHeader->Misc.VirtualSize);
  1152.         OUTPUT("\t\tVirtualAddress : 0x%X\n", (uintptr_t)pCurrentSectionHeader->VirtualAddress);
  1153.         OUTPUT("\t\tSizeOfRawData : 0x%X\n", (uintptr_t)pCurrentSectionHeader->SizeOfRawData);
  1154.         OUTPUT("\t\tPointerToRawData : 0x%X\n", (uintptr_t)pCurrentSectionHeader->PointerToRawData);
  1155.         OUTPUT("\t\tCharacteristics : 0x%X %s\n", (uintptr_t)pCurrentSectionHeader->Characteristics, GetSectionProtection(pCurrentSectionHeader->Characteristics));
  1156.  
  1157.         if (dImportAddress >= pCurrentSectionHeader->VirtualAddress && dImportAddress < pCurrentSectionHeader->VirtualAddress + pCurrentSectionHeader->Misc.VirtualSize) {
  1158.             pImageImportHeader = pCurrentSectionHeader;
  1159.         }
  1160.     }
  1161.     return pImageImportHeader;
  1162. }
  1163.  
  1164. void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor, DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection) {
  1165.     OUTPUT("\n[+] IMPORTED DLL\n");
  1166.     while (pImageImportDescriptor->Name != 0) {
  1167.         OUTPUT("\n\tDLL NAME : %s\n", (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  1168.         if (pImageImportDescriptor->OriginalFirstThunk == 0) {
  1169.             ++pImageImportDescriptor;
  1170.             continue;
  1171.         }
  1172.         auto pOriginalFirstThunk = reinterpret_cast<PIMAGE_THUNK_DATA32>(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  1173.         while (pOriginalFirstThunk->u1.AddressOfData != 0) {
  1174.             const auto pImageImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(dRawOffset + (pOriginalFirstThunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  1175.             if (pImageImportByName) {
  1176.                 OUTPUT("\t\tFunction: %s\n", (char*)pImageImportByName->Name);
  1177.             }
  1178.             pOriginalFirstThunk++;
  1179.         }
  1180.         pImageImportDescriptor++;
  1181.     }
  1182. }
  1183.  
  1184. void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor, DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection) {
  1185.     OUTPUT("\n[+] IMPORTED DLL\n");
  1186.     while (pImageImportDescriptor->Name != 0) {
  1187.         OUTPUT("\n\tDLL NAME : %s\n", (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  1188.         if (pImageImportDescriptor->OriginalFirstThunk == 0) {
  1189.             ++pImageImportDescriptor;
  1190.             continue;
  1191.         }
  1192.         auto pOriginalFirstThunk = reinterpret_cast<PIMAGE_THUNK_DATA64>(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  1193.         while (pOriginalFirstThunk->u1.AddressOfData != 0) {
  1194.             const auto pImageImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(dRawOffset + (pOriginalFirstThunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  1195.             if (pImageImportByName) {
  1196.                 OUTPUT("\t\tFunction: %s\n", (char*)pImageImportByName->Name);
  1197.             }
  1198.             pOriginalFirstThunk++;
  1199.         }
  1200.         pImageImportDescriptor++;
  1201.     }
  1202. }
  1203. //use above ^^ ALWAYS
  1204. */
  1205.  
  1206.  
  1207. /*
  1208. // older-orig-deprecated vv
  1209. // Main PE Analysis function
  1210. void AnalyzePEFile(const wchar_t* filePathW)
  1211. {
  1212.     //WCHAR filePathW[MAX_PATH];
  1213.     //MultiByteToWideChar(CP_ACP, 0, filePathA, -1, filePathW, MAX_PATH);
  1214.     OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
  1215.     //AppendToOutput(L"[+] Starting PE Analysis for: %ls\n\n", filePathW);
  1216.  
  1217.     // Get file content
  1218.     LPVOID lpFileContent = GetFileContent(filePathW);
  1219.     if (!lpFileContent)
  1220.     {
  1221.         OUTPUT("[-] Failed to read file content!\n");
  1222.         return;
  1223.     }
  1224.  
  1225.     // Get DOS header
  1226.     const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileContent);
  1227.     if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
  1228.     {
  1229.         OUTPUT("[-] Invalid DOS signature!\n");
  1230.         HeapFree(GetProcessHeap(), 0, lpFileContent);
  1231.         return;
  1232.     }
  1233.  
  1234.     // Get NT headers
  1235.     const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>((DWORD_PTR)lpFileContent + pImageDosHeader->e_lfanew);
  1236.     if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE)
  1237.     {
  1238.         OUTPUT("[-] Invalid NT signature!\n");
  1239.         HeapFree(GetProcessHeap(), 0, lpFileContent);
  1240.         return;
  1241.     }
  1242.  
  1243.     // Display File Header information
  1244.     OUTPUT("[+] PE FILE HEADER\n");
  1245.     OUTPUT("\tMachine : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.Machine);
  1246.     OUTPUT("\tNumberOfSections : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSections);
  1247.     OUTPUT("\tTimeDateStamp : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.TimeDateStamp);
  1248.     OUTPUT("\tPointerToSymbolTable : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.PointerToSymbolTable);
  1249.     OUTPUT("\tNumberOfSymbols : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSymbols);
  1250.     OUTPUT("\tSizeOfOptionalHeader : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.SizeOfOptionalHeader);
  1251.     OUTPUT("\tCharacteristics : 0x%X %s\n\n",
  1252.         (uintptr_t)pImageNtHeaders->FileHeader.Characteristics,
  1253.         GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics));
  1254.  
  1255.     // Display Optional Header information
  1256.     OUTPUT("[+] PE OPTIONAL HEADER\n");
  1257.     OUTPUT("\tMagic : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Magic);
  1258.     OUTPUT("\tAddressOfEntryPoint : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
  1259.     OUTPUT("\tImageBase : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.ImageBase);
  1260.     OUTPUT("\tSectionAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SectionAlignment);
  1261.     OUTPUT("\tFileAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.FileAlignment);
  1262.     OUTPUT("\tMajorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
  1263.     OUTPUT("\tMinorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
  1264.     OUTPUT("\tMajorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorImageVersion);
  1265.     OUTPUT("\tMinorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorImageVersion);
  1266.     OUTPUT("\tMajorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorSubsystemVersion);
  1267.     OUTPUT("\tMinorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorSubsystemVersion);
  1268.     OUTPUT("\tWin32VersionValue : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Win32VersionValue);
  1269.     OUTPUT("\tSizeOfImage : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfImage);
  1270.     OUTPUT("\tSizeOfHeaders : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeaders);
  1271.     OUTPUT("\tCheckSum : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.CheckSum);
  1272.     OUTPUT("\tSubsystem : 0x%X %s\n",
  1273.         (uintptr_t)pImageNtHeaders->OptionalHeader.Subsystem,
  1274.         GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem));
  1275.     OUTPUT("\tDllCharacteristics : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.DllCharacteristics);
  1276.     OUTPUT("\tSizeOfStackReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackReserve);
  1277.     OUTPUT("\tSizeOfStackCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackCommit);
  1278.     OUTPUT("\tSizeOfHeapReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapReserve);
  1279.     OUTPUT("\tSizeOfHeapCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapCommit);
  1280.     OUTPUT("\tLoaderFlags : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.LoaderFlags);
  1281.     OUTPUT("\tNumberOfRvaAndSizes : 0x%X\n\n", (uintptr_t)pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes);
  1282.  
  1283.     // Get Data Directories
  1284.     GetDataDirectories(&pImageNtHeaders->OptionalHeader.DataDirectory[0]);
  1285.  
  1286.     // Get the import section
  1287.     const auto pImageSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(
  1288.         (DWORD_PTR)pImageNtHeaders + sizeof(IMAGE_NT_HEADERS));
  1289.  
  1290.     const auto pImageImportSection = GetSections(
  1291.         pImageSectionHeader,
  1292.         pImageNtHeaders->FileHeader.NumberOfSections,
  1293.         pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress);
  1294.  
  1295.     if (!pImageImportSection)
  1296.     {
  1297.         OUTPUT("[-] Error: Could not find import section!\n");
  1298.         HeapFree(GetProcessHeap(), 0, lpFileContent);
  1299.         return;
  1300.     }
  1301.  
  1302.     // Get imports based on architecture
  1303.     const auto pImageImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
  1304.         (DWORD_PTR)lpFileContent + pImageImportSection->PointerToRawData);
  1305.  
  1306.     if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
  1307.     {
  1308.         GetImports32(
  1309.             pImageImportDescriptor,
  1310.             (DWORD)lpFileContent + pImageImportSection->PointerToRawData,
  1311.             pImageImportSection);
  1312.     }
  1313.     else if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
  1314.     {
  1315.         GetImports64(
  1316.             pImageImportDescriptor,
  1317.             (DWORD)lpFileContent + pImageImportSection->PointerToRawData,
  1318.             pImageImportSection);
  1319.     }
  1320.     else
  1321.     {
  1322.         OUTPUT("[-] Unsupported architecture!\n");
  1323.     }
  1324.  
  1325.     // Cleanup
  1326.     HeapFree(GetProcessHeap(), 0, lpFileContent);
  1327.  
  1328.     // Update the GUI with the analysis results
  1329.     UpdateEditControl();
  1330. }
  1331.  
  1332. void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory)
  1333. {
  1334.     OUTPUT("[+] PE DATA DIRECTORIES\n");
  1335.     for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i, ++pImageDataDirectory)
  1336.     {
  1337.         if (pImageDataDirectory->VirtualAddress == 0)
  1338.             continue;
  1339.  
  1340.         OUTPUT("\tDataDirectory (%s) VirtualAddress : 0x%X\n",
  1341.             GetDataDirectoryName(i),
  1342.             (uintptr_t)pImageDataDirectory->VirtualAddress);
  1343.         OUTPUT("\tDataDirectory (%s) Size : 0x%X\n\n",
  1344.             GetDataDirectoryName(i),
  1345.             (uintptr_t)pImageDataDirectory->Size);
  1346.     }
  1347. }
  1348.  
  1349. PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader,
  1350.     int NumberOfSections, DWORD dImportAddress)
  1351. {
  1352.     PIMAGE_SECTION_HEADER pImageImportHeader = nullptr;
  1353.  
  1354.     OUTPUT("\n[+] PE IMAGE SECTIONS\n");
  1355.  
  1356.     for (int i = 0; i < NumberOfSections; ++i)
  1357.     {
  1358.         const auto pCurrentSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageSectionHeader +
  1359.             i * sizeof(IMAGE_SECTION_HEADER));
  1360.  
  1361.         OUTPUT("\n\tSECTION : %s\n", (wchar_t*)pCurrentSectionHeader->Name);
  1362.         OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\n",
  1363.             (uintptr_t)pCurrentSectionHeader->Misc.PhysicalAddress);
  1364.         OUTPUT("\t\tMisc (VirtualSize) : 0x%X\n",
  1365.             (uintptr_t)pCurrentSectionHeader->Misc.VirtualSize);
  1366.         OUTPUT("\t\tVirtualAddress : 0x%X\n",
  1367.             (uintptr_t)pCurrentSectionHeader->VirtualAddress);
  1368.         OUTPUT("\t\tSizeOfRawData : 0x%X\n",
  1369.             (uintptr_t)pCurrentSectionHeader->SizeOfRawData);
  1370.         OUTPUT("\t\tPointerToRawData : 0x%X\n",
  1371.             (uintptr_t)pCurrentSectionHeader->PointerToRawData);
  1372.         OUTPUT("\t\tPointerToRelocations : 0x%X\n",
  1373.             (uintptr_t)pCurrentSectionHeader->PointerToRelocations);
  1374.         OUTPUT("\t\tPointerToLinenumbers : 0x%X\n",
  1375.             (uintptr_t)pCurrentSectionHeader->PointerToLinenumbers);
  1376.         OUTPUT("\t\tNumberOfRelocations : 0x%X\n",
  1377.             (uintptr_t)pCurrentSectionHeader->NumberOfRelocations);
  1378.         OUTPUT("\t\tNumberOfLinenumbers : 0x%X\n",
  1379.             (uintptr_t)pCurrentSectionHeader->NumberOfLinenumbers);
  1380.         OUTPUT("\t\tCharacteristics : 0x%X %s\n",
  1381.             (uintptr_t)pCurrentSectionHeader->Characteristics,
  1382.             GetSectionProtection(pCurrentSectionHeader->Characteristics));
  1383.  
  1384.         if (dImportAddress >= pCurrentSectionHeader->VirtualAddress &&
  1385.             dImportAddress < pCurrentSectionHeader->VirtualAddress +
  1386.             pCurrentSectionHeader->Misc.VirtualSize)
  1387.         {
  1388.             pImageImportHeader = pCurrentSectionHeader;
  1389.         }
  1390.     }
  1391.  
  1392.     return pImageImportHeader;
  1393. }
  1394. void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
  1395.     DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection)
  1396. {
  1397.     OUTPUT("\n[+] IMPORTED DLL\n");
  1398.  
  1399.     while (pImageImportDescriptor->Name != 0)
  1400.     {
  1401.         OUTPUT("\n\tDLL NAME : %s\n",
  1402.             (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  1403.         OUTPUT("\tCharacteristics : 0x%X\n",
  1404.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->Characteristics - pImageImportSection->VirtualAddress)));
  1405.         OUTPUT("\tOriginalFirstThunk : 0x%X\n",
  1406.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress)));
  1407.         OUTPUT("\tTimeDateStamp : 0x%X\n",
  1408.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->TimeDateStamp - pImageImportSection->VirtualAddress)));
  1409.         OUTPUT("\tForwarderChain : 0x%X\n",
  1410.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->ForwarderChain - pImageImportSection->VirtualAddress)));
  1411.         OUTPUT("\tFirstThunk : 0x%X\n",
  1412.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->FirstThunk - pImageImportSection->VirtualAddress)));
  1413.  
  1414.         if (pImageImportDescriptor->OriginalFirstThunk == 0)
  1415.         {
  1416.             ++pImageImportDescriptor;
  1417.             continue;
  1418.         }
  1419.  
  1420.         auto pOriginalFirstThrunk = (PIMAGE_THUNK_DATA32)(dRawOffset +
  1421.             (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  1422.  
  1423.         OUTPUT("\n\tImported Functions : \n\n");
  1424.  
  1425.         while (pOriginalFirstThrunk->u1.AddressOfData != 0)
  1426.         {
  1427.             if (pOriginalFirstThrunk->u1.AddressOfData >= IMAGE_ORDINAL_FLAG32)
  1428.             {
  1429.                 ++pOriginalFirstThrunk;
  1430.                 continue;
  1431.             }
  1432.  
  1433.             const auto pImageImportByName = (PIMAGE_IMPORT_BY_NAME)(dRawOffset +
  1434.                 (pOriginalFirstThrunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  1435.  
  1436.             if (pImageImportByName == nullptr)
  1437.             {
  1438.                 ++pOriginalFirstThrunk;
  1439.                 continue;
  1440.             }
  1441.  
  1442.             if (pOriginalFirstThrunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
  1443.             {
  1444.                 OUTPUT("\t\t0x%X (Ordinal) : %s\n",
  1445.                     (uintptr_t)pOriginalFirstThrunk->u1.AddressOfData,
  1446.                     (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
  1447.             }
  1448.             else
  1449.             {
  1450.                 OUTPUT("\t\t%s\n",
  1451.                     (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
  1452.             }
  1453.  
  1454.             ++pOriginalFirstThrunk;
  1455.         }
  1456.  
  1457.         ++pImageImportDescriptor;
  1458.     }
  1459. }
  1460.  
  1461. void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
  1462.     DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection)
  1463. {
  1464.     OUTPUT("\n[+] IMPORTED DLL\n");
  1465.  
  1466.     while (pImageImportDescriptor->Name != 0)
  1467.     {
  1468.         OUTPUT("\n\tDLL NAME : %s\n",
  1469.             (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  1470.         OUTPUT("\tCharacteristics : 0x%X\n",
  1471.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->Characteristics - pImageImportSection->VirtualAddress)));
  1472.         OUTPUT("\tOriginalFirstThunk : 0x%X\n",
  1473.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress)));
  1474.         OUTPUT("\tTimeDateStamp : 0x%X\n",
  1475.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->TimeDateStamp - pImageImportSection->VirtualAddress)));
  1476.         OUTPUT("\tForwarderChain : 0x%X\n",
  1477.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->ForwarderChain - pImageImportSection->VirtualAddress)));
  1478.         OUTPUT("\tFirstThunk : 0x%X\n",
  1479.             (uintptr_t)(dRawOffset + (pImageImportDescriptor->FirstThunk - pImageImportSection->VirtualAddress)));
  1480.  
  1481.         if (pImageImportDescriptor->OriginalFirstThunk == 0)
  1482.         {
  1483.             ++pImageImportDescriptor;
  1484.             continue;
  1485.         }
  1486.  
  1487.         auto pOriginalFirstThrunk = (PIMAGE_THUNK_DATA64)(dRawOffset +
  1488.             (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  1489.  
  1490.         OUTPUT("\n\tImported Functions : \n\n");
  1491.  
  1492.         while (pOriginalFirstThrunk->u1.AddressOfData != 0)
  1493.         {
  1494.             if (pOriginalFirstThrunk->u1.AddressOfData >= IMAGE_ORDINAL_FLAG64)
  1495.             {
  1496.                 ++pOriginalFirstThrunk;
  1497.                 continue;
  1498.             }
  1499.  
  1500.             const auto pImageImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)dRawOffset +
  1501.                 (pOriginalFirstThrunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  1502.  
  1503.             if (pImageImportByName == nullptr)
  1504.             {
  1505.                 ++pOriginalFirstThrunk;
  1506.                 continue;
  1507.             }
  1508.  
  1509.             if (pOriginalFirstThrunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
  1510.             {
  1511.                 OUTPUT("\t\t0x%llX (Ordinal) : %s\n",
  1512.                     pOriginalFirstThrunk->u1.AddressOfData,
  1513.                     (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
  1514.             }
  1515.             else
  1516.             {
  1517.                 OUTPUT("\t\t%s\n",
  1518.                     (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
  1519.             }
  1520.  
  1521.             ++pOriginalFirstThrunk;
  1522.         }
  1523.  
  1524.         ++pImageImportDescriptor;
  1525.     }
  1526. }
  1527. // older-orig-deprecated ^^
  1528. */
  1529.  
  1530. //filePathW
  1531. //lpFilePath
  1532. HANDLE GetFileContent(const wchar_t* lpFilePath) {
  1533.     HANDLE hFile = CreateFileW(lpFilePath, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
  1534.     if (hFile == INVALID_HANDLE_VALUE) return nullptr;
  1535.     DWORD fileSize = GetFileSize(hFile, nullptr);
  1536.     auto lpFileContent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, fileSize);
  1537.     DWORD bytesRead;
  1538.     ReadFile(hFile, lpFileContent, fileSize, &bytesRead, nullptr);
  1539.     CloseHandle(hFile);
  1540.     return lpFileContent;
  1541. }
  1542.  
  1543. void UpdateEditControl() {
  1544.     SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  1545.     SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  1546.     SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  1547. }
Tags: #all-done!!!
Add Comment
Please, Sign In to add comment