Advertisement
alien_fx_fiend

PE-Explorer GUI (No Maximize/Resize) *FINAL RELEASE 2.4*

Nov 27th, 2024
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 51.95 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 "helpers.h"
  15. #include "resource.h"
  16. #pragma comment(lib, "comctl32.lib")
  17.  
  18. namespace PEHelpers {
  19.    std::wstring GetImageCharacteristics(DWORD characteristics) {
  20.        if (characteristics & IMAGE_FILE_DLL) return L"(DLL)";
  21.        if (characteristics & IMAGE_FILE_SYSTEM) return L"(DRIVER)";
  22.        if (characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) return L"(EXE)";
  23.        return L"(UNKNOWN)";
  24.    }
  25.  
  26.    std::wstring GetSubsystem(WORD subsystem) {
  27.        switch (subsystem) {
  28.        case IMAGE_SUBSYSTEM_NATIVE: return L"(NATIVE/DRIVER)";
  29.        case IMAGE_SUBSYSTEM_WINDOWS_GUI: return L"(GUI)";
  30.        case IMAGE_SUBSYSTEM_WINDOWS_CUI: return L"(CONSOLE)";
  31.        default: return L"(UNKNOWN)";
  32.        }
  33.    }
  34.  
  35.    std::wstring GetDataDirectoryName(int DirectoryNumber) {
  36.        switch (DirectoryNumber) {
  37.        case 0: return L"Export Table";
  38.        case 1: return L"Import Table";
  39.        case 2: return L"Resource Table";
  40.        case 3: return L"Exception Entry";
  41.        case 4: return L"Security Entry";
  42.        case 5: return L"Relocation Table";
  43.        case 6: return L"Debug Entry";
  44.        case 7: return L"Copyright Entry";
  45.        case 8: return L"Global PTR Entry";
  46.        case 9: return L"TLS Entry";
  47.        case 10: return L"Configuration Entry";
  48.        case 11: return L"Bound Import Entry";
  49.        case 12: return L"IAT";
  50.        case 13: return L"Delay Import Descriptor";
  51.        case 14: return L"COM Descriptor";
  52.        default: return L"Unknown";
  53.        }
  54.    }
  55.  
  56.    std::wstring GetSectionProtection(DWORD characteristics) {
  57.        std::wstring protection = L"(";
  58.        bool needsSeparator = false;
  59.  
  60.        if (characteristics & IMAGE_SCN_MEM_EXECUTE) {
  61.            protection += L"EXECUTE";
  62.            needsSeparator = true;
  63.        }
  64.  
  65.        if (characteristics & IMAGE_SCN_MEM_READ) {
  66.            if (needsSeparator) protection += L" | ";
  67.            protection += L"READ";
  68.            needsSeparator = true;
  69.        }
  70.  
  71.        if (characteristics & IMAGE_SCN_MEM_WRITE) {
  72.            if (needsSeparator) protection += L" | ";
  73.            protection += L"WRITE";
  74.        }
  75.  
  76.        protection += L")";
  77.        return protection;
  78.    }
  79. }
  80.  
  81. using namespace std;
  82.  
  83. // At the top of your file, change the window class name to wide string
  84. #define WINDOW_CLASS_NAME L"PEAnalyzerWindow"
  85. //const wchar_t* const WINDOW_CLASS_NAME = L"PEAnalyzerWindow";
  86.  
  87. // Use ANSI versions explicitly
  88. //#undef CreateWindow
  89. //#undef CreateWindowEx
  90. //#define CreateWindow  CreateWindowW
  91. //#define CreateWindowEx CreateWindowExW
  92.  
  93. // Helper function to replace printf with GUI output
  94. #define OUTPUT(format, ...) AppendToOutput(L##format, ##__VA_ARGS__)
  95. //#define OUTPUT(format, ...) AppendToOutput(format, ##__VA_ARGS__)
  96. //#define printf(format, ...) AppendToOutput(format, ##__VA_ARGS__)
  97.  
  98. // Window dimensions
  99. #define WINDOW_WIDTH    1024
  100. #define WINDOW_HEIGHT   768
  101. #define EDIT_MARGIN    10
  102.  
  103. // Global variables
  104. HWND g_hMainWindow = NULL;
  105. HWND g_hEditControl = NULL;
  106. HFONT g_hFont = NULL;
  107. std::wstringstream g_OutputText;
  108. WCHAR filePathW[MAX_PATH];
  109. std::vector<wchar_t> g_OutputBuffer;
  110. std::wstring tempBuffer; // Declare tempBuffer globally
  111.  
  112. // Function declarations
  113. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  114. LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
  115. void CreateMainWindow(HINSTANCE hInstance);
  116. void InitializeControls(HWND hwnd);
  117. void AddMenus(HWND hwnd);
  118. void OpenFileDialog(HWND hwnd);
  119. //void AnalyzePEFile(const WCHAR* filePathW);
  120. void AnalyzePEFile(const wchar_t* filePathW);
  121. HANDLE GetFileContent(const wchar_t* lpFilePath);
  122. /*void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory);
  123. PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader,
  124.    int NumberOfSections, DWORD dImportAddress);
  125. void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
  126.    DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection);
  127. void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
  128.    DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection);*/
  129. void AppendToOutput(const wchar_t* format, ...);
  130. void UpdateEditControl();
  131.  
  132. // Main window class name
  133. //const char* const WINDOW_CLASS_NAME = "PEAnalyzerWindow";
  134.  
  135. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  136.    INITCOMMONCONTROLSEX icc = { sizeof(INITCOMMONCONTROLSEX), ICC_WIN95_CLASSES };
  137.    InitCommonControlsEx(&icc);
  138.  
  139.    CreateMainWindow(hInstance);
  140.    if (!g_hMainWindow) return -1;
  141.  
  142.    ShowWindow(g_hMainWindow, nCmdShow);
  143.    UpdateWindow(g_hMainWindow);
  144.  
  145.    MSG msg = {};
  146.    while (GetMessage(&msg, NULL, 0, 0)) {
  147.        TranslateMessage(&msg);
  148.        DispatchMessage(&msg);
  149.    }
  150.  
  151.    if (g_hFont) DeleteObject(g_hFont);
  152.    return (int)msg.wParam;
  153. }
  154.  
  155. void CreateMainWindow(HINSTANCE hInstance) {
  156.    WNDCLASSEXW wc = { sizeof(WNDCLASSEXW), 0, WindowProc, 0, 0, hInstance, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)), LoadCursor(NULL, IDC_ARROW), (HBRUSH)(COLOR_WINDOW + 1), NULL, WINDOW_CLASS_NAME, LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)) };
  157.    RegisterClassExW(&wc);
  158.  
  159.    // Get screen dimensions
  160.    int screenWidth = GetSystemMetrics(SM_CXSCREEN);
  161.    int screenHeight = GetSystemMetrics(SM_CYSCREEN);
  162.  
  163.    // Calculate center position
  164.    int windowX = (screenWidth - WINDOW_WIDTH) / 2;
  165.    int windowY = (screenHeight - WINDOW_HEIGHT) / 2;
  166.  
  167.    // Remove WS_MAXIMIZEBOX and WS_THICKFRAME from the window style
  168.    DWORD style = (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX) & ~WS_THICKFRAME;
  169.    //WS_OVERLAPPEDWINDOW ~~> style
  170.    g_hMainWindow = CreateWindowExW(0, WINDOW_CLASS_NAME, L"PE File Analyzer", style, windowX, windowY, WINDOW_WIDTH, WINDOW_HEIGHT, nullptr, nullptr, hInstance, nullptr);
  171. }
  172.  
  173. void InitializeControls(HWND hwnd) {
  174.    g_hEditControl = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"",
  175.        WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
  176.        EDIT_MARGIN, EDIT_MARGIN,
  177.        WINDOW_WIDTH - (2 * EDIT_MARGIN), WINDOW_HEIGHT - (2 * EDIT_MARGIN),
  178.        hwnd, nullptr,
  179.        (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), nullptr);
  180.  
  181.    g_hFont = CreateFont(-14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
  182.        ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  183.        DEFAULT_QUALITY, DEFAULT_PITCH | FF_MODERN, L"Consolas");
  184.  
  185.    if (g_hFont)
  186.        SendMessage(g_hEditControl, WM_SETFONT, (WPARAM)g_hFont, TRUE);
  187.  
  188.    // Add this line to subclass the Edit control
  189.    SetWindowSubclass(g_hEditControl, EditSubclassProc, 0, 0);
  190. }
  191.  
  192. void AddMenus(HWND hwnd) {
  193.    HMENU hMenuBar = CreateMenu();
  194.    HMENU hFileMenu = CreateMenu();
  195.    AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hFileMenu, L"&File");
  196.    AppendMenu(hFileMenu, MF_STRING, 1, L"&Open");
  197.    AppendMenu(hFileMenu, MF_STRING, 2, L"E&xit");
  198.    SetMenu(hwnd, hMenuBar);
  199. }
  200.  
  201. LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
  202.    if (uMsg == WM_KEYDOWN) {
  203.        switch (wParam) {
  204.        case VK_F1:    // F1 key
  205.            SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_F1, 0);
  206.            return 0;
  207.        case VK_ESCAPE: // Escape key
  208.            SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_ESCAPE, 0);
  209.            return 0;
  210.        }
  211.    }
  212.    return DefSubclassProc(hwnd, uMsg, wParam, lParam);
  213. }
  214.  
  215. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  216.    switch (uMsg) {
  217.    case WM_CREATE: InitializeControls(hwnd); AddMenus(hwnd); return 0;
  218.    case WM_SIZE: SetWindowPos(g_hEditControl, NULL, EDIT_MARGIN, EDIT_MARGIN, LOWORD(lParam) - (2 * EDIT_MARGIN), HIWORD(lParam) - (2 * EDIT_MARGIN), SWP_NOZORDER); return 0;
  219.    case WM_KEYDOWN:
  220.        switch (wParam) {
  221.        case VK_F1:
  222.            MessageBoxW(hwnd,
  223.                L"PE Header Parser 2.3 GUI-based Programmed in C++ Win32 API (1173 lines of code) by Entisoft Software(c) Evans Thorpemorton",
  224.                L"About",
  225.                MB_OK | MB_ICONINFORMATION);
  226.            return 0;
  227.  
  228.        case VK_ESCAPE:
  229.            PostQuitMessage(0);
  230.            return 0;
  231.        }
  232.        break;
  233.    case WM_COMMAND: if (LOWORD(wParam) == 1) OpenFileDialog(hwnd); if (LOWORD(wParam) == 2) PostQuitMessage(0); return 0;
  234.    case WM_DESTROY: PostQuitMessage(0); return 0;
  235.    }
  236.    return DefWindowProc(hwnd, uMsg, wParam, lParam);
  237. }
  238.  
  239. void OpenFileDialog(HWND hwnd) {
  240.    WCHAR fileName[MAX_PATH] = L"";
  241.    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 };
  242.    if (GetOpenFileNameW(&ofn)) {
  243.        SetWindowTextW(g_hEditControl, L"");
  244.        g_OutputText.str(L"");
  245.        g_OutputText.clear();
  246.        AnalyzePEFile(ofn.lpstrFile);
  247.        UpdateEditControl();
  248.    }
  249. }
  250.  
  251. class FileMapper {
  252. private:
  253.    HANDLE hFile = INVALID_HANDLE_VALUE;
  254.    HANDLE hMapping = nullptr;
  255.    LPVOID lpView = nullptr;
  256.  
  257. public:
  258.    ~FileMapper() {
  259.        if (lpView) UnmapViewOfFile(lpView);
  260.        if (hMapping) CloseHandle(hMapping);
  261.        if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
  262.    }
  263.  
  264.    bool Initialize(const wchar_t* path) {
  265.        hFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, nullptr,
  266.            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  267.        if (hFile == INVALID_HANDLE_VALUE) return false;
  268.  
  269.        hMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr);
  270.        if (!hMapping) return false;
  271.  
  272.        lpView = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
  273.        return lpView != nullptr;
  274.    }
  275.  
  276.    LPVOID GetView() const { return lpView; }
  277. };
  278.  
  279. // Modified AppendToOutput to handle newlines properly:
  280. void AppendToOutput(const wchar_t* format, ...) {
  281.    std::vector<wchar_t> buffer(1024);
  282.    va_list args;
  283.    va_start(args, format);
  284.  
  285.    while (true) {
  286.        int result = _vsnwprintf(buffer.data(), buffer.size(), format, args);
  287.        if (result >= 0) break;
  288.        buffer.resize(buffer.size() * 2);
  289.    }
  290.    va_end(args);
  291.  
  292.    // Convert \n to \r\n
  293.    std::wstring output = buffer.data();
  294.    size_t pos = 0;
  295.    while ((pos = output.find(L'\n', pos)) != std::wstring::npos) {
  296.        if (pos == 0 || output[pos - 1] != L'\r') {
  297.            output.insert(pos, L"\r");
  298.            pos += 2;
  299.        }
  300.        else {
  301.            pos++;
  302.        }
  303.    }
  304.  
  305.    g_OutputText << output;
  306.    UpdateEditControl();
  307. }
  308.  
  309. /*
  310. void AppendToOutput(const wchar_t* format, ...) {
  311.    wchar_t buffer[16384]; // Ensure sufficient buffer size
  312.    va_list args;
  313.    va_start(args, format);
  314.    StringCchVPrintfW(buffer, ARRAYSIZE(buffer), format, args);
  315.    va_end(args);
  316.  
  317.    tempBuffer += buffer;
  318.  
  319.    // Update Edit Control periodically to improve performance
  320.    if (tempBuffer.size() > 8000) {
  321.        g_OutputText << tempBuffer;
  322.        tempBuffer.clear();
  323.  
  324.        SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  325.        SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  326.        SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  327.    }
  328. }
  329.  
  330.  
  331. // Final update to flush any remaining content
  332. void FlushOutput() {
  333.    if (!tempBuffer.empty()) {
  334.        g_OutputText << tempBuffer;
  335.        tempBuffer.clear();
  336.  
  337.        SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  338.        SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  339.        SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  340.    }
  341. }
  342. */
  343.  
  344.  
  345. /*
  346. //use below ^^ ALWAYS
  347. void AppendToOutput(const wchar_t* format, ...) {
  348.    va_list args;
  349.    va_start(args, format);
  350.  
  351.    // Use a vector as a dynamically resizable buffer
  352.    std::vector<wchar_t> buffer(16384); // Start with an initial size
  353.    int result = -1;
  354.  
  355.    while (true) {
  356.        // Attempt to format the string
  357.        result = _vsnwprintf(buffer.data(), buffer.size(), format, args);
  358.  
  359.        if (result >= 0 && static_cast<size_t>(result) < buffer.size()) {
  360.            // Successfully formatted within the current buffer size
  361.            break;
  362.        }
  363.  
  364.        // Resize the buffer and try again
  365.        buffer.resize(buffer.size() * 2);
  366.    }
  367.    va_end(args);
  368.  
  369.    // Convert `\n` to `\r\n` for proper display in the EditBox
  370.    std::wstring formattedOutput(buffer.data());
  371.    size_t pos = 0;
  372.    while ((pos = formattedOutput.find(L'\n', pos)) != std::wstring::npos) {
  373.        formattedOutput.replace(pos, 1, L"\r\n");
  374.        pos += 2; // Move past the replacement
  375.    }
  376.  
  377.    // Append to the global output buffer
  378.    g_OutputText << formattedOutput;
  379.  
  380.    // Update the EditBox periodically to prevent overloading
  381.    if (g_OutputText.str().size() > 8000) {
  382.        SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  383.        SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  384.        SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  385.    }
  386. }
  387. //use above ^^ ALWAYS
  388. */
  389.  
  390. //currentlatest
  391. /*void AppendToOutput(const wchar_t* format, ...) {
  392.    wchar_t buffer[4096];
  393.    va_list args;
  394.    va_start(args, format);
  395.    StringCchVPrintfW(buffer, ARRAYSIZE(buffer), format, args);
  396.    va_end(args);
  397.    g_OutputText << buffer;
  398.    SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  399.    SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  400.    SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  401. }
  402. */
  403.  
  404. //use-below-basic-failsafe-working vv
  405. //basic test function
  406. /*void AnalyzePEFile(const wchar_t* filePathW) {
  407.    OUTPUT("[+] Analyzing file: %s\n", filePathW);
  408.    LPVOID lpFileContent = GetFileContent(filePathW);
  409.    if (!lpFileContent) { OUTPUT("[-] Could not read file.\n"); return; }
  410.    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpFileContent;
  411.    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) { OUTPUT("[-] Invalid DOS signature.\n"); HeapFree(GetProcessHeap(), 0, lpFileContent); return; }
  412.    PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)lpFileContent + dosHeader->e_lfanew);
  413.    if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) { OUTPUT("[-] Invalid NT signature.\n"); HeapFree(GetProcessHeap(), 0, lpFileContent); return; }
  414.    OUTPUT("[+] PE file analyzed successfully.\n");
  415.    HeapFree(GetProcessHeap(), 0, lpFileContent);
  416.    UpdateEditControl();
  417. }*/
  418. //use-above-basic-failsafe-working vv
  419.  
  420. //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
  421.  
  422. void AnalyzePEFile(const wchar_t* filePathW) {
  423.    OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
  424.  
  425.    FileMapper mapper;
  426.    if (!mapper.Initialize(filePathW)) {
  427.        OUTPUT("[-] Failed to open file! Error: %d\r\n", GetLastError());
  428.        return;
  429.    }
  430.  
  431.    
  432.    // Open and read file
  433.    HANDLE hFile = CreateFileW(filePathW, GENERIC_READ, FILE_SHARE_READ, nullptr,
  434.        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  435.    if (hFile == INVALID_HANDLE_VALUE) {
  436.        OUTPUT("[-] Failed to open file! Error: %d\n", GetLastError());
  437.        return;
  438.    }
  439.  
  440.    DWORD fileSize = GetFileSize(hFile, nullptr);
  441.    if (fileSize == INVALID_FILE_SIZE) {
  442.        CloseHandle(hFile);
  443.        OUTPUT("[-] Failed to get file size! Error: %d\n", GetLastError());
  444.        return;
  445.    }
  446.  
  447.    HANDLE hFileMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 0, nullptr);
  448.    if (!hFileMapping) {
  449.        CloseHandle(hFile);
  450.        OUTPUT("[-] Failed to create file mapping! Error: %d\n", GetLastError());
  451.        return;
  452.    }
  453.  
  454.    LPVOID lpFileContent = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
  455.    if (!lpFileContent) {
  456.        CloseHandle(hFileMapping);
  457.        CloseHandle(hFile);
  458.        OUTPUT("[-] Failed to map view of file! Error: %d\n", GetLastError());
  459.        return;
  460.    }
  461.  
  462.    const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(mapper.GetView());
  463.    if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
  464.        OUTPUT("[-] Invalid DOS signature!\r\n");
  465.        return;
  466.    }
  467.  
  468.    const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
  469.        static_cast<BYTE*>(mapper.GetView()) + pImageDosHeader->e_lfanew);
  470.    if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
  471.        OUTPUT("[-] Invalid NT signature!\r\n");
  472.        return;
  473.    }
  474.  
  475.    // Print File Header Information
  476.    OUTPUT("[+] PE FILE HEADER\n");
  477.    OUTPUT("\tMachine: 0x%X\n", pImageNtHeaders->FileHeader.Machine);
  478.    OUTPUT("\tNumberOfSections: 0x%X\n", pImageNtHeaders->FileHeader.NumberOfSections);
  479.    OUTPUT("\tTimeDateStamp: 0x%X\n", pImageNtHeaders->FileHeader.TimeDateStamp);
  480.    OUTPUT("\tPointerToSymbolTable: 0x%X\r\n",
  481.        static_cast<DWORD>(pImageNtHeaders->FileHeader.PointerToSymbolTable));
  482.    OUTPUT("\tNumberOfSymbols: 0x%X\r\n",
  483.        static_cast<DWORD>(pImageNtHeaders->FileHeader.NumberOfSymbols));
  484.    OUTPUT("\tSizeOfOptionalHeader: 0x%X\r\n",
  485.        static_cast<DWORD>(pImageNtHeaders->FileHeader.SizeOfOptionalHeader));
  486.    OUTPUT("\tCharacteristics: 0x%X %s\n\n",
  487.        pImageNtHeaders->FileHeader.Characteristics,
  488.        PEHelpers::GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics).c_str());
  489.  
  490.    // Print Optional Header Information
  491.    OUTPUT("[+] PE OPTIONAL HEADER\n");
  492.    OUTPUT("\tMagic: 0x%X\n", pImageNtHeaders->OptionalHeader.Magic);
  493.    OUTPUT("\tAddressOfEntryPoint: 0x%X\n", pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
  494.    OUTPUT("\tImageBase: 0x%llX\n", (ULONGLONG)pImageNtHeaders->OptionalHeader.ImageBase);
  495.    OUTPUT("\tSectionAlignment: 0x%X\n", pImageNtHeaders->OptionalHeader.SectionAlignment);
  496.    OUTPUT("\tFileAlignment: 0x%X\n", pImageNtHeaders->OptionalHeader.FileAlignment);
  497.    
  498.    // Added missing Optional Header fields
  499.    OUTPUT("\tMajorOperatingSystemVersion: 0x%X\r\n",
  500.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion));
  501.    OUTPUT("\tMinorOperatingSystemVersion: 0x%X\r\n",
  502.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion));
  503.    OUTPUT("\tMajorImageVersion: 0x%X\r\n",
  504.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorImageVersion));
  505.    OUTPUT("\tMinorImageVersion: 0x%X\r\n",
  506.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorImageVersion));
  507.    OUTPUT("\tMajorSubsystemVersion: 0x%X\r\n",
  508.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MajorSubsystemVersion));
  509.    OUTPUT("\tMinorSubsystemVersion: 0x%X\r\n",
  510.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.MinorSubsystemVersion));
  511.    OUTPUT("\tWin32VersionValue: 0x%X\r\n",
  512.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.Win32VersionValue));
  513.    OUTPUT("\tSizeOfImage: 0x%X\r\n",
  514.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.SizeOfImage));
  515.    OUTPUT("\tSizeOfHeaders: 0x%X\r\n",
  516.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.SizeOfHeaders));
  517.    OUTPUT("\tCheckSum: 0x%X\r\n",
  518.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.CheckSum));
  519.    OUTPUT("\tSubsystem: 0x%X %s\r\n",
  520.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.Subsystem),
  521.        PEHelpers::GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem).c_str());
  522.    OUTPUT("\tDllCharacteristics: 0x%X\r\n",
  523.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.DllCharacteristics));
  524.    OUTPUT("\tSizeOfStackReserve: 0x%llX\r\n",
  525.        static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfStackReserve));
  526.    OUTPUT("\tSizeOfStackCommit: 0x%llX\r\n",
  527.        static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfStackCommit));
  528.    OUTPUT("\tSizeOfHeapReserve: 0x%llX\r\n",
  529.        static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfHeapReserve));
  530.    OUTPUT("\tSizeOfHeapCommit: 0x%llX\r\n",
  531.        static_cast<ULONGLONG>(pImageNtHeaders->OptionalHeader.SizeOfHeapCommit));
  532.    OUTPUT("\tLoaderFlags: 0x%X\r\n",
  533.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.LoaderFlags));
  534.    OUTPUT("\tNumberOfRvaAndSizes: 0x%X\r\n\r\n",
  535.        static_cast<DWORD>(pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes));
  536.    
  537.    OUTPUT("\tSubsystem: 0x%X %s\n\n",
  538.        pImageNtHeaders->OptionalHeader.Subsystem,
  539.        PEHelpers::GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem).c_str());
  540.  
  541.    // Print Data Directories
  542.    OUTPUT("[+] PE DATA DIRECTORIES\n");
  543.    for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
  544.        const auto& dir = pImageNtHeaders->OptionalHeader.DataDirectory[i];
  545.        if (dir.VirtualAddress != 0) {
  546.            OUTPUT("\t%s:\n", PEHelpers::GetDataDirectoryName(i).c_str());
  547.            OUTPUT("\t\tVirtualAddress: 0x%X\n", dir.VirtualAddress);
  548.            OUTPUT("\t\tSize: 0x%X\n", dir.Size);
  549.        }
  550.    }
  551.  
  552.    // Analyze Sections
  553.    OUTPUT("\n[+] PE IMAGE SECTIONS\r\n");
  554.    auto pSection = IMAGE_FIRST_SECTION(pImageNtHeaders);
  555.    for (WORD i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++, pSection++) {
  556.        // Create a null-terminated string from the section name
  557.        char sectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
  558.        memcpy(sectionName, pSection->Name, IMAGE_SIZEOF_SHORT_NAME);
  559.  
  560.        // Remove any non-printable characters
  561.        for (int j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) {
  562.            if (!isprint(static_cast<unsigned char>(sectionName[j]))) {
  563.                sectionName[j] = '\0';
  564.            }
  565.        }
  566.  
  567.        // Convert to wide string
  568.        wchar_t wideSectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
  569.        MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  570.            sectionName, -1,
  571.            wideSectionName, IMAGE_SIZEOF_SHORT_NAME + 1);
  572.  
  573.        OUTPUT("\tSECTION : %s\r\n", wideSectionName);
  574.        OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\r\n", pSection->Misc.PhysicalAddress);
  575.        OUTPUT("\t\tMisc (VirtualSize) : 0x%X\r\n", pSection->Misc.VirtualSize);
  576.        OUTPUT("\t\tVirtualAddress : 0x%X\r\n", pSection->VirtualAddress);
  577.        OUTPUT("\t\tSizeOfRawData : 0x%X\r\n", pSection->SizeOfRawData);
  578.        OUTPUT("\t\tPointerToRawData : 0x%X\r\n", pSection->PointerToRawData);
  579.        OUTPUT("\t\tPointerToRelocations : 0x%X\r\n", pSection->PointerToRelocations);
  580.        OUTPUT("\t\tPointerToLinenumbers : 0x%X\r\n", pSection->PointerToLinenumbers);
  581.        OUTPUT("\t\tNumberOfRelocations : 0x%X\r\n", pSection->NumberOfRelocations);
  582.        OUTPUT("\t\tNumberOfLinenumbers : 0x%X\r\n", pSection->NumberOfLinenumbers);
  583.        OUTPUT("\t\tCharacteristics : 0x%X %s\r\n\r\n",
  584.            pSection->Characteristics,
  585.            PEHelpers::GetSectionProtection(pSection->Characteristics).c_str());
  586.    }
  587.  
  588.    // Analyze Imports
  589.    const auto& importDir = pImageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
  590.    if (importDir.VirtualAddress && importDir.Size) {
  591.        OUTPUT("\n[+] IMPORTED DLLS AND FUNCTIONS\r\n");
  592.  
  593.        // Find the section containing imports
  594.        auto pSection = IMAGE_FIRST_SECTION(pImageNtHeaders);
  595.        PIMAGE_SECTION_HEADER pImportSection = nullptr;
  596.  
  597.        // Find the import section
  598.        for (WORD i = 0; i < pImageNtHeaders->FileHeader.NumberOfSections; i++, pSection++) {
  599.            if (importDir.VirtualAddress >= pSection->VirtualAddress &&
  600.                importDir.VirtualAddress < (pSection->VirtualAddress + pSection->Misc.VirtualSize)) {
  601.                pImportSection = pSection;
  602.                break;
  603.            }
  604.        }
  605.  
  606.        if (!pImportSection) {
  607.            OUTPUT("[-] Could not find import section\r\n");
  608.            return;
  609.        }
  610.  
  611.        // Get the import descriptor
  612.        auto pImportDesc = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
  613.            (BYTE*)lpFileContent +
  614.            pImportSection->PointerToRawData +
  615.            (importDir.VirtualAddress - pImportSection->VirtualAddress));
  616.  
  617.        // Process all DLLs
  618.        while (pImportDesc && pImportDesc->Name != 0) {
  619.            // Get DLL name
  620.            const char* dllName = reinterpret_cast<const char*>(
  621.                (BYTE*)lpFileContent +
  622.                pImportSection->PointerToRawData +
  623.                (pImportDesc->Name - pImportSection->VirtualAddress));
  624.  
  625.            if (!IsBadReadPtr(dllName, 1)) {
  626.                std::vector<wchar_t> wideDllName(MAX_PATH);
  627.                MultiByteToWideChar(CP_ACP, 0, dllName, -1,
  628.                    wideDllName.data(), MAX_PATH);
  629.  
  630.                // Print DLL information
  631.                OUTPUT("\n\tDLL NAME : %s\r\n", wideDllName.data());
  632.                OUTPUT("\tCharacteristics : 0x%X\r\n", pImportDesc->Characteristics);
  633.                OUTPUT("\tOriginalFirstThunk : 0x%X\r\n", pImportDesc->OriginalFirstThunk);
  634.                OUTPUT("\tTimeDateStamp : 0x%X\r\n", pImportDesc->TimeDateStamp);
  635.                OUTPUT("\tForwarderChain : 0x%X\r\n", pImportDesc->ForwarderChain);
  636.                OUTPUT("\tFirstThunk : 0x%X\r\n", pImportDesc->FirstThunk);
  637.  
  638.                OUTPUT("\n\tImported Functions :\r\n\r\n");
  639.  
  640.                // Process functions using OriginalFirstThunk
  641.                if (pImportDesc->OriginalFirstThunk) {
  642.                    auto pThunk = reinterpret_cast<PIMAGE_THUNK_DATA>(
  643.                        (BYTE*)lpFileContent +
  644.                        pImportSection->PointerToRawData +
  645.                        (pImportDesc->OriginalFirstThunk - pImportSection->VirtualAddress));
  646.  
  647.                    // Process all functions for this DLL
  648.                    while (pThunk && pThunk->u1.AddressOfData) {
  649.                        if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG)) {
  650.                            auto pImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(
  651.                                (BYTE*)lpFileContent +
  652.                                pImportSection->PointerToRawData +
  653.                                (pThunk->u1.AddressOfData - pImportSection->VirtualAddress));
  654.  
  655.                            if (!IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
  656.                                std::vector<wchar_t> wideFuncName(MAX_PATH);
  657.                                MultiByteToWideChar(CP_ACP, 0,
  658.                                    reinterpret_cast<const char*>(pImportByName->Name),
  659.                                    -1, wideFuncName.data(), MAX_PATH);
  660.  
  661.                                OUTPUT("\t\t%s\r\n", wideFuncName.data());
  662.                            }
  663.                        }
  664.                        pThunk++;
  665.                    }
  666.                }
  667.            }
  668.            pImportDesc++;
  669.        }
  670.    }
  671.  
  672. cleanup:
  673.    if (lpFileContent) {
  674.        UnmapViewOfFile(lpFileContent);
  675.    }
  676.    if (hFileMapping) {
  677.        CloseHandle(hFileMapping);
  678.    }
  679.    if (hFile) {
  680.        CloseHandle(hFile);
  681.    }
  682.  
  683.    UpdateEditControl();
  684. }
  685.  
  686. /*
  687. //use below vv ALWAYS
  688. void AnalyzePEFile(const wchar_t* filePathW) {
  689.    OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
  690.  
  691.    LPVOID lpFileContent = GetFileContent(filePathW);
  692.    if (!lpFileContent) {
  693.        OUTPUT("[-] Failed to read file content!\n");
  694.        return;
  695.    }
  696.  
  697.    const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileContent);
  698.    if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
  699.        OUTPUT("[-] Invalid DOS signature!\n");
  700.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  701.        return;
  702.    }
  703.  
  704.    const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>((DWORD_PTR)lpFileContent + pImageDosHeader->e_lfanew);
  705.    if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
  706.        OUTPUT("[-] Invalid NT signature!\n");
  707.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  708.        return;
  709.    }
  710.  
  711.    //UpdateEditControl(); //added just now remove line!
  712.  
  713.    OUTPUT("[+] PE FILE HEADER\n");
  714.    OUTPUT("\tMachine : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.Machine);
  715.    OUTPUT("\tNumberOfSections : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSections);
  716.    OUTPUT("\tTimeDateStamp : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.TimeDateStamp);
  717.    OUTPUT("\tPointerToSymbolTable : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.PointerToSymbolTable);
  718.    OUTPUT("\tNumberOfSymbols : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSymbols);
  719.    OUTPUT("\tSizeOfOptionalHeader : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.SizeOfOptionalHeader);
  720.    OUTPUT("\tCharacteristics : 0x%X %s\n\n", (uintptr_t)pImageNtHeaders->FileHeader.Characteristics, GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics));
  721.  
  722.    OUTPUT("[+] PE OPTIONAL HEADER\n");
  723.    OUTPUT("\tMagic : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Magic);
  724.    OUTPUT("\tAddressOfEntryPoint : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
  725.    OUTPUT("\tImageBase : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.ImageBase);
  726.    OUTPUT("\tSectionAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SectionAlignment);
  727.    OUTPUT("\tFileAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.FileAlignment);
  728.    OUTPUT("\tMajorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
  729.    OUTPUT("\tMinorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
  730.    OUTPUT("\tMajorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorImageVersion);
  731.    OUTPUT("\tMinorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorImageVersion);
  732.    OUTPUT("\tMajorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorSubsystemVersion);
  733.    OUTPUT("\tMinorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorSubsystemVersion);
  734.    OUTPUT("\tWin32VersionValue : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Win32VersionValue);
  735.    OUTPUT("\tSizeOfImage : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfImage);
  736.    OUTPUT("\tSizeOfHeaders : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeaders);
  737.    OUTPUT("\tCheckSum : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.CheckSum);
  738.    OUTPUT("\tSubsystem : 0x%X %s\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Subsystem, GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem));
  739.    OUTPUT("\tDllCharacteristics : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.DllCharacteristics);
  740.    OUTPUT("\tSizeOfStackReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackReserve);
  741.    OUTPUT("\tSizeOfStackCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackCommit);
  742.    OUTPUT("\tSizeOfHeapReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapReserve);
  743.    OUTPUT("\tSizeOfHeapCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapCommit);
  744.    OUTPUT("\tLoaderFlags : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.LoaderFlags);
  745.    OUTPUT("\tNumberOfRvaAndSizes : 0x%X\n\n", (uintptr_t)pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes);
  746.  
  747.    //UpdateEditControl(); //added just now remove line!
  748.  
  749.    GetDataDirectories(&pImageNtHeaders->OptionalHeader.DataDirectory[0]);
  750.  
  751.    const auto pImageSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>((DWORD_PTR)pImageNtHeaders + sizeof(IMAGE_NT_HEADERS));
  752.    const auto pImageImportSection = GetSections(pImageSectionHeader, pImageNtHeaders->FileHeader.NumberOfSections, pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress);
  753.  
  754.    if (!pImageImportSection) {
  755.        OUTPUT("[-] Error: Could not find import section!\n");
  756.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  757.        return;
  758.    }
  759.  
  760.    const auto pImageImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>((DWORD_PTR)lpFileContent + pImageImportSection->PointerToRawData);
  761.    if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386) {
  762.        GetImports32(pImageImportDescriptor, (DWORD)lpFileContent + pImageImportSection->PointerToRawData, pImageImportSection);
  763.    }
  764.    else if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64) {
  765.        GetImports64(pImageImportDescriptor, (DWORD)lpFileContent + pImageImportSection->PointerToRawData, pImageImportSection);
  766.    }
  767.    else {
  768.        OUTPUT("[-] Unsupported architecture!\n");
  769.    }
  770.  
  771.    HeapFree(GetProcessHeap(), 0, lpFileContent);
  772.    UpdateEditControl();
  773. }
  774.  
  775. void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory) {
  776.    OUTPUT("[+] PE DATA DIRECTORIES\n");
  777.    for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i, ++pImageDataDirectory) {
  778.        if (pImageDataDirectory->VirtualAddress == 0) continue;
  779.        OUTPUT("\tDataDirectory (%s) VirtualAddress : 0x%X\n", GetDataDirectoryName(i), (uintptr_t)pImageDataDirectory->VirtualAddress);
  780.        OUTPUT("\tDataDirectory (%s) Size : 0x%X\n\n", GetDataDirectoryName(i), (uintptr_t)pImageDataDirectory->Size);
  781.    }
  782. }
  783.  
  784. PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader, int NumberOfSections, DWORD dImportAddress) {
  785.    PIMAGE_SECTION_HEADER pImageImportHeader = nullptr;
  786.    OUTPUT("\n[+] PE IMAGE SECTIONS\n");
  787.    for (int i = 0; i < NumberOfSections; ++i) {
  788.        const auto pCurrentSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>((DWORD_PTR)pImageSectionHeader + i * sizeof(IMAGE_SECTION_HEADER));
  789.        OUTPUT("\n\tSECTION : %s\n", (wchar_t*)pCurrentSectionHeader->Name);
  790.        OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\n", (uintptr_t)pCurrentSectionHeader->Misc.PhysicalAddress);
  791.        OUTPUT("\t\tMisc (VirtualSize) : 0x%X\n", (uintptr_t)pCurrentSectionHeader->Misc.VirtualSize);
  792.        OUTPUT("\t\tVirtualAddress : 0x%X\n", (uintptr_t)pCurrentSectionHeader->VirtualAddress);
  793.        OUTPUT("\t\tSizeOfRawData : 0x%X\n", (uintptr_t)pCurrentSectionHeader->SizeOfRawData);
  794.        OUTPUT("\t\tPointerToRawData : 0x%X\n", (uintptr_t)pCurrentSectionHeader->PointerToRawData);
  795.        OUTPUT("\t\tCharacteristics : 0x%X %s\n", (uintptr_t)pCurrentSectionHeader->Characteristics, GetSectionProtection(pCurrentSectionHeader->Characteristics));
  796.  
  797.        if (dImportAddress >= pCurrentSectionHeader->VirtualAddress && dImportAddress < pCurrentSectionHeader->VirtualAddress + pCurrentSectionHeader->Misc.VirtualSize) {
  798.            pImageImportHeader = pCurrentSectionHeader;
  799.        }
  800.    }
  801.    return pImageImportHeader;
  802. }
  803.  
  804. void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor, DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection) {
  805.    OUTPUT("\n[+] IMPORTED DLL\n");
  806.    while (pImageImportDescriptor->Name != 0) {
  807.        OUTPUT("\n\tDLL NAME : %s\n", (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  808.        if (pImageImportDescriptor->OriginalFirstThunk == 0) {
  809.            ++pImageImportDescriptor;
  810.            continue;
  811.        }
  812.        auto pOriginalFirstThunk = reinterpret_cast<PIMAGE_THUNK_DATA32>(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  813.        while (pOriginalFirstThunk->u1.AddressOfData != 0) {
  814.            const auto pImageImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(dRawOffset + (pOriginalFirstThunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  815.            if (pImageImportByName) {
  816.                OUTPUT("\t\tFunction: %s\n", (char*)pImageImportByName->Name);
  817.            }
  818.            pOriginalFirstThunk++;
  819.        }
  820.        pImageImportDescriptor++;
  821.    }
  822. }
  823.  
  824. void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor, DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection) {
  825.    OUTPUT("\n[+] IMPORTED DLL\n");
  826.    while (pImageImportDescriptor->Name != 0) {
  827.        OUTPUT("\n\tDLL NAME : %s\n", (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  828.        if (pImageImportDescriptor->OriginalFirstThunk == 0) {
  829.            ++pImageImportDescriptor;
  830.            continue;
  831.        }
  832.        auto pOriginalFirstThunk = reinterpret_cast<PIMAGE_THUNK_DATA64>(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  833.        while (pOriginalFirstThunk->u1.AddressOfData != 0) {
  834.            const auto pImageImportByName = reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(dRawOffset + (pOriginalFirstThunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  835.            if (pImageImportByName) {
  836.                OUTPUT("\t\tFunction: %s\n", (char*)pImageImportByName->Name);
  837.            }
  838.            pOriginalFirstThunk++;
  839.        }
  840.        pImageImportDescriptor++;
  841.    }
  842. }
  843. //use above ^^ ALWAYS
  844. */
  845.  
  846.  
  847. /*
  848. // older-orig-deprecated vv
  849. // Main PE Analysis function
  850. void AnalyzePEFile(const wchar_t* filePathW)
  851. {
  852.    //WCHAR filePathW[MAX_PATH];
  853.    //MultiByteToWideChar(CP_ACP, 0, filePathA, -1, filePathW, MAX_PATH);
  854.    OUTPUT("[+] Starting PE Analysis for: %s\n\n", filePathW);
  855.    //AppendToOutput(L"[+] Starting PE Analysis for: %ls\n\n", filePathW);
  856.  
  857.    // Get file content
  858.    LPVOID lpFileContent = GetFileContent(filePathW);
  859.    if (!lpFileContent)
  860.    {
  861.        OUTPUT("[-] Failed to read file content!\n");
  862.        return;
  863.    }
  864.  
  865.    // Get DOS header
  866.    const auto pImageDosHeader = static_cast<PIMAGE_DOS_HEADER>(lpFileContent);
  867.    if (pImageDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
  868.    {
  869.        OUTPUT("[-] Invalid DOS signature!\n");
  870.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  871.        return;
  872.    }
  873.  
  874.    // Get NT headers
  875.    const auto pImageNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>((DWORD_PTR)lpFileContent + pImageDosHeader->e_lfanew);
  876.    if (pImageNtHeaders->Signature != IMAGE_NT_SIGNATURE)
  877.    {
  878.        OUTPUT("[-] Invalid NT signature!\n");
  879.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  880.        return;
  881.    }
  882.  
  883.    // Display File Header information
  884.    OUTPUT("[+] PE FILE HEADER\n");
  885.    OUTPUT("\tMachine : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.Machine);
  886.    OUTPUT("\tNumberOfSections : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSections);
  887.    OUTPUT("\tTimeDateStamp : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.TimeDateStamp);
  888.    OUTPUT("\tPointerToSymbolTable : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.PointerToSymbolTable);
  889.    OUTPUT("\tNumberOfSymbols : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.NumberOfSymbols);
  890.    OUTPUT("\tSizeOfOptionalHeader : 0x%X\n", (uintptr_t)pImageNtHeaders->FileHeader.SizeOfOptionalHeader);
  891.    OUTPUT("\tCharacteristics : 0x%X %s\n\n",
  892.        (uintptr_t)pImageNtHeaders->FileHeader.Characteristics,
  893.        GetImageCharacteristics(pImageNtHeaders->FileHeader.Characteristics));
  894.  
  895.    // Display Optional Header information
  896.    OUTPUT("[+] PE OPTIONAL HEADER\n");
  897.    OUTPUT("\tMagic : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Magic);
  898.    OUTPUT("\tAddressOfEntryPoint : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.AddressOfEntryPoint);
  899.    OUTPUT("\tImageBase : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.ImageBase);
  900.    OUTPUT("\tSectionAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SectionAlignment);
  901.    OUTPUT("\tFileAlignment : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.FileAlignment);
  902.    OUTPUT("\tMajorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorOperatingSystemVersion);
  903.    OUTPUT("\tMinorOperatingSystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorOperatingSystemVersion);
  904.    OUTPUT("\tMajorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorImageVersion);
  905.    OUTPUT("\tMinorImageVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorImageVersion);
  906.    OUTPUT("\tMajorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MajorSubsystemVersion);
  907.    OUTPUT("\tMinorSubsystemVersion : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.MinorSubsystemVersion);
  908.    OUTPUT("\tWin32VersionValue : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.Win32VersionValue);
  909.    OUTPUT("\tSizeOfImage : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfImage);
  910.    OUTPUT("\tSizeOfHeaders : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeaders);
  911.    OUTPUT("\tCheckSum : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.CheckSum);
  912.    OUTPUT("\tSubsystem : 0x%X %s\n",
  913.        (uintptr_t)pImageNtHeaders->OptionalHeader.Subsystem,
  914.        GetSubsystem(pImageNtHeaders->OptionalHeader.Subsystem));
  915.    OUTPUT("\tDllCharacteristics : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.DllCharacteristics);
  916.    OUTPUT("\tSizeOfStackReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackReserve);
  917.    OUTPUT("\tSizeOfStackCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfStackCommit);
  918.    OUTPUT("\tSizeOfHeapReserve : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapReserve);
  919.    OUTPUT("\tSizeOfHeapCommit : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.SizeOfHeapCommit);
  920.    OUTPUT("\tLoaderFlags : 0x%X\n", (uintptr_t)pImageNtHeaders->OptionalHeader.LoaderFlags);
  921.    OUTPUT("\tNumberOfRvaAndSizes : 0x%X\n\n", (uintptr_t)pImageNtHeaders->OptionalHeader.NumberOfRvaAndSizes);
  922.  
  923.    // Get Data Directories
  924.    GetDataDirectories(&pImageNtHeaders->OptionalHeader.DataDirectory[0]);
  925.  
  926.    // Get the import section
  927.    const auto pImageSectionHeader = reinterpret_cast<PIMAGE_SECTION_HEADER>(
  928.        (DWORD_PTR)pImageNtHeaders + sizeof(IMAGE_NT_HEADERS));
  929.  
  930.    const auto pImageImportSection = GetSections(
  931.        pImageSectionHeader,
  932.        pImageNtHeaders->FileHeader.NumberOfSections,
  933.        pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress);
  934.  
  935.    if (!pImageImportSection)
  936.    {
  937.        OUTPUT("[-] Error: Could not find import section!\n");
  938.        HeapFree(GetProcessHeap(), 0, lpFileContent);
  939.        return;
  940.    }
  941.  
  942.    // Get imports based on architecture
  943.    const auto pImageImportDescriptor = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(
  944.        (DWORD_PTR)lpFileContent + pImageImportSection->PointerToRawData);
  945.  
  946.    if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_I386)
  947.    {
  948.        GetImports32(
  949.            pImageImportDescriptor,
  950.            (DWORD)lpFileContent + pImageImportSection->PointerToRawData,
  951.            pImageImportSection);
  952.    }
  953.    else if (pImageNtHeaders->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
  954.    {
  955.        GetImports64(
  956.            pImageImportDescriptor,
  957.            (DWORD)lpFileContent + pImageImportSection->PointerToRawData,
  958.            pImageImportSection);
  959.    }
  960.    else
  961.    {
  962.        OUTPUT("[-] Unsupported architecture!\n");
  963.    }
  964.  
  965.    // Cleanup
  966.    HeapFree(GetProcessHeap(), 0, lpFileContent);
  967.  
  968.    // Update the GUI with the analysis results
  969.    UpdateEditControl();
  970. }
  971.  
  972. void GetDataDirectories(PIMAGE_DATA_DIRECTORY pImageDataDirectory)
  973. {
  974.    OUTPUT("[+] PE DATA DIRECTORIES\n");
  975.    for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; ++i, ++pImageDataDirectory)
  976.    {
  977.        if (pImageDataDirectory->VirtualAddress == 0)
  978.            continue;
  979.  
  980.        OUTPUT("\tDataDirectory (%s) VirtualAddress : 0x%X\n",
  981.            GetDataDirectoryName(i),
  982.            (uintptr_t)pImageDataDirectory->VirtualAddress);
  983.        OUTPUT("\tDataDirectory (%s) Size : 0x%X\n\n",
  984.            GetDataDirectoryName(i),
  985.            (uintptr_t)pImageDataDirectory->Size);
  986.    }
  987. }
  988.  
  989. PIMAGE_SECTION_HEADER GetSections(const PIMAGE_SECTION_HEADER pImageSectionHeader,
  990.    int NumberOfSections, DWORD dImportAddress)
  991. {
  992.    PIMAGE_SECTION_HEADER pImageImportHeader = nullptr;
  993.  
  994.    OUTPUT("\n[+] PE IMAGE SECTIONS\n");
  995.  
  996.    for (int i = 0; i < NumberOfSections; ++i)
  997.    {
  998.        const auto pCurrentSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)pImageSectionHeader +
  999.            i * sizeof(IMAGE_SECTION_HEADER));
  1000.  
  1001.        OUTPUT("\n\tSECTION : %s\n", (wchar_t*)pCurrentSectionHeader->Name);
  1002.        OUTPUT("\t\tMisc (PhysicalAddress) : 0x%X\n",
  1003.            (uintptr_t)pCurrentSectionHeader->Misc.PhysicalAddress);
  1004.        OUTPUT("\t\tMisc (VirtualSize) : 0x%X\n",
  1005.            (uintptr_t)pCurrentSectionHeader->Misc.VirtualSize);
  1006.        OUTPUT("\t\tVirtualAddress : 0x%X\n",
  1007.            (uintptr_t)pCurrentSectionHeader->VirtualAddress);
  1008.        OUTPUT("\t\tSizeOfRawData : 0x%X\n",
  1009.            (uintptr_t)pCurrentSectionHeader->SizeOfRawData);
  1010.        OUTPUT("\t\tPointerToRawData : 0x%X\n",
  1011.            (uintptr_t)pCurrentSectionHeader->PointerToRawData);
  1012.        OUTPUT("\t\tPointerToRelocations : 0x%X\n",
  1013.            (uintptr_t)pCurrentSectionHeader->PointerToRelocations);
  1014.        OUTPUT("\t\tPointerToLinenumbers : 0x%X\n",
  1015.            (uintptr_t)pCurrentSectionHeader->PointerToLinenumbers);
  1016.        OUTPUT("\t\tNumberOfRelocations : 0x%X\n",
  1017.            (uintptr_t)pCurrentSectionHeader->NumberOfRelocations);
  1018.        OUTPUT("\t\tNumberOfLinenumbers : 0x%X\n",
  1019.            (uintptr_t)pCurrentSectionHeader->NumberOfLinenumbers);
  1020.        OUTPUT("\t\tCharacteristics : 0x%X %s\n",
  1021.            (uintptr_t)pCurrentSectionHeader->Characteristics,
  1022.            GetSectionProtection(pCurrentSectionHeader->Characteristics));
  1023.  
  1024.        if (dImportAddress >= pCurrentSectionHeader->VirtualAddress &&
  1025.            dImportAddress < pCurrentSectionHeader->VirtualAddress +
  1026.            pCurrentSectionHeader->Misc.VirtualSize)
  1027.        {
  1028.            pImageImportHeader = pCurrentSectionHeader;
  1029.        }
  1030.    }
  1031.  
  1032.    return pImageImportHeader;
  1033. }
  1034. void GetImports32(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
  1035.    DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection)
  1036. {
  1037.    OUTPUT("\n[+] IMPORTED DLL\n");
  1038.  
  1039.    while (pImageImportDescriptor->Name != 0)
  1040.    {
  1041.        OUTPUT("\n\tDLL NAME : %s\n",
  1042.            (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  1043.        OUTPUT("\tCharacteristics : 0x%X\n",
  1044.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->Characteristics - pImageImportSection->VirtualAddress)));
  1045.        OUTPUT("\tOriginalFirstThunk : 0x%X\n",
  1046.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress)));
  1047.        OUTPUT("\tTimeDateStamp : 0x%X\n",
  1048.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->TimeDateStamp - pImageImportSection->VirtualAddress)));
  1049.        OUTPUT("\tForwarderChain : 0x%X\n",
  1050.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->ForwarderChain - pImageImportSection->VirtualAddress)));
  1051.        OUTPUT("\tFirstThunk : 0x%X\n",
  1052.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->FirstThunk - pImageImportSection->VirtualAddress)));
  1053.  
  1054.        if (pImageImportDescriptor->OriginalFirstThunk == 0)
  1055.        {
  1056.            ++pImageImportDescriptor;
  1057.            continue;
  1058.        }
  1059.  
  1060.        auto pOriginalFirstThrunk = (PIMAGE_THUNK_DATA32)(dRawOffset +
  1061.            (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  1062.  
  1063.        OUTPUT("\n\tImported Functions : \n\n");
  1064.  
  1065.        while (pOriginalFirstThrunk->u1.AddressOfData != 0)
  1066.        {
  1067.            if (pOriginalFirstThrunk->u1.AddressOfData >= IMAGE_ORDINAL_FLAG32)
  1068.            {
  1069.                ++pOriginalFirstThrunk;
  1070.                continue;
  1071.            }
  1072.  
  1073.            const auto pImageImportByName = (PIMAGE_IMPORT_BY_NAME)(dRawOffset +
  1074.                (pOriginalFirstThrunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  1075.  
  1076.            if (pImageImportByName == nullptr)
  1077.            {
  1078.                ++pOriginalFirstThrunk;
  1079.                continue;
  1080.            }
  1081.  
  1082.            if (pOriginalFirstThrunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)
  1083.            {
  1084.                OUTPUT("\t\t0x%X (Ordinal) : %s\n",
  1085.                    (uintptr_t)pOriginalFirstThrunk->u1.AddressOfData,
  1086.                    (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
  1087.            }
  1088.            else
  1089.            {
  1090.                OUTPUT("\t\t%s\n",
  1091.                    (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
  1092.            }
  1093.  
  1094.            ++pOriginalFirstThrunk;
  1095.        }
  1096.  
  1097.        ++pImageImportDescriptor;
  1098.    }
  1099. }
  1100.  
  1101. void GetImports64(PIMAGE_IMPORT_DESCRIPTOR pImageImportDescriptor,
  1102.    DWORD dRawOffset, const PIMAGE_SECTION_HEADER pImageImportSection)
  1103. {
  1104.    OUTPUT("\n[+] IMPORTED DLL\n");
  1105.  
  1106.    while (pImageImportDescriptor->Name != 0)
  1107.    {
  1108.        OUTPUT("\n\tDLL NAME : %s\n",
  1109.            (wchar_t*)(dRawOffset + (pImageImportDescriptor->Name - pImageImportSection->VirtualAddress)));
  1110.        OUTPUT("\tCharacteristics : 0x%X\n",
  1111.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->Characteristics - pImageImportSection->VirtualAddress)));
  1112.        OUTPUT("\tOriginalFirstThunk : 0x%X\n",
  1113.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress)));
  1114.        OUTPUT("\tTimeDateStamp : 0x%X\n",
  1115.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->TimeDateStamp - pImageImportSection->VirtualAddress)));
  1116.        OUTPUT("\tForwarderChain : 0x%X\n",
  1117.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->ForwarderChain - pImageImportSection->VirtualAddress)));
  1118.        OUTPUT("\tFirstThunk : 0x%X\n",
  1119.            (uintptr_t)(dRawOffset + (pImageImportDescriptor->FirstThunk - pImageImportSection->VirtualAddress)));
  1120.  
  1121.        if (pImageImportDescriptor->OriginalFirstThunk == 0)
  1122.        {
  1123.            ++pImageImportDescriptor;
  1124.            continue;
  1125.        }
  1126.  
  1127.        auto pOriginalFirstThrunk = (PIMAGE_THUNK_DATA64)(dRawOffset +
  1128.            (pImageImportDescriptor->OriginalFirstThunk - pImageImportSection->VirtualAddress));
  1129.  
  1130.        OUTPUT("\n\tImported Functions : \n\n");
  1131.  
  1132.        while (pOriginalFirstThrunk->u1.AddressOfData != 0)
  1133.        {
  1134.            if (pOriginalFirstThrunk->u1.AddressOfData >= IMAGE_ORDINAL_FLAG64)
  1135.            {
  1136.                ++pOriginalFirstThrunk;
  1137.                continue;
  1138.            }
  1139.  
  1140.            const auto pImageImportByName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)dRawOffset +
  1141.                (pOriginalFirstThrunk->u1.AddressOfData - pImageImportSection->VirtualAddress));
  1142.  
  1143.            if (pImageImportByName == nullptr)
  1144.            {
  1145.                ++pOriginalFirstThrunk;
  1146.                continue;
  1147.            }
  1148.  
  1149.            if (pOriginalFirstThrunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)
  1150.            {
  1151.                OUTPUT("\t\t0x%llX (Ordinal) : %s\n",
  1152.                    pOriginalFirstThrunk->u1.AddressOfData,
  1153.                    (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
  1154.            }
  1155.            else
  1156.            {
  1157.                OUTPUT("\t\t%s\n",
  1158.                    (wchar_t*)((DWORD_PTR)dRawOffset + (pImageImportByName->Name - pImageImportSection->VirtualAddress)));
  1159.            }
  1160.  
  1161.            ++pOriginalFirstThrunk;
  1162.        }
  1163.  
  1164.        ++pImageImportDescriptor;
  1165.    }
  1166. }
  1167. // older-orig-deprecated ^^
  1168. */
  1169.  
  1170. //filePathW
  1171. //lpFilePath
  1172. HANDLE GetFileContent(const wchar_t* lpFilePath) {
  1173.    HANDLE hFile = CreateFileW(lpFilePath, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
  1174.    if (hFile == INVALID_HANDLE_VALUE) return nullptr;
  1175.    DWORD fileSize = GetFileSize(hFile, nullptr);
  1176.    auto lpFileContent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, fileSize);
  1177.    DWORD bytesRead;
  1178.    ReadFile(hFile, lpFileContent, fileSize, &bytesRead, nullptr);
  1179.    CloseHandle(hFile);
  1180.    return lpFileContent;
  1181. }
  1182.  
  1183. void UpdateEditControl() {
  1184.    SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  1185.    SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  1186.    SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  1187. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement