alien_fx_fiend

PE-Explorer (Ani+Textual ProgressBar) Needs PEFixing *FINAL RELEASE 4.0*

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