Advertisement
alien_fx_fiend

PE Header Parsing (FINAL PHASE DONE !!!) Now /e AlwaysOnTop, SelectAll Ctrl+A, Drag&Drop. IncrBuffer

Feb 18th, 2025 (edited)
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 122.96 KB | Source Code | 0 0
  1. ==++Here is the full source code (file 1/4) of PE Header Parsing App C++ GUI-based++==::
  2.  
  3. P.S: I was able to complete this project afterall, it took a great AI like o3 mini to spot the bugs & bring it to a working state, then there were Chinese characters corrupting the Output, which was handled decently by Claude3.5 Sonnet !!! o3 mini also helped me /w a strategy guide that was mindblowing !!!!!
  4.  
  5. ```main.cpp
  6. #define STRICT
  7. #define WIN32_LEAN_AND_MEAN
  8. #define DEBUG_OUTPUT(format, ...) \
  9.     do { \
  10.         OUTPUT("[DEBUG] %ls:%d - " format "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
  11.     } while(0)
  12. #ifndef OUTPUT
  13. #define OUTPUT(format, ...) wprintf(L##format, ##__VA_ARGS__)
  14. #endif
  15. #include <Windows.h>
  16. #include <winternl.h>
  17. #include <CommCtrl.h>
  18. #include <commdlg.h>
  19. #include <string>
  20. #include <strsafe.h>
  21. #include <sstream>
  22. #include <iomanip>
  23. #include <stdio.h>
  24. #include <vector>
  25. #include <shellapi.h>
  26. //#include "helpers.h"
  27. #include "PEHeaders.h"
  28. #include "resource.h"
  29.  
  30.  
  31. std::wstring AnsiToWide(const char* str) {
  32.     if (!str) return L"";
  33.     int size = MultiByteToWideChar(CP_ACP, 0, str, -1, nullptr, 0);
  34.     if (size <= 0) return L"";
  35.     std::vector<wchar_t> buf(size);
  36.     MultiByteToWideChar(CP_ACP, 0, str, -1, buf.data(), size);
  37.     return std::wstring(buf.data());
  38. }
  39.  
  40. std::wstring Utf8ToWide(const char* str) {
  41.     if (!str) return L"";
  42.     int size = MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0);
  43.     if (size <= 0) return L"";
  44.     std::vector<wchar_t> buf(size);
  45.     MultiByteToWideChar(CP_UTF8, 0, str, -1, buf.data(), size);
  46.     return std::wstring(buf.data());
  47. }
  48.  
  49. #pragma comment(lib, "comctl32.lib")
  50.  
  51. //namespace was here
  52.  
  53. // Window defines
  54. #define WINDOW_CLASS_NAME L"PEAnalyzerWindow"
  55. #define OUTPUT(format, ...) AppendToOutput(L##format, ##__VA_ARGS__)
  56. #define WINDOW_WIDTH    1024
  57. #define WINDOW_HEIGHT   768
  58. #define EDIT_MARGIN    10
  59.  
  60. // Global variables
  61. HWND g_hMainWindow = NULL;
  62. HWND g_hEditControl = NULL;
  63. HWND g_hStatusBar = NULL;
  64. HWND g_hProgressBar = NULL;
  65. HFONT g_hFont = NULL;
  66. std::wstringstream g_OutputText;
  67. std::vector<wchar_t> g_OutputBuffer;
  68. std::wstring tempBuffer;
  69. WCHAR filePathW[MAX_PATH];
  70. bool g_FileLoaded = false;
  71.  
  72. // Resource parsing constants
  73. static const wchar_t* RESOURCE_TYPES[] = {
  74.     L"Unknown",     L"Cursor",      L"Bitmap",      L"Icon",
  75.     L"Menu",        L"Dialog",      L"String",      L"FontDir",
  76.     L"Font",        L"Accelerator", L"RCData",      L"MessageTable",
  77.     L"GroupCursor", L"GroupIcon",   L"Version",     L"DlgInclude"
  78. };
  79.  
  80. //adding structs here now
  81.  
  82. enum class FileValidationResult {
  83.     Valid,
  84.     InvalidPath,
  85.     FileNotFound,
  86.     AccessDenied,
  87.     UnsupportedType
  88. };
  89.  
  90. // Forward declarations for global functions
  91. void UpdateEditControl();
  92. void AppendToOutput(const wchar_t* format, ...);
  93. void SetStatusText(const wchar_t* text);
  94. void ShowProgress(int percentage);
  95. void OpenFileDialog(HWND hwnd);
  96. void AnalyzePEFile(const wchar_t* filePathW);
  97. //analyzepefile 4wd func
  98. HANDLE GetFileContent(const wchar_t* lpFilePath);
  99. void OpenFileDialog(HWND hwnd); // Add these in the global scope, before any namespace declarations
  100.  
  101. // GUI-related forward declarations
  102. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  103. LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
  104.     LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData);
  105. void CreateMainWindow(HINSTANCE hInstance);
  106. void InitializeControls(HWND hwnd);
  107. void AddMenus(HWND hwnd);
  108. //void SetStatusText(const wchar_t* text);
  109. //void ShowProgress(int percentage);
  110. //void UpdateEditControl();    
  111. DWORD GetFileSizeCustom(const wchar_t* filePath);
  112.  
  113. //bool Is64BitPE(PIMAGE_NT_HEADERS pNtHeaders);
  114.  
  115.  
  116. //using namespace std;
  117. //using namespace PEParser;
  118. //using namespace PEHelpers;
  119.  
  120. //namespace PEParser {
  121.  
  122. //struct PEAnalyzer;  // Forward declaration
  123. class FileMapper;
  124. FileValidationResult ValidatePEFile(const wchar_t* filePath);
  125. bool InitializePEAnalyzer(PEAnalyzer& analyzer, const wchar_t* filePath);
  126. //class FileValidationResult ValidatePEFile(const wchar_t* filePath);
  127. void ParseSections(const PEAnalyzer& analyzer); //forwarddeclare parse+ bring namespace up
  128. void ParseImportDirectory(const PEAnalyzer& analyzer);
  129. void ParseExportDirectory(const PEAnalyzer& analyzer);
  130. void ParseResourceDirectory(const PEAnalyzer& analyzer);
  131. void ParseDebugDirectory(const PEAnalyzer& analyzer);
  132. void AnalyzeHeaders(const PEAnalyzer& analyzer);
  133. void AnalyzeDataDirectories(const PEAnalyzer& analyzer);
  134. //bool InitializePEAnalyzer(PEAnalyzer& analyzer, const wchar_t* filePath);
  135.  
  136. //newglobals
  137. void ParseNTHeader64(const PEAnalyzer& analyzer);
  138. void ParseNTHeader32(const PEAnalyzer& analyzer);
  139. void ParseImportFunctions32(const PEAnalyzer& analyzer, PIMAGE_IMPORT_DESCRIPTOR pImportDesc);
  140. void ParseImportFunctions64(const PEAnalyzer& analyzer, PIMAGE_IMPORT_DESCRIPTOR pImportDesc);
  141. void ParseExportedFunctions(const PEAnalyzer& analyzer, PIMAGE_EXPORT_DIRECTORY pExportDir,
  142.     PDWORD pFunctions, PDWORD pNames, PWORD pOrdinals);
  143. void ProcessResourceDirectory(
  144.     PIMAGE_RESOURCE_DIRECTORY resDir,
  145.     int level,
  146.     const wchar_t* type,
  147.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  148.     const PEAnalyzer& analyzer);
  149. void ProcessNamedResourceEntry(const IMAGE_RESOURCE_DIRECTORY_ENTRY& entry,
  150.     int level, PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  151.     const PEAnalyzer& analyzer);
  152. void ProcessIdResourceEntry(const IMAGE_RESOURCE_DIRECTORY_ENTRY& entry,
  153.     int level, const wchar_t* type,
  154.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  155.     const PEAnalyzer& analyzer);
  156. void ProcessResourceSubdirectory(const IMAGE_RESOURCE_DIRECTORY_ENTRY& entry,
  157.     int level, const wchar_t* type,
  158.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  159.     const PEAnalyzer& analyzer);
  160. void ProcessResourceData(const IMAGE_RESOURCE_DIRECTORY_ENTRY& entry,
  161.     int level, const wchar_t* type,
  162.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  163.     const PEAnalyzer& analyzer);
  164. void ProcessDebugEntry(const IMAGE_DEBUG_DIRECTORY& debugEntry, const PEAnalyzer& analyzer);
  165. void ProcessRSDSDebugInfo(const IMAGE_DEBUG_DIRECTORY& debugEntry, DWORD* pCVHeader,
  166.     const PEAnalyzer& analyzer);
  167. void ProcessCodeViewDebugInfo(const IMAGE_DEBUG_DIRECTORY& debugEntry, const PEAnalyzer& analyzer);
  168. void ProcessNB10DebugInfo(const IMAGE_DEBUG_DIRECTORY& debugEntry, DWORD* pCVHeader,
  169.     const PEAnalyzer& analyzer);
  170. //void ParseImportDirectory(const PEAnalyzer& analyzer);
  171. //void ParseExportDirectory(const PEAnalyzer& analyzer);
  172. //DWORD GetFileSizeCustom(const wchar_t* filePath);
  173. //endnewglobals
  174.  
  175. //using namespace std;
  176. //using namespace PEHelpers;
  177. //struct was here
  178.  
  179.  
  180. // File mapping helper class
  181. class FileMapper {
  182. private:
  183.     HANDLE hFile;
  184.     HANDLE hMapping;
  185.     LPVOID lpView;
  186.  
  187. public:
  188.     FileMapper() : hFile(INVALID_HANDLE_VALUE), hMapping(nullptr), lpView(nullptr) {}
  189.     ~FileMapper() { Cleanup(); }
  190.  
  191.     void Cleanup() {
  192.         if (lpView) {
  193.             UnmapViewOfFile(lpView);
  194.             lpView = nullptr;
  195.         }
  196.         if (hMapping) {
  197.             CloseHandle(hMapping);
  198.             hMapping = nullptr;
  199.         }
  200.         if (hFile != INVALID_HANDLE_VALUE) {
  201.             CloseHandle(hFile);
  202.             hFile = INVALID_HANDLE_VALUE;
  203.         }
  204.     }
  205.  
  206.         bool Initialize(const wchar_t* path) {
  207.         Cleanup();
  208.        
  209.         hFile = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
  210.             nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  211.         if (hFile == INVALID_HANDLE_VALUE) {
  212.             OUTPUT("[-] Failed to open file\n");
  213.             return false;
  214.         }
  215.  
  216.         LARGE_INTEGER fileSize;
  217.         if (!GetFileSizeEx(hFile, &fileSize)) {
  218.             OUTPUT("[-] Failed to get file size\n");
  219.             Cleanup();
  220.             return false;
  221.         }
  222.  
  223.         // Create mapping without SEC_IMAGE first
  224.         hMapping = CreateFileMappingW(hFile, nullptr, PAGE_READONLY,
  225.             fileSize.HighPart, fileSize.LowPart, nullptr);
  226.         if (!hMapping) {
  227.             OUTPUT("[-] Failed to create file mapping\n");
  228.             Cleanup();
  229.             return false;
  230.         }
  231.  
  232.         lpView = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
  233.         if (!lpView) {
  234.             OUTPUT("[-] Failed to map view of file\n");
  235.             Cleanup();
  236.             return false;
  237.         }
  238.  
  239.         return true;
  240.         }
  241.  
  242.         LPVOID GetView() const { return lpView; }
  243. };
  244.  
  245. FileValidationResult ValidatePEFile(const wchar_t* filePath) {
  246.     if (!filePath || wcslen(filePath) == 0) {
  247.         OUTPUT("[-] Null or empty file path\n");
  248.         return FileValidationResult::InvalidPath;
  249.     }
  250.  
  251.     // Check file extension
  252.     const wchar_t* ext = wcsrchr(filePath, L'.');
  253.     if (!ext || (wcscmp(ext, L".exe") != 0 && wcscmp(ext, L".dll") != 0)) {
  254.         OUTPUT("[-] Unsupported file type. Only .exe and .dll are supported\n");
  255.         return FileValidationResult::UnsupportedType;
  256.     }
  257.  
  258.     // Detailed file access check
  259.     HANDLE hFile = CreateFileW(
  260.         filePath,
  261.         GENERIC_READ,
  262.         FILE_SHARE_READ | FILE_SHARE_WRITE,
  263.         NULL,
  264.         OPEN_EXISTING,
  265.         FILE_ATTRIBUTE_NORMAL,
  266.         NULL
  267.     );
  268.  
  269.     if (hFile == INVALID_HANDLE_VALUE) {
  270.         DWORD error = GetLastError();
  271.         switch (error) {
  272.         case ERROR_FILE_NOT_FOUND:
  273.             OUTPUT("[-] File not found: %ls\n", filePath);
  274.             return FileValidationResult::FileNotFound;
  275.         case ERROR_ACCESS_DENIED:
  276.             OUTPUT("[-] Access denied. Check file permissions: %ls\n", filePath);
  277.             return FileValidationResult::AccessDenied;
  278.         default:
  279.             OUTPUT("[-] File open error %d: %ls\n", error, filePath);
  280.             return FileValidationResult::InvalidPath;
  281.         }
  282.     }
  283.  
  284.     // Additional checks
  285.     LARGE_INTEGER fileSize;
  286.     if (!GetFileSizeEx(hFile, &fileSize)) {
  287.         CloseHandle(hFile);
  288.         OUTPUT("[-] Cannot determine file size\n");
  289.         return FileValidationResult::InvalidPath;
  290.     }
  291.  
  292.     CloseHandle(hFile);
  293.     return FileValidationResult::Valid;
  294. }
  295.  
  296. // Initialization function
  297. bool InitializePEAnalyzer(PEAnalyzer& analyzer, const wchar_t* filePath) {
  298.     FileValidationResult validationResult = ValidatePEFile(filePath);
  299.     if (validationResult != FileValidationResult::Valid) {
  300.         OUTPUT("[-] File validation failed with code: %d\n", static_cast<int>(validationResult));
  301.         return false;
  302.     }
  303.  
  304.         /*if (!analyzer.lpFileContent) {
  305.             OUTPUT("[-] No file content available\n");
  306.             return false;
  307.         }*/ //chatgpt4omitted
  308.  
  309.     analyzer.pMapper = new FileMapper();
  310.     if (!analyzer.pMapper->Initialize(filePath)) {
  311.         OUTPUT("[-] Failed to map file. Detailed error in FileMapper\n");
  312.         return false;
  313.     }
  314.  
  315.     analyzer.lpFileContent = analyzer.pMapper->GetView();
  316.     analyzer.fileSize = GetFileSizeCustom(filePath);
  317.     if (!analyzer.lpFileContent) {
  318.         OUTPUT("[-] Memory mapping failed\n");
  319.         return false;
  320.     }
  321.  
  322.     // Validate DOS Header
  323.     analyzer.pDosHeader = static_cast<PIMAGE_DOS_HEADER>(analyzer.lpFileContent);
  324.     if (!IsSafeToRead(analyzer, analyzer.pDosHeader, sizeof(IMAGE_DOS_HEADER)) ||
  325.         analyzer.pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
  326.         OUTPUT("[-] Invalid DOS signature: 0x%X (Expected 0x%X)\n",
  327.             analyzer.pDosHeader->e_magic, IMAGE_DOS_SIGNATURE);
  328.         return false;
  329.     }
  330.  
  331.     // Validate NT Header Offset
  332.     if (analyzer.pDosHeader->e_lfanew >= analyzer.fileSize ||
  333.         analyzer.pDosHeader->e_lfanew < sizeof(IMAGE_DOS_HEADER)) {
  334.         OUTPUT("[-] Invalid e_lfanew value: 0x%X\n", analyzer.pDosHeader->e_lfanew);
  335.         return false;
  336.     }
  337.  
  338.     /* // Comprehensive PE signature validation
  339.         if (!analyzer.lpFileContent || analyzer.fileSize == 0) {
  340.         OUTPUT("[-] Memory mapping failed or file size is zero\n");
  341.         return false;
  342.     }
  343.  
  344.         // Add bounds checking
  345.         if (analyzer.fileSize < sizeof(IMAGE_DOS_HEADER)) {
  346.             OUTPUT("[-] File too small to contain DOS header\n");
  347.             return false;
  348.         }
  349.  
  350.     // DOS Header validation with extensive checks
  351.         analyzer.pDosHeader = static_cast<PIMAGE_DOS_HEADER>(analyzer.lpFileContent);
  352.  
  353.         // Validate DOS header
  354.         //if (!IsSafeToRead(analyzer, analyzer.pDosHeader, sizeof(IMAGE_DOS_HEADER))) {
  355.         //    OUTPUT("[-] Invalid DOS header access\n");
  356.             return false;
  357.         //}
  358.  
  359.     // More robust DOS signature check
  360.         if (analyzer.pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
  361.             OUTPUT("[-] Invalid DOS signature: 0x%X (Expected 0x%X)\n",
  362.                 analyzer.pDosHeader->e_magic, IMAGE_DOS_SIGNATURE);
  363.             return false;
  364.         }
  365.  
  366.     // Validate e_lfanew with more checks
  367.     if (analyzer.pDosHeader->e_lfanew >= analyzer.fileSize ||
  368.         analyzer.pDosHeader->e_lfanew < sizeof(IMAGE_DOS_HEADER)) {
  369.         OUTPUT("[-] Invalid e_lfanew value: 0x%X\n", analyzer.pDosHeader->e_lfanew);
  370.         return false;
  371.     } */ //chatgpt4omitted
  372.  
  373.     /*analyzer.lpFileContent = mapper.GetView();
  374.     if (!analyzer.lpFileContent) {
  375.         OUTPUT("[-] Failed to get file view. Memory mapping issue.\n");
  376.         return false;
  377.     }
  378.  
  379.     analyzer.fileSize = GetFileSizeCustom(filePath);
  380.     if (!analyzer.fileSize) {
  381.         OUTPUT("[-] Unable to determine file size. File might be empty.\n");
  382.         return false;
  383.     }*/
  384.  
  385.     // Validate file content
  386.     /*if (analyzer.fileSize < sizeof(IMAGE_DOS_HEADER)) {
  387.         OUTPUT("[-] File too small to be a valid PE\n");
  388.         return false;
  389.     }
  390.  
  391.     analyzer.pDosHeader = static_cast<PIMAGE_DOS_HEADER>(analyzer.lpFileContent);
  392.     if (!analyzer.pDosHeader || analyzer.pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
  393.         OUTPUT("[-] Invalid DOS signature\n");
  394.         return false;
  395.     }
  396.  
  397.     // Validate e_lfanew
  398.     if (analyzer.pDosHeader->e_lfanew >= analyzer.fileSize ||
  399.         analyzer.pDosHeader->e_lfanew < sizeof(IMAGE_DOS_HEADER)) {
  400.         OUTPUT("[-] Invalid e_lfanew value\n");
  401.         return false;
  402.     }*/
  403.  
  404.     // Validate NT Headers
  405.     LONG ntHeaderOffset = analyzer.pDosHeader->e_lfanew;
  406.     auto pNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
  407.         static_cast<BYTE*>(analyzer.lpFileContent) + ntHeaderOffset);
  408.  
  409.     if (!IsSafeToRead(analyzer, pNtHeaders, sizeof(IMAGE_NT_HEADERS)) ||
  410.         pNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
  411.         OUTPUT("[-] Invalid NT signature: 0x%X (Expected 0x%X)\n",
  412.             pNtHeaders->Signature, IMAGE_NT_SIGNATURE);
  413.         return false;
  414.     }
  415.  
  416.     /* // Validate NT Headers location
  417.     LONG ntHeaderOffset = analyzer.pDosHeader->e_lfanew;
  418.     if (ntHeaderOffset <= 0 ||
  419.         ntHeaderOffset >= analyzer.fileSize ||
  420.         ntHeaderOffset < sizeof(IMAGE_DOS_HEADER)) {
  421.         OUTPUT("[-] Invalid NT Headers offset: 0x%X\n", ntHeaderOffset);
  422.         return false;
  423.     }
  424.  
  425.     // NT Headers signature validation
  426.     auto pNtHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(
  427.         static_cast<BYTE*>(analyzer.lpFileContent) + ntHeaderOffset);
  428.  
  429.     if (pNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
  430.         OUTPUT("[-] Invalid NT signature: 0x%X (Expected 0x%X)\n",
  431.             pNtHeaders->Signature,
  432.             IMAGE_NT_SIGNATURE);
  433.         return false;
  434.     } */ //chatgpt4omitted
  435.  
  436.     /*if (IsBadReadPtr(pNtHeaders, sizeof(IMAGE_NT_HEADERS)) ||
  437.         pNtHeaders->Signature != IMAGE_NT_SIGNATURE) {
  438.         OUTPUT("[-] Invalid NT signature\n");
  439.         return false;
  440.     }*/
  441.  
  442.     // Determine architecture with additional safety checks
  443.         // Determine Architecture
  444.     /* WORD magicNumber = pNtHeaders->OptionalHeader.Magic;
  445.     analyzer.is64Bit = (magicNumber == IMAGE_NT_OPTIONAL_HDR64_MAGIC);
  446.     if (analyzer.is64Bit) {
  447.         analyzer.pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
  448.         analyzer.pNtHeaders32 = nullptr;
  449.     }
  450.     else {
  451.         analyzer.pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
  452.         analyzer.pNtHeaders64 = nullptr;
  453.     }*/ //chatgpt4omitted
  454.  
  455.     // Determine Architecture
  456.     WORD magicNumber = pNtHeaders->OptionalHeader.Magic;
  457.     analyzer.is64Bit = (magicNumber == IMAGE_NT_OPTIONAL_HDR64_MAGIC);
  458.     if (analyzer.is64Bit) {
  459.         analyzer.pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
  460.         analyzer.pNtHeaders32 = nullptr;
  461.     }
  462.     else {
  463.         analyzer.pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
  464.         analyzer.pNtHeaders64 = nullptr;
  465.     }
  466.  
  467.     return true;
  468. }
  469.  
  470.  
  471. //    return true;
  472. //}
  473. /* catch (const std::exception& ex) {
  474.     OUTPUT("[-] Initialization error: %s\n", ex.what());
  475.     return false;
  476. }
  477. catch (...) {
  478.     OUTPUT("[-] Unknown initialization error\n");
  479.     return false;
  480. }
  481. } */ //chatgpt4omitted
  482.  
  483. // Helper function for file size
  484. DWORD GetFileSizeCustom(const wchar_t* filePath) {
  485.     HANDLE hFile = CreateFileW(filePath, GENERIC_READ, FILE_SHARE_READ,
  486.         nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  487.     if (hFile == INVALID_HANDLE_VALUE) return 0;
  488.  
  489.     DWORD fileSize = ::GetFileSize(hFile, nullptr);
  490.     CloseHandle(hFile);
  491.     return fileSize;
  492. } //removing other not this duplicate
  493.  
  494. // Main analysis function
  495. void AnalyzePEFile(const wchar_t* filePathW) {
  496.     if (!filePathW || wcslen(filePathW) == 0) {
  497.         OUTPUT("[-] Invalid file path\n");
  498.         SetStatusText(L"Invalid file path!");
  499.         ShowProgress(0);
  500.         return;
  501.     }
  502.  
  503.  
  504.     /* // Check file extension
  505.     const wchar_t* ext = wcsrchr(filePathW, L'.');
  506.     if (!ext || (wcscmp(ext, L".exe") != 0 && wcscmp(ext, L".dll") != 0)) {
  507.         OUTPUT("[-] Unsupported file type. Use .exe or .dll\n");
  508.         SetStatusText(L"Unsupported file type!");
  509.         ShowProgress(0);
  510.         return;
  511.     } */
  512.  
  513.     /* // Check if file exists
  514.     HANDLE hFile = CreateFileW(filePathW, GENERIC_READ, FILE_SHARE_READ,
  515.         NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  516.     if (hFile == INVALID_HANDLE_VALUE) {
  517.         DWORD error = GetLastError();
  518.         OUTPUT("[-] Cannot open file. Error code: %d\n", error);
  519.         SetStatusText(L"Failed to open file!");
  520.         ShowProgress(0);
  521.         return;
  522.     }
  523.     CloseHandle(hFile); */
  524.  
  525.     // Reset and prepare for analysis
  526.         g_OutputText.str(L"");
  527.         g_OutputText.clear();
  528.         UpdateEditControl();
  529.  
  530.         OUTPUT("[+] Starting PE Analysis for: %ls\n\n", filePathW);
  531.         SetStatusText(L"Analyzing PE File...");
  532.         ShowProgress(10);
  533.     //ShowProgress(10);
  534.  
  535.         PEAnalyzer analyzer;
  536.         try {
  537.             if (!InitializePEAnalyzer(analyzer, filePathW)) {
  538.                 OUTPUT("[-] PE Initialization Failed\n");
  539.                 SetStatusText(L"PE Analysis Failed");
  540.                 ShowProgress(0);
  541.                 UpdateEditControl();
  542.                 return;
  543.             }
  544.  
  545.         // Add safety check
  546.         /*if (!analyzer.lpFileContent || !analyzer.pDosHeader) {
  547.             OUTPUT("[-] Invalid PE file structure\n");
  548.             SetStatusText(L"Invalid PE File");
  549.             ShowProgress(0);
  550.             UpdateEditControl();
  551.             return;
  552.         }*/
  553.  
  554.  
  555.         /* analyzer.lpFileContent = mapper.GetView();
  556.         analyzer.fileSize = GetFileSizeCustom(filePathW);
  557.  
  558.         if (!InitializePEAnalyzer(analyzer, filePathW)) {
  559.             OUTPUT("[-] PE Initialization Failed\n");
  560.             SetStatusText(L"Analysis Failed - Invalid PE");
  561.             ShowProgress(0);
  562.             return;
  563.         } */ //chatgpt4omitted
  564.  
  565.         // Detailed logging for architecture
  566.         OUTPUT("[+] File Architecture: %ls\n", analyzer.is64Bit ? L"64-bit" : L"32-bit");
  567.  
  568.         // Show initial progress
  569.         ShowProgress(10);
  570.         /*
  571.         // Add null checks before processing
  572.         if (!analyzer.lpFileContent) {
  573.             OUTPUT("[-] No file content available\n");
  574.             SetStatusText(L"Failed to read file content!");
  575.             ShowProgress(0);
  576.             return;
  577.         }
  578.  
  579.         // Inside AnalyzePEFile, before parsing headers
  580.         if (analyzer.is64Bit) {
  581.             if (!PEHelpers::ValidateFileSize(analyzer.pNtHeaders64->OptionalHeader.SizeOfImage, analyzer.fileSize)) {
  582.                 OUTPUT("[-] PE file size mismatch with 64-bit image size!\n");
  583.                 throw std::runtime_error("Invalid file size or PE image");
  584.             }
  585.         }
  586.         else {
  587.             if (!PEHelpers::ValidateFileSize(analyzer.pNtHeaders32->OptionalHeader.SizeOfImage, analyzer.fileSize)) {
  588.                 OUTPUT("[-] PE file size mismatch with 32-bit image size!\n");
  589.                 throw std::runtime_error("Invalid file size or PE image");
  590.             }
  591.         }
  592.         */
  593.         // Wrap each analysis step in its own try-catch
  594.         // Basic headers analysis
  595.         try {
  596.             ShowProgress(20);
  597.             AnalyzeHeaders(analyzer);
  598.         }
  599.         catch (const std::exception& ex) {
  600.             OUTPUT("[-] Header Analysis Error: %ls\n", ex.what());
  601.             throw;  // Re-throw to handle in the outer catch block
  602.         }
  603.         //AnalyzeHeaders(analyzer);
  604.  
  605.         // Data directories
  606.         try {
  607.             ShowProgress(30);
  608.             AnalyzeDataDirectories(analyzer);
  609.         }
  610.         catch (const std::exception& ex) {
  611.             OUTPUT("[-] Data Directories Analysis Error: %ls\n", ex.what());
  612.             throw;  // Re-throw to handle in the outer catch block
  613.         }
  614.         //AnalyzeDataDirectories(analyzer);
  615.  
  616.         // Parse sections
  617.         try {
  618.             ShowProgress(40);
  619.             ParseSections(analyzer);
  620.         }
  621.         catch (const std::exception& ex) {
  622.             OUTPUT("[-] Sections Parsing Error: %ls\n", ex.what());
  623.             throw;  // Re-throw to handle in the outer catch block
  624.         }
  625.  
  626.         //ParseSections(analyzer);
  627.  
  628.         // Parse imports
  629.         try {
  630.             ShowProgress(50);
  631.             ParseImportDirectory(analyzer);
  632.         }
  633.         catch (const std::exception& ex) {
  634.             OUTPUT("[-] Import Directory Parsing Error: %ls\n", ex.what());
  635.             throw;  // Re-throw to handle in the outer catch block
  636.         }
  637.         //ParseImportDirectory(analyzer);
  638.  
  639.         // Parse exports
  640.         try {
  641.             ShowProgress(60);            
  642.             ParseExportDirectory(analyzer);
  643.         }
  644.         catch (const std::exception& ex) {
  645.             OUTPUT("[-] Export Directory Parsing Error: %ls\n", ex.what());
  646.             throw;  // Re-throw to handle in the outer catch block
  647.         }
  648.         //ParseExportDirectory(analyzer);
  649.  
  650.         // Parse resources
  651.         try {
  652.             ShowProgress(70);
  653.             ParseResourceDirectory(analyzer);
  654.         }
  655.         catch (const std::exception& ex) {
  656.             OUTPUT("[-] Resource Directory Parsing Error: %ls\n", ex.what());
  657.             throw;  // Re-throw to handle in the outer catch block
  658.         }
  659.         //ParseResourceDirectory(analyzer);
  660.  
  661.         // Parse debug info
  662.         try {
  663.             ShowProgress(80);            
  664.             ParseDebugDirectory(analyzer);
  665.         }
  666.         catch (const std::exception& ex) {
  667.             OUTPUT("[-] Debug Directory Parsing Error: %ls\n", ex.what());
  668.             throw;  // Re-throw to handle in the outer catch block
  669.         }
  670.         //ParseDebugDirectory(analyzer);
  671.        
  672.         ShowProgress(100);
  673.         SetStatusText(L"Analysis Complete");
  674.  
  675.         // Mark that a file is loaded.
  676.         g_FileLoaded = true;
  677.  
  678.         // Enable the "Select All" menu item.
  679.         HMENU hMenu = GetMenu(g_hMainWindow);
  680.         HMENU hFileMenu = GetSubMenu(hMenu, 0); // Assuming "File" is the first menu
  681.         EnableMenuItem(hFileMenu, 2, MF_BYCOMMAND | MF_ENABLED);
  682.         //EnableMenuItem(hFileMenu, ID_FILE_SELECTALL, MF_BYCOMMAND | MF_ENABLED);
  683.         DrawMenuBar(g_hMainWindow);
  684.  
  685.         if (analyzer.pMapper) {
  686.             delete analyzer.pMapper;
  687.             analyzer.pMapper = nullptr;
  688.         }
  689.     }
  690.     //}
  691.     catch (const std::exception& ex) {
  692.         OUTPUT("[-] Unexpected Exception: %ls\n", ex.what());
  693.         SetStatusText(L"Analysis Failed");
  694.         ShowProgress(0);
  695.     }
  696.     catch (...) {
  697.         OUTPUT("[-] Unknown critical error during PE analysis\n");
  698.         SetStatusText(L"Critical Failure");
  699.         ShowProgress(0);
  700.     }
  701.     /*catch (const std::exception& ex) {
  702.         OUTPUT("[-] Exception during analysis: %s\n", ex.what());
  703.         SetStatusText(L"Analysis failed due to error.");
  704.         ShowProgress(0);
  705.         return;
  706.     }*/ //newly commented out
  707.     /*catch (const std::exception& e) {
  708.         OUTPUT("[-] Error during analysis: %s\n", e.what());
  709.         SetStatusText(L"Analysis failed!");
  710.     }*/
  711.  
  712.     //ShowWindow(g_hProgressBar, SW_HIDE);
  713.     // Ensure edit control is updated
  714.     UpdateEditControl();
  715.     analyzer.~PEAnalyzer(); // Explicit call to the destructor if not already invoked
  716. }
  717.  
  718. //amalgamating parsing funcs here experimental
  719.  
  720.     // Header analysis function
  721. void AnalyzeHeaders(const PEAnalyzer& analyzer) {
  722.     if (!analyzer.lpFileContent || !analyzer.pDosHeader) {
  723.         throw std::runtime_error("Invalid PE headers");
  724.     }
  725.  
  726.     OUTPUT("[+] PE IMAGE INFORMATION\n\n");
  727.     OUTPUT("[+] Architecture: %ls\n\n", analyzer.is64Bit ? L"x64" : L"x86");
  728.  
  729.     // Validate DOS Header
  730.     if (!IsSafeToRead(analyzer, analyzer.pDosHeader, sizeof(IMAGE_DOS_HEADER))) {
  731.         throw std::runtime_error("Invalid DOS header");
  732.     }
  733.  
  734.     // DOS Header
  735.     OUTPUT("[+] DOS HEADER\n");
  736.     OUTPUT("\te_magic    : 0x%X\n", analyzer.pDosHeader->e_magic);
  737.     OUTPUT("\te_cblp     : 0x%X\n", analyzer.pDosHeader->e_cblp);
  738.     OUTPUT("\te_cp       : 0x%X\n", analyzer.pDosHeader->e_cp);
  739.     OUTPUT("\te_crlc     : 0x%X\n", analyzer.pDosHeader->e_crlc);
  740.     OUTPUT("\te_cparhdr  : 0x%X\n", analyzer.pDosHeader->e_cparhdr);
  741.     OUTPUT("\te_minalloc : 0x%X\n", analyzer.pDosHeader->e_minalloc);
  742.     OUTPUT("\te_maxalloc : 0x%X\n", analyzer.pDosHeader->e_maxalloc);
  743.     OUTPUT("\te_ss       : 0x%X\n", analyzer.pDosHeader->e_ss);
  744.     OUTPUT("\te_sp       : 0x%X\n", analyzer.pDosHeader->e_sp);
  745.     OUTPUT("\te_csum     : 0x%X\n", analyzer.pDosHeader->e_csum);
  746.     OUTPUT("\te_ip       : 0x%X\n", analyzer.pDosHeader->e_ip);
  747.     OUTPUT("\te_cs       : 0x%X\n", analyzer.pDosHeader->e_cs);
  748.     OUTPUT("\te_lfarlc   : 0x%X\n", analyzer.pDosHeader->e_lfarlc);
  749.     OUTPUT("\te_ovno     : 0x%X\n", analyzer.pDosHeader->e_ovno);
  750.     OUTPUT("\te_oemid    : 0x%X\n", analyzer.pDosHeader->e_oemid);
  751.     OUTPUT("\te_oeminfo  : 0x%X\n", analyzer.pDosHeader->e_oeminfo);
  752.     OUTPUT("\te_lfanew   : 0x%X\n\n", analyzer.pDosHeader->e_lfanew);
  753.  
  754.     // Validate NT Headers
  755.     if (analyzer.is64Bit && analyzer.pNtHeaders64) {
  756.         ParseNTHeader64(analyzer);
  757.     }
  758.     else if (analyzer.pNtHeaders32) {
  759.         ParseNTHeader32(analyzer);
  760.     }
  761.     else {
  762.         throw std::runtime_error("Invalid NT headers");
  763.     }
  764. }
  765.  
  766. void ParseNTHeader32(const PEAnalyzer& analyzer) {
  767.     if (!analyzer.pNtHeaders32) {
  768.         throw std::runtime_error("Invalid NT headers");
  769.     }
  770.  
  771.     OUTPUT("[+] NT HEADER (32-bit)\n");
  772.     OUTPUT("\tSignature: 0x%X\n\n", analyzer.pNtHeaders32->Signature);
  773.  
  774.     // File Header
  775.     OUTPUT("[+] FILE HEADER\n");
  776.     OUTPUT("\tMachine: 0x%X\n", analyzer.pNtHeaders32->FileHeader.Machine);
  777.     OUTPUT("\tNumberOfSections: 0x%X\n", analyzer.pNtHeaders32->FileHeader.NumberOfSections);
  778.     OUTPUT("\tTimeDateStamp: 0x%X\n", analyzer.pNtHeaders32->FileHeader.TimeDateStamp);
  779.     OUTPUT("\tPointerToSymbolTable: 0x%X\n", analyzer.pNtHeaders32->FileHeader.PointerToSymbolTable);
  780.     OUTPUT("\tNumberOfSymbols: 0x%X\n", analyzer.pNtHeaders32->FileHeader.NumberOfSymbols);
  781.     OUTPUT("\tSizeOfOptionalHeader: 0x%X\n", analyzer.pNtHeaders32->FileHeader.SizeOfOptionalHeader);
  782.     OUTPUT("\tCharacteristics: 0x%X\n\n", analyzer.pNtHeaders32->FileHeader.Characteristics);
  783.  
  784.     // Optional Header
  785.     OUTPUT("[+] OPTIONAL HEADER\n");
  786.     OUTPUT("\tMagic: 0x%X\n", analyzer.pNtHeaders32->OptionalHeader.Magic);
  787.     OUTPUT("\tAddressOfEntryPoint: 0x%X\n", analyzer.pNtHeaders32->OptionalHeader.AddressOfEntryPoint);
  788.     OUTPUT("\tImageBase: 0x%X\n", analyzer.pNtHeaders32->OptionalHeader.ImageBase);
  789.     OUTPUT("\tSectionAlignment: 0x%X\n", analyzer.pNtHeaders32->OptionalHeader.SectionAlignment);
  790.     OUTPUT("\tFileAlignment: 0x%X\n", analyzer.pNtHeaders32->OptionalHeader.FileAlignment);
  791.     OUTPUT("\tSizeOfImage: 0x%X\n", analyzer.pNtHeaders32->OptionalHeader.SizeOfImage);
  792.     OUTPUT("\tSizeOfHeaders: 0x%X\n", analyzer.pNtHeaders32->OptionalHeader.SizeOfHeaders);
  793.     OUTPUT("\tSubsystem: 0x%X\n\n", analyzer.pNtHeaders32->OptionalHeader.Subsystem);
  794. }
  795.  
  796. void ParseNTHeader64(const PEAnalyzer& analyzer) {
  797.     if (!analyzer.pNtHeaders64) {
  798.         throw std::runtime_error("Invalid NT headers");
  799.     }
  800.  
  801.     OUTPUT("[+] NT HEADER (64-bit)\n");
  802.     OUTPUT("\tSignature: 0x%X\n\n", analyzer.pNtHeaders64->Signature);
  803.  
  804.     // File Header
  805.     OUTPUT("[+] FILE HEADER\n");
  806.     OUTPUT("\tMachine: 0x%X\n", analyzer.pNtHeaders64->FileHeader.Machine);
  807.     OUTPUT("\tNumberOfSections: 0x%X\n", analyzer.pNtHeaders64->FileHeader.NumberOfSections);
  808.     OUTPUT("\tTimeDateStamp: 0x%X\n", analyzer.pNtHeaders64->FileHeader.TimeDateStamp);
  809.     OUTPUT("\tPointerToSymbolTable: 0x%X\n", analyzer.pNtHeaders64->FileHeader.PointerToSymbolTable);
  810.     OUTPUT("\tNumberOfSymbols: 0x%X\n", analyzer.pNtHeaders64->FileHeader.NumberOfSymbols);
  811.     OUTPUT("\tSizeOfOptionalHeader: 0x%X\n", analyzer.pNtHeaders64->FileHeader.SizeOfOptionalHeader);
  812.     OUTPUT("\tCharacteristics: 0x%X\n\n", analyzer.pNtHeaders64->FileHeader.Characteristics);
  813.  
  814.     // Optional Header
  815.     OUTPUT("[+] OPTIONAL HEADER\n");
  816.     OUTPUT("\tMagic: 0x%X\n", analyzer.pNtHeaders64->OptionalHeader.Magic);
  817.     OUTPUT("\tAddressOfEntryPoint: 0x%X\n", analyzer.pNtHeaders64->OptionalHeader.AddressOfEntryPoint);
  818.     OUTPUT("\tImageBase: 0x%llX\n", analyzer.pNtHeaders64->OptionalHeader.ImageBase);
  819.     OUTPUT("\tSectionAlignment: 0x%X\n", analyzer.pNtHeaders64->OptionalHeader.SectionAlignment);
  820.     OUTPUT("\tFileAlignment: 0x%X\n", analyzer.pNtHeaders64->OptionalHeader.FileAlignment);
  821.     OUTPUT("\tSizeOfImage: 0x%X\n", analyzer.pNtHeaders64->OptionalHeader.SizeOfImage);
  822.     OUTPUT("\tSizeOfHeaders: 0x%X\n", analyzer.pNtHeaders64->OptionalHeader.SizeOfHeaders);
  823.     OUTPUT("\tSubsystem: 0x%X\n\n", analyzer.pNtHeaders64->OptionalHeader.Subsystem);
  824. }
  825. //}
  826.  
  827.         //russianheat (clipped peanalyzefile() code here)
  828.  
  829.  
  830.         // Data Directories analysis
  831. void AnalyzeDataDirectories(const PEAnalyzer& analyzer) {
  832.     OUTPUT("[+] DATA DIRECTORIES\n");
  833.     const IMAGE_DATA_DIRECTORY* dataDirectories = analyzer.is64Bit ?
  834.         analyzer.pNtHeaders64->OptionalHeader.DataDirectory :
  835.         analyzer.pNtHeaders32->OptionalHeader.DataDirectory;
  836.  
  837.     for (int i = 0; i < IMAGE_NUMBEROF_DIRECTORY_ENTRIES; i++) {
  838.         if (dataDirectories[i].VirtualAddress != 0) {
  839.             OUTPUT("\t%ls:\n", PEHelpers::GetDataDirectoryName(i).c_str());
  840.             OUTPUT("\t\tVirtualAddress: 0x%X\n", dataDirectories[i].VirtualAddress);
  841.             OUTPUT("\t\tSize: 0x%X\n", dataDirectories[i].Size);
  842.         }
  843.     }
  844.     OUTPUT("\n");
  845. }
  846.  
  847. // Safe memory check helper
  848. template<typename T>
  849. bool IsSafeToRead(const PEAnalyzer& analyzer, const T* ptr, size_t size) {
  850.     if (!ptr) return false;
  851.     DWORD_PTR start = reinterpret_cast<DWORD_PTR>(analyzer.lpFileContent);
  852.     DWORD_PTR end = start + analyzer.fileSize;
  853.     DWORD_PTR ptrAddr = reinterpret_cast<DWORD_PTR>(ptr);
  854.     return (ptrAddr >= start && (ptrAddr + size) <= end);
  855. }
  856.  
  857. // Section parsing with safety checks
  858. void ParseSections(const PEAnalyzer& analyzer) {
  859.     OUTPUT("[+] SECTION HEADERS\n");
  860.  
  861.     PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(
  862.         analyzer.is64Bit ?
  863.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders64) :
  864.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32));
  865.  
  866.     WORD numberOfSections = analyzer.is64Bit ?
  867.         analyzer.pNtHeaders64->FileHeader.NumberOfSections :
  868.         analyzer.pNtHeaders32->FileHeader.NumberOfSections;
  869.  
  870.     if (!IsSafeToRead(analyzer, pSection,
  871.         sizeof(IMAGE_SECTION_HEADER) * numberOfSections)) {
  872.         throw std::runtime_error("Invalid section headers");
  873.     }
  874.  
  875.     for (WORD i = 0; i < numberOfSections; i++, pSection++) {
  876.         char sectionName[IMAGE_SIZEOF_SHORT_NAME + 1] = {};
  877.         memcpy(sectionName, pSection->Name, IMAGE_SIZEOF_SHORT_NAME);
  878.  
  879.         // Sanitize section name
  880.         for (int j = 0; j < IMAGE_SIZEOF_SHORT_NAME; j++) {
  881.             if (!isprint(static_cast<unsigned char>(sectionName[j]))) {
  882.                 sectionName[j] = '\0';
  883.                 break;
  884.             }
  885.         }
  886.  
  887.         // Output section information        
  888.         OUTPUT("\tSECTION: %ls\n", AnsiToWide(sectionName).c_str());
  889.         OUTPUT("\t\tVirtualSize: 0x%X\n", pSection->Misc.VirtualSize);
  890.         OUTPUT("\t\tVirtualAddress: 0x%X\n", pSection->VirtualAddress);
  891.         OUTPUT("\t\tSizeOfRawData: 0x%X\n", pSection->SizeOfRawData);
  892.         OUTPUT("\t\tPointerToRawData: 0x%X\n", pSection->PointerToRawData);
  893.         OUTPUT("\t\tPointerToRelocations: 0x%X\n", pSection->PointerToRelocations);
  894.         OUTPUT("\t\tPointerToLinenumbers: 0x%X\n", pSection->PointerToLinenumbers);
  895.         OUTPUT("\t\tNumberOfRelocations: 0x%X\n", pSection->NumberOfRelocations);
  896.         OUTPUT("\t\tNumberOfLinenumbers: 0x%X\n", pSection->NumberOfLinenumbers);
  897.         OUTPUT("\t\tCharacteristics: 0x%X %ls\n\n",
  898.             pSection->Characteristics,
  899.             PEHelpers::GetSectionProtection(pSection->Characteristics).c_str());
  900.     }
  901. } //end of parsesection here
  902.  
  903.     // Import Directory parsing with safety checks
  904. void ParseImportDirectory(const PEAnalyzer& analyzer) {
  905.     const auto& importDir = analyzer.is64Bit ?
  906.         analyzer.pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] :
  907.         analyzer.pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
  908.  
  909.     if (!importDir.VirtualAddress || !importDir.Size) {
  910.         OUTPUT("\n[-] No import directory found.\n");
  911.         return;
  912.     }
  913.  
  914.     OUTPUT("\n[+] IMPORT DIRECTORY (%ls)\n", analyzer.is64Bit ? L"64-bit" : L"32-bit");
  915.  
  916.     auto pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)PEHelpers::GetRvaPtr(
  917.         importDir.VirtualAddress,
  918.         IMAGE_FIRST_SECTION(analyzer.is64Bit ?
  919.             (PIMAGE_NT_HEADERS)analyzer.pNtHeaders64 :
  920.             (PIMAGE_NT_HEADERS)analyzer.pNtHeaders32),
  921.         analyzer.is64Bit ?
  922.         analyzer.pNtHeaders64->FileHeader.NumberOfSections :
  923.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  924.         analyzer.lpFileContent,
  925.         analyzer.fileSize);
  926.  
  927.     if (!IsSafeToRead(analyzer, pImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
  928.         throw std::runtime_error("Invalid import descriptor");
  929.     }
  930.  
  931.     while (pImportDesc->Name != 0) {
  932.         const char* dllName = (const char*)PEHelpers::GetRvaPtr(
  933.             pImportDesc->Name,
  934.             IMAGE_FIRST_SECTION(analyzer.is64Bit ?
  935.                 reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders64) :
  936.                 reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32)),
  937.             analyzer.is64Bit ?
  938.             analyzer.pNtHeaders64->FileHeader.NumberOfSections :
  939.             analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  940.             analyzer.lpFileContent,
  941.             analyzer.fileSize);
  942.  
  943.         if (!IsSafeToRead(analyzer, dllName, 1)) {
  944.             break;
  945.         }
  946.  
  947.         if (dllName && !IsBadReadPtr(dllName, 1)) {
  948.             OUTPUT("\n\tDLL NAME: %ls\n", AnsiToWide(dllName).c_str());
  949.             OUTPUT("\tCharacteristics: 0x%X\n", pImportDesc->Characteristics);
  950.             OUTPUT("\tTimeDateStamp: 0x%X\n", pImportDesc->TimeDateStamp);
  951.             OUTPUT("\tForwarderChain: 0x%X\n", pImportDesc->ForwarderChain);
  952.             OUTPUT("\tFirstThunk: 0x%X\n\n", pImportDesc->FirstThunk);
  953.             OUTPUT("\tImported Functions:\n");
  954.         }
  955.  
  956.         // Parse functions based on architecture
  957.         if (analyzer.is64Bit) {
  958.             ParseImportFunctions64(analyzer, pImportDesc);
  959.         }
  960.         else {
  961.             ParseImportFunctions32(analyzer, pImportDesc);
  962.         }
  963.  
  964.         pImportDesc++;
  965.         if (!IsSafeToRead(analyzer, pImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
  966.             break;
  967.         }
  968.     }
  969. }
  970.  
  971. void ParseImportFunctions32(const PEAnalyzer& analyzer, PIMAGE_IMPORT_DESCRIPTOR pImportDesc) {
  972.     auto pThunk = (PIMAGE_THUNK_DATA32)PEHelpers::GetRvaPtr(
  973.         pImportDesc->OriginalFirstThunk ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk,
  974.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  975.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  976.         analyzer.lpFileContent,
  977.         analyzer.fileSize);
  978.  
  979.     while (pThunk && pThunk->u1.AddressOfData) {
  980.         if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)) {
  981.             auto pImportByName = (PIMAGE_IMPORT_BY_NAME)PEHelpers::GetRvaPtr(
  982.                 pThunk->u1.AddressOfData,
  983.                 IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  984.                 analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  985.                 analyzer.lpFileContent,
  986.                 analyzer.fileSize);
  987.  
  988.             if (pImportByName && !IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
  989.                 wchar_t wFuncName[MAX_PATH];
  990.                 MultiByteToWideChar(CP_ACP, 0, pImportByName->Name, -1, wFuncName, MAX_PATH);
  991.                 OUTPUT("\t\t%ls\n", wFuncName);
  992.             }
  993.         }
  994.         else {
  995.             OUTPUT("\t\tOrdinal: %d\n", pThunk->u1.Ordinal & 0xFFFF);
  996.         }
  997.         pThunk++;
  998.     }
  999. }
  1000.  
  1001. void ParseImportFunctions64(const PEAnalyzer& analyzer, PIMAGE_IMPORT_DESCRIPTOR pImportDesc) {
  1002.     auto pThunk = (PIMAGE_THUNK_DATA64)PEHelpers::GetRvaPtr(
  1003.         pImportDesc->OriginalFirstThunk ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk,
  1004.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1005.         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1006.         analyzer.lpFileContent,
  1007.         analyzer.fileSize);
  1008.  
  1009.     while (pThunk && pThunk->u1.AddressOfData) {
  1010.         if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)) {
  1011.             auto pImportByName = (PIMAGE_IMPORT_BY_NAME)PEHelpers::GetRvaPtr(
  1012.                 (DWORD)pThunk->u1.AddressOfData,
  1013.                 IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1014.                 analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1015.                 analyzer.lpFileContent,
  1016.                 analyzer.fileSize);
  1017.  
  1018.             if (pImportByName && !IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
  1019.                 wchar_t wFuncName[MAX_PATH];
  1020.                 MultiByteToWideChar(CP_ACP, 0, pImportByName->Name, -1, wFuncName, MAX_PATH);
  1021.                 OUTPUT("\t\t%ls\n", wFuncName);
  1022.             }
  1023.         }
  1024.         else {
  1025.             OUTPUT("\t\tOrdinal: %lld\n", pThunk->u1.Ordinal & 0xFFFF);
  1026.         }
  1027.         pThunk++;
  1028.     }
  1029. }
  1030.  
  1031. // Export Directory parsing with safety checks
  1032. void ParseExportDirectory(const PEAnalyzer& analyzer) {
  1033.     const auto& exportDir = analyzer.is64Bit ?
  1034.         analyzer.pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] :
  1035.         analyzer.pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
  1036.  
  1037.     if (!exportDir.VirtualAddress || !exportDir.Size) {
  1038.         OUTPUT("\n[-] No export directory found.\n");
  1039.         return;
  1040.     }
  1041.  
  1042.     OUTPUT("\n[+] EXPORT DIRECTORY (%ls)\n", analyzer.is64Bit ? L"64-bit" : L"32-bit");
  1043.  
  1044.     auto pExportDir = (PIMAGE_EXPORT_DIRECTORY)PEHelpers::GetRvaPtr(
  1045.         exportDir.VirtualAddress,
  1046.         IMAGE_FIRST_SECTION(analyzer.is64Bit ?
  1047.             reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders64) :
  1048.             reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32)),
  1049.         analyzer.is64Bit ?
  1050.         analyzer.pNtHeaders64->FileHeader.NumberOfSections :
  1051.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1052.         analyzer.lpFileContent,
  1053.         analyzer.fileSize);
  1054.  
  1055.     if (!IsSafeToRead(analyzer, pExportDir, sizeof(IMAGE_EXPORT_DIRECTORY))) {
  1056.         throw std::runtime_error("Invalid export directory");
  1057.     }
  1058.  
  1059.     // Output export directory information
  1060.     OUTPUT("\tCharacteristics: 0x%X\n", pExportDir->Characteristics);
  1061.     OUTPUT("\tTimeDateStamp: 0x%X\n", pExportDir->TimeDateStamp);
  1062.     OUTPUT("\tMajorVersion: %d\n", pExportDir->MajorVersion);
  1063.     OUTPUT("\tMinorVersion: %d\n", pExportDir->MinorVersion);
  1064.     OUTPUT("\tName: 0x%X\n", pExportDir->Name);
  1065.     OUTPUT("\tBase: %d\n", pExportDir->Base);
  1066.     OUTPUT("\tNumberOfFunctions: %d\n", pExportDir->NumberOfFunctions);
  1067.     OUTPUT("\tNumberOfNames: %d\n", pExportDir->NumberOfNames);
  1068.     OUTPUT("\tAddressOfFunctions: 0x%X\n", pExportDir->AddressOfFunctions);
  1069.     OUTPUT("\tAddressOfNames: 0x%X\n", pExportDir->AddressOfNames);
  1070.     OUTPUT("\tAddressOfNameOrdinals: 0x%X\n\n", pExportDir->AddressOfNameOrdinals);
  1071.  
  1072.     // Get export tables with safety checks
  1073.  
  1074.     // Add IMAGE_FIRST_SECTION and section count parameters
  1075.     auto pFunctions = (PDWORD)PEHelpers::GetRvaPtr(pExportDir->AddressOfFunctions,
  1076.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1077.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1078.         analyzer.lpFileContent,
  1079.         analyzer.fileSize);
  1080.  
  1081.     auto pNames = (PDWORD)PEHelpers::GetRvaPtr(pExportDir->AddressOfNames,
  1082.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1083.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1084.         analyzer.lpFileContent,
  1085.         analyzer.fileSize);
  1086.  
  1087.     auto pOrdinals = (PWORD)PEHelpers::GetRvaPtr(pExportDir->AddressOfNameOrdinals,
  1088.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1089.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1090.         analyzer.lpFileContent,
  1091.         analyzer.fileSize);
  1092.  
  1093.     //auto pFunctions = (PDWORD)PEHelpers::GetRvaPtr(pExportDir->AddressOfFunctions, /*...*/);
  1094.     //auto pNames = (PDWORD)PEHelpers::GetRvaPtr(pExportDir->AddressOfNames, /*...*/);
  1095.     //auto pOrdinals = (PWORD)PEHelpers::GetRvaPtr(pExportDir->AddressOfNameOrdinals, /*...*/);
  1096.  
  1097.     if (!IsSafeToRead(analyzer, pFunctions, sizeof(DWORD) * pExportDir->NumberOfFunctions) ||
  1098.         !IsSafeToRead(analyzer, pNames, sizeof(DWORD) * pExportDir->NumberOfNames) ||
  1099.         !IsSafeToRead(analyzer, pOrdinals, sizeof(WORD) * pExportDir->NumberOfNames)) {
  1100.         throw std::runtime_error("Invalid export tables");
  1101.     }
  1102.  
  1103.     // Parse and output exported functions
  1104.     ParseExportedFunctions(analyzer, pExportDir, pFunctions, pNames, pOrdinals);
  1105. }
  1106.  
  1107. void ParseExportedFunctions(const PEAnalyzer& analyzer, PIMAGE_EXPORT_DIRECTORY pExportDir,
  1108.     PDWORD pFunctions, PDWORD pNames, PWORD pOrdinals) {
  1109.  
  1110.     OUTPUT("\tExported Functions:\n\n");
  1111.     for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {
  1112.         if (IsBadReadPtr(pNames + i, sizeof(DWORD)) ||
  1113.             IsBadReadPtr(pOrdinals + i, sizeof(WORD))) {
  1114.             break;
  1115.         }
  1116.  
  1117.         const char* functionName = (const char*)PEHelpers::GetRvaPtr(
  1118.             pNames[i],
  1119.             analyzer.is64Bit ? IMAGE_FIRST_SECTION((PIMAGE_NT_HEADERS64)analyzer.pNtHeaders64) : IMAGE_FIRST_SECTION((PIMAGE_NT_HEADERS32)analyzer.pNtHeaders32),
  1120.             analyzer.is64Bit ? analyzer.pNtHeaders64->FileHeader.NumberOfSections : analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1121.             analyzer.lpFileContent,
  1122.             analyzer.fileSize);
  1123.  
  1124.         /*const char* functionName = (const char*)PEHelpers::GetRvaPtr(
  1125.             pNames[i],
  1126.             IMAGE_FIRST_SECTION(analyzer.is64Bit ? analyzer.pNtHeaders64 : analyzer.pNtHeaders32),
  1127.             analyzer.is64Bit ? analyzer.pNtHeaders64->FileHeader.NumberOfSections :
  1128.             analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1129.             analyzer.lpFileContent);*/
  1130.  
  1131.         if (functionName && !IsBadReadPtr(functionName, 1)) {
  1132.             WORD ordinal = pOrdinals[i];
  1133.             if (ordinal < pExportDir->NumberOfFunctions) {
  1134.                 DWORD functionRva = pFunctions[ordinal];
  1135.                 wchar_t wFunctionName[MAX_PATH];
  1136.                 MultiByteToWideChar(CP_ACP, 0, functionName, -1, wFunctionName, MAX_PATH);
  1137.                 OUTPUT("\t\t%ls (Ordinal: %d, RVA: 0x%08X)\n", wFunctionName, ordinal + pExportDir->Base, functionRva);
  1138.             }
  1139.         }
  1140.     }
  1141. }
  1142.  
  1143. void ParseResourceDirectory(const PEAnalyzer& analyzer) {
  1144.     const auto& resourceDir = analyzer.is64Bit ?
  1145.         analyzer.pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE] :
  1146.         analyzer.pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
  1147.  
  1148.     if (!resourceDir.VirtualAddress || !resourceDir.Size) {
  1149.         OUTPUT("\n[-] No resource directory found.\n");
  1150.         return;
  1151.     }
  1152.  
  1153.     OUTPUT("\n[+] RESOURCE DIRECTORY (%ls)\n", analyzer.is64Bit ? L"64-bit" : L"32-bit");
  1154.  
  1155.     auto pResourceDir = (PIMAGE_RESOURCE_DIRECTORY)PEHelpers::GetRvaPtr(
  1156.         resourceDir.VirtualAddress,
  1157.         IMAGE_FIRST_SECTION(analyzer.is64Bit ?
  1158.             reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders64) :
  1159.             reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32)),
  1160.         analyzer.is64Bit ?
  1161.         analyzer.pNtHeaders64->FileHeader.NumberOfSections :
  1162.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1163.         analyzer.lpFileContent,
  1164.         analyzer.fileSize);
  1165.  
  1166.     if (!IsSafeToRead(analyzer, pResourceDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
  1167.         throw std::runtime_error("Invalid resource directory");
  1168.     }
  1169.  
  1170.     ProcessResourceDirectory(pResourceDir, 0, nullptr, pResourceDir, analyzer);
  1171. }
  1172.  
  1173. void ProcessResourceDirectory(
  1174.     PIMAGE_RESOURCE_DIRECTORY resDir,
  1175.     int level,
  1176.     const wchar_t* type,
  1177.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  1178.     const PEAnalyzer& analyzer)
  1179. {
  1180.     if (!IsSafeToRead(analyzer, resDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
  1181.         return;
  1182.     }
  1183.  
  1184.     auto entry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resDir + 1);
  1185.     WORD totalEntries = resDir->NumberOfNamedEntries + resDir->NumberOfIdEntries;
  1186.  
  1187.     for (WORD i = 0; i < totalEntries; i++) {
  1188.         if (!IsSafeToRead(analyzer, entry + i, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))) {
  1189.             break;
  1190.         }
  1191.  
  1192.         // Indent based on level
  1193.         for (int indent = 0; indent < level; indent++) {
  1194.             OUTPUT("\t");
  1195.         }
  1196.  
  1197.         // Process named entries
  1198.         if (entry[i].NameIsString) {
  1199.             ProcessNamedResourceEntry(entry[i], level, baseResourceDir, analyzer);
  1200.         }
  1201.         // Process ID entries
  1202.         else {
  1203.             ProcessIdResourceEntry(entry[i], level, type, baseResourceDir, analyzer);
  1204.         }
  1205.  
  1206.         // Process subdirectories or data
  1207.         if (entry[i].DataIsDirectory) {
  1208.             ProcessResourceSubdirectory(entry[i], level, type, baseResourceDir, analyzer);
  1209.         }
  1210.         else {
  1211.             ProcessResourceData(entry[i], level, type, baseResourceDir, analyzer);
  1212.         }
  1213.     }
  1214. }
  1215.  
  1216. //newlyfrom You,com Claude
  1217. void ProcessNamedResourceEntry(const IMAGE_RESOURCE_DIRECTORY_ENTRY& entry,
  1218.     int level, PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  1219.     const PEAnalyzer& analyzer) {
  1220.  
  1221.     auto nameEntry = (PIMAGE_RESOURCE_DIR_STRING_U)((BYTE*)baseResourceDir + entry.NameOffset);
  1222.     if (!IsBadReadPtr(nameEntry, sizeof(IMAGE_RESOURCE_DIR_STRING_U))) {
  1223.         std::vector<wchar_t> resourceName(nameEntry->Length + 1);
  1224.         wcsncpy_s(resourceName.data(), nameEntry->Length + 1,
  1225.             nameEntry->NameString, nameEntry->Length);
  1226.         resourceName[nameEntry->Length] = L'\0';
  1227.  
  1228.         if (level == 0) {
  1229.             OUTPUT("Resource Type: Custom (%ls)\n", resourceName.data());
  1230.         }
  1231.         else {
  1232.             OUTPUT("Name: %ls\n", resourceName.data());
  1233.         }
  1234.     }
  1235. }
  1236.  
  1237. void ProcessIdResourceEntry(const IMAGE_RESOURCE_DIRECTORY_ENTRY& entry,
  1238.     int level, const wchar_t* type,
  1239.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  1240.     const PEAnalyzer& analyzer) {
  1241.  
  1242.     if (level == 0) {
  1243.         DWORD resourceType = entry.Id;
  1244.         if (resourceType < 16) {
  1245.             OUTPUT("Resource Type: %ls (ID: %d)\n", RESOURCE_TYPES[resourceType], resourceType);
  1246.         }
  1247.         else {
  1248.             OUTPUT("Resource Type: Custom (ID: %d)\n", resourceType);
  1249.         }
  1250.     }
  1251.     else {
  1252.         OUTPUT("ID: %d\n", entry.Id);
  1253.     }
  1254. }
  1255.  
  1256. void ProcessResourceSubdirectory(const IMAGE_RESOURCE_DIRECTORY_ENTRY& entry,
  1257.     int level, const wchar_t* type,
  1258.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  1259.     const PEAnalyzer& analyzer) {
  1260.  
  1261.     auto nextDir = (PIMAGE_RESOURCE_DIRECTORY)((BYTE*)baseResourceDir + entry.OffsetToDirectory);
  1262.     if (!IsBadReadPtr(nextDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
  1263.         ProcessResourceDirectory(nextDir, level + 1,
  1264.             level == 0 ? RESOURCE_TYPES[min(entry.Id, 15)] : type,
  1265.             baseResourceDir, analyzer);
  1266.     }
  1267. }
  1268.  
  1269. void ProcessResourceData(const IMAGE_RESOURCE_DIRECTORY_ENTRY& entry,
  1270.     int level, const wchar_t* type,
  1271.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  1272.     const PEAnalyzer& analyzer) {
  1273.  
  1274.     auto dataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((BYTE*)baseResourceDir + entry.OffsetToData);
  1275.     if (!IsBadReadPtr(dataEntry, sizeof(IMAGE_RESOURCE_DATA_ENTRY))) {
  1276.         for (int indent = 0; indent < level + 1; indent++) {
  1277.             OUTPUT("\t");
  1278.         }
  1279.         OUTPUT("Size: %d bytes, RVA: 0x%X\n", dataEntry->Size, dataEntry->OffsetToData);
  1280.     }
  1281. }
  1282.  
  1283. void ParseDebugDirectory(const PEAnalyzer& analyzer) {
  1284.     const auto& debugDir = analyzer.is64Bit ?
  1285.         analyzer.pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG] :
  1286.         analyzer.pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
  1287.  
  1288.     if (!debugDir.VirtualAddress || !debugDir.Size) {
  1289.         OUTPUT("\n[-] No debug directory found.\n");
  1290.         return;
  1291.     }
  1292.  
  1293.     OUTPUT("\n[+] DEBUG DIRECTORY (%ls)\n", analyzer.is64Bit ? L"64-bit" : L"32-bit");
  1294.  
  1295.     auto pDebugDir = (PIMAGE_DEBUG_DIRECTORY)PEHelpers::GetRvaPtr(
  1296.         debugDir.VirtualAddress,
  1297.         IMAGE_FIRST_SECTION(analyzer.is64Bit ?
  1298.             reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders64) :
  1299.             reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32)),
  1300.         analyzer.is64Bit ?
  1301.         analyzer.pNtHeaders64->FileHeader.NumberOfSections :
  1302.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1303.         analyzer.lpFileContent,
  1304.         analyzer.fileSize);
  1305.  
  1306.     if (!IsSafeToRead(analyzer, pDebugDir, sizeof(IMAGE_DEBUG_DIRECTORY))) {
  1307.         throw std::runtime_error("Invalid debug directory");
  1308.     }
  1309.  
  1310.     DWORD numEntries = min(debugDir.Size / sizeof(IMAGE_DEBUG_DIRECTORY), 16);
  1311.     for (DWORD i = 0; i < numEntries; i++) {
  1312.         ProcessDebugEntry(pDebugDir[i], analyzer);
  1313.     }
  1314. }
  1315.  
  1316. void ProcessDebugEntry(const IMAGE_DEBUG_DIRECTORY& debugEntry, const PEAnalyzer& analyzer) {
  1317.     OUTPUT("\tDebug Entry:\n");
  1318.     OUTPUT("\tCharacteristics: 0x%X\n", debugEntry.Characteristics);
  1319.     OUTPUT("\tTimeDateStamp: 0x%X\n", debugEntry.TimeDateStamp);
  1320.     OUTPUT("\tVersion: %d.%d\n", debugEntry.MajorVersion, debugEntry.MinorVersion);
  1321.     OUTPUT("\tType: 0x%X", debugEntry.Type);
  1322.  
  1323.     // Output debug type
  1324.     switch (debugEntry.Type) {
  1325.     case IMAGE_DEBUG_TYPE_COFF:
  1326.         OUTPUT(" (COFF)\n"); break;
  1327.     case IMAGE_DEBUG_TYPE_CODEVIEW:
  1328.         OUTPUT(" (CodeView)\n");
  1329.         ProcessCodeViewDebugInfo(debugEntry, analyzer);
  1330.         break;
  1331.         // ... other debug types ...
  1332.     default:
  1333.         OUTPUT(" (Unknown)\n"); break;
  1334.     }
  1335.  
  1336.     OUTPUT("\tSizeOfData: 0x%X\n", debugEntry.SizeOfData);
  1337.     OUTPUT("\tAddressOfRawData: 0x%X\n", debugEntry.AddressOfRawData);
  1338.     OUTPUT("\tPointerToRawData: 0x%X\n\n", debugEntry.PointerToRawData);
  1339. }
  1340.  
  1341. // Helper functions for processing specific debug info types
  1342. void ProcessCodeViewDebugInfo(const IMAGE_DEBUG_DIRECTORY& debugEntry, const PEAnalyzer& analyzer) {
  1343.     if (debugEntry.Type != IMAGE_DEBUG_TYPE_CODEVIEW ||
  1344.         !debugEntry.PointerToRawData ||
  1345.         debugEntry.SizeOfData < sizeof(DWORD)) {
  1346.         return;
  1347.     }
  1348.  
  1349.     auto pCVHeader = (DWORD*)((BYTE*)analyzer.lpFileContent + debugEntry.PointerToRawData);
  1350.     if (!IsSafeToRead(analyzer, pCVHeader, sizeof(DWORD))) {
  1351.         return;
  1352.     }
  1353.  
  1354.     // Process different CodeView formats
  1355.     switch (*pCVHeader) {
  1356.     case 0x53445352: // 'RSDS'
  1357.         ProcessRSDSDebugInfo(debugEntry, pCVHeader, analyzer);
  1358.         break;
  1359.     case 0x3031424E: // 'NB10'
  1360.         ProcessNB10DebugInfo(debugEntry, pCVHeader, analyzer);
  1361.         break;
  1362.     }
  1363. }
  1364.  
  1365. void ProcessRSDSDebugInfo(const IMAGE_DEBUG_DIRECTORY& debugEntry, DWORD* pCVHeader,
  1366.     const PEAnalyzer& analyzer) {
  1367.  
  1368.     if (debugEntry.SizeOfData >= (sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD) + 1)) {
  1369.         auto pCVData = (char*)(pCVHeader + 1);
  1370.         if (!IsBadReadPtr(pCVData + 16, 1)) {
  1371.             auto guid = (GUID*)pCVData;
  1372.             DWORD age = *(DWORD*)(pCVData + 16);
  1373.             const char* pdbPath = pCVData + 20;
  1374.  
  1375.             OUTPUT("\tPDB Information:\n");
  1376.             OUTPUT("\tGUID: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
  1377.                 guid->Data1, guid->Data2, guid->Data3,
  1378.                 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
  1379.                 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
  1380.             OUTPUT("\tAge: %d\n", age);
  1381.             OUTPUT("\tPDB Path: %ls\n\n", AnsiToWide(pdbPath).c_str());
  1382.         }
  1383.     }
  1384. }
  1385.  
  1386. void ProcessNB10DebugInfo(const IMAGE_DEBUG_DIRECTORY& debugEntry, DWORD* pCVHeader,
  1387.     const PEAnalyzer& analyzer) {
  1388.  
  1389.     if (debugEntry.SizeOfData >= 16) {
  1390.         auto pNB10Data = (char*)(pCVHeader + 1);
  1391.         DWORD offset = *(DWORD*)pNB10Data;
  1392.         DWORD timestamp = *(DWORD*)(pNB10Data + 4);
  1393.         DWORD age = *(DWORD*)(pNB10Data + 8);
  1394.         const char* pdbPath = pNB10Data + 12;
  1395.  
  1396.         OUTPUT("\tPDB Information (NB10):\n");
  1397.         OUTPUT("\tOffset: 0x%X\n", offset);
  1398.         OUTPUT("\tTimestamp: 0x%X\n", timestamp);
  1399.         OUTPUT("\tAge: %d\n", age);
  1400.         OUTPUT("\tPDB Path: %ls\n\n", pdbPath);
  1401.     }
  1402. }
  1403.  
  1404. //colonelburton
  1405.  
  1406. void ParseImportDirectory32(const PEAnalyzer& analyzer) {
  1407.     const auto& importDir = analyzer.pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
  1408.     if (!importDir.VirtualAddress || !importDir.Size) return;
  1409.  
  1410.     if (!PEHelpers::IsRvaValid(importDir.VirtualAddress, analyzer.fileSize,
  1411.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32))) {
  1412.         OUTPUT("[-] Invalid import directory RVA!\n");
  1413.         throw std::runtime_error("RVA out of bounds");
  1414.         return;
  1415.     }
  1416.  
  1417.     OUTPUT("\n[+] IMPORT DIRECTORY (32-bit)\n");
  1418.     auto pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)PEHelpers::GetRvaPtr(
  1419.         importDir.VirtualAddress,
  1420.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1421.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1422.         analyzer.lpFileContent,
  1423.         analyzer.fileSize);
  1424.  
  1425.     if (!pImportDesc) return;
  1426.  
  1427.     while (pImportDesc->Name != 0) {
  1428.         if (IsBadReadPtr(pImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
  1429.             OUTPUT("[-] Invalid import descriptor detected!\n");
  1430.             break;
  1431.         }
  1432.  
  1433.         const char* dllName = (const char*)PEHelpers::GetRvaPtr(
  1434.             pImportDesc->Name,
  1435.             IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1436.             analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1437.             analyzer.lpFileContent,
  1438.             analyzer.fileSize);
  1439.  
  1440.         if (dllName && !IsBadReadPtr(dllName, 1)) {
  1441.             std::vector<wchar_t> wideDllName(MAX_PATH);
  1442.             MultiByteToWideChar(CP_UTF8, 0, dllName, -1, wideDllName.data(), MAX_PATH);
  1443.  
  1444.             OUTPUT("\n\tDLL NAME: %ls\n", wideDllName.data());
  1445.             OUTPUT("\tCharacteristics: 0x%X\n", pImportDesc->Characteristics);
  1446.             OUTPUT("\tTimeDateStamp: 0x%X\n", pImportDesc->TimeDateStamp);
  1447.             OUTPUT("\tForwarderChain: 0x%X\n", pImportDesc->ForwarderChain);
  1448.             OUTPUT("\tFirstThunk: 0x%X\n", pImportDesc->FirstThunk);
  1449.             OUTPUT("\n\tImported Functions:\n");
  1450.  
  1451.             auto pThunk = (PIMAGE_THUNK_DATA32)PEHelpers::GetRvaPtr(
  1452.                 pImportDesc->OriginalFirstThunk ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk,
  1453.                 IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1454.                 analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1455.                 analyzer.lpFileContent,
  1456.                 analyzer.fileSize);
  1457.  
  1458.             while (pThunk && pThunk->u1.AddressOfData) {
  1459.                 if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)) {
  1460.                     auto pImportByName = (PIMAGE_IMPORT_BY_NAME)PEHelpers::GetRvaPtr(
  1461.                         pThunk->u1.AddressOfData,
  1462.                         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1463.                         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1464.                         analyzer.lpFileContent,
  1465.                         analyzer.fileSize);
  1466.  
  1467.                     if (pImportByName && !IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
  1468.                         std::vector<wchar_t> wideFuncName(MAX_PATH);
  1469.                         MultiByteToWideChar(CP_ACP, 0, (char*)pImportByName->Name, -1,
  1470.                             wideFuncName.data(), MAX_PATH);
  1471.                         OUTPUT("\t\t%ls\n", wideFuncName.data());
  1472.                     }
  1473.                 }
  1474.                 else {
  1475.                     OUTPUT("\t\tOrdinal: %d\n", pThunk->u1.Ordinal & 0xFFFF);
  1476.                 }
  1477.                 pThunk++;
  1478.             }
  1479.         }
  1480.         pImportDesc++;
  1481.     }
  1482. }
  1483.  
  1484. void ParseImportDirectory64(const PEAnalyzer& analyzer) {
  1485.     const auto& importDir = analyzer.pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
  1486.     if (!importDir.VirtualAddress || !importDir.Size) return;
  1487.  
  1488.     if (!PEHelpers::IsRvaValid(importDir.VirtualAddress, analyzer.fileSize,
  1489.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders64))) {
  1490.         OUTPUT("[-] Invalid import directory RVA!\n");
  1491.         throw std::runtime_error("RVA out of bounds");
  1492.         return;
  1493.     }
  1494.  
  1495.     OUTPUT("\n[+] IMPORT DIRECTORY (64-bit)\n");
  1496.     auto pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)PEHelpers::GetRvaPtr(
  1497.         importDir.VirtualAddress,
  1498.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1499.         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1500.         analyzer.lpFileContent,
  1501.         analyzer.fileSize);
  1502.  
  1503.     if (!pImportDesc) return;
  1504.  
  1505.     while (pImportDesc->Name != 0) {
  1506.         if (IsBadReadPtr(pImportDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR))) {
  1507.             OUTPUT("[-] Invalid import descriptor detected!\n");
  1508.             break;
  1509.         }
  1510.  
  1511.         const char* dllName = (const char*)PEHelpers::GetRvaPtr(
  1512.             pImportDesc->Name,
  1513.             IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1514.             analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1515.             analyzer.lpFileContent,
  1516.             analyzer.fileSize);
  1517.  
  1518.         if (dllName && !IsBadReadPtr(dllName, 1)) {
  1519.             std::vector<wchar_t> wideDllName(MAX_PATH);
  1520.             MultiByteToWideChar(CP_UTF8, 0, dllName, -1, wideDllName.data(), MAX_PATH);
  1521.  
  1522.             OUTPUT("\n\tDLL NAME: %ls\n", wideDllName.data());
  1523.             OUTPUT("\tCharacteristics: 0x%X\n", pImportDesc->Characteristics);
  1524.             OUTPUT("\tTimeDateStamp: 0x%X\n", pImportDesc->TimeDateStamp);
  1525.             OUTPUT("\tForwarderChain: 0x%X\n", pImportDesc->ForwarderChain);
  1526.             OUTPUT("\tFirstThunk: 0x%X\n", pImportDesc->FirstThunk);
  1527.             OUTPUT("\n\tImported Functions:\n");
  1528.  
  1529.             auto pThunk = (PIMAGE_THUNK_DATA64)PEHelpers::GetRvaPtr(
  1530.                 pImportDesc->OriginalFirstThunk ? pImportDesc->OriginalFirstThunk : pImportDesc->FirstThunk,
  1531.                 IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1532.                 analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1533.                 analyzer.lpFileContent,
  1534.                 analyzer.fileSize);
  1535.  
  1536.             while (pThunk && pThunk->u1.AddressOfData) {
  1537.                 if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG64)) {
  1538.                     auto pImportByName = (PIMAGE_IMPORT_BY_NAME)PEHelpers::GetRvaPtr(
  1539.                         (DWORD)pThunk->u1.AddressOfData,
  1540.                         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1541.                         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1542.                         analyzer.lpFileContent,
  1543.                         analyzer.fileSize);
  1544.  
  1545.                     if (pImportByName && !IsBadReadPtr(pImportByName, sizeof(IMAGE_IMPORT_BY_NAME))) {
  1546.                         std::vector<wchar_t> wideFuncName(MAX_PATH);
  1547.                         MultiByteToWideChar(CP_ACP, 0, (char*)pImportByName->Name, -1,
  1548.                             wideFuncName.data(), MAX_PATH);
  1549.                         OUTPUT("\t\t%ls\n", wideFuncName.data());
  1550.                     }
  1551.                 }
  1552.                 else {
  1553.                     OUTPUT("\t\tOrdinal: %lld\n", pThunk->u1.Ordinal & 0xFFFF);
  1554.                 }
  1555.                 pThunk++;
  1556.             }
  1557.         }
  1558.         pImportDesc++;
  1559.     }
  1560. }
  1561.  
  1562. /*void ParseImportDirectory(const PEAnalyzer& analyzer) {
  1563.     if (analyzer.is64Bit) {
  1564.         ParseImportDirectory64(analyzer);
  1565.     }
  1566.     else {
  1567.         ParseImportDirectory32(analyzer);
  1568.     }
  1569. }*/ //removing the empty content duplicates
  1570. //}
  1571.  
  1572. void ParseExportDirectory32(const PEAnalyzer& analyzer) {
  1573.     const auto& exportDir = analyzer.pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
  1574.     if (!exportDir.VirtualAddress || !exportDir.Size) return;
  1575.  
  1576.     if (!PEHelpers::IsRvaValid(exportDir.VirtualAddress, analyzer.fileSize,
  1577.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32))) {
  1578.         OUTPUT("[-] Invalid export directory RVA!\n");
  1579.         throw std::runtime_error("RVA out of bounds");
  1580.         return;
  1581.     }
  1582.  
  1583.     OUTPUT("\n[+] EXPORT DIRECTORY (32-bit)\n");
  1584.     auto pExportDir = (PIMAGE_EXPORT_DIRECTORY)PEHelpers::GetRvaPtr(
  1585.         exportDir.VirtualAddress,
  1586.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1587.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1588.         analyzer.lpFileContent,
  1589.         analyzer.fileSize);
  1590.  
  1591.     if (!pExportDir || IsBadReadPtr(pExportDir, sizeof(IMAGE_EXPORT_DIRECTORY))) {
  1592.         OUTPUT("[-] Invalid export directory structure!\n");
  1593.         return;
  1594.     }
  1595.  
  1596.     OUTPUT("\tCharacteristics: 0x%X\n", pExportDir->Characteristics);
  1597.     OUTPUT("\tTimeDateStamp: 0x%X\n", pExportDir->TimeDateStamp);
  1598.     OUTPUT("\tMajorVersion: %d\n", pExportDir->MajorVersion);
  1599.     OUTPUT("\tMinorVersion: %d\n", pExportDir->MinorVersion);
  1600.     OUTPUT("\tName: 0x%X\n", pExportDir->Name);
  1601.     OUTPUT("\tBase: %d\n", pExportDir->Base);
  1602.     OUTPUT("\tNumberOfFunctions: %d\n", pExportDir->NumberOfFunctions);
  1603.     OUTPUT("\tNumberOfNames: %d\n", pExportDir->NumberOfNames);
  1604.     OUTPUT("\tAddressOfFunctions: 0x%X\n", pExportDir->AddressOfFunctions);
  1605.     OUTPUT("\tAddressOfNames: 0x%X\n", pExportDir->AddressOfNames);
  1606.     OUTPUT("\tAddressOfNameOrdinals: 0x%X\n\n", pExportDir->AddressOfNameOrdinals);
  1607.  
  1608.     auto pFunctions = (PDWORD)PEHelpers::GetRvaPtr(
  1609.         pExportDir->AddressOfFunctions,
  1610.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1611.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1612.         analyzer.lpFileContent,
  1613.         analyzer.fileSize);
  1614.  
  1615.     auto pNames = (PDWORD)PEHelpers::GetRvaPtr(
  1616.         pExportDir->AddressOfNames,
  1617.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1618.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1619.         analyzer.lpFileContent,
  1620.         analyzer.fileSize);
  1621.  
  1622.     auto pNameOrdinals = (PWORD)PEHelpers::GetRvaPtr(
  1623.         pExportDir->AddressOfNameOrdinals,
  1624.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1625.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1626.         analyzer.lpFileContent,
  1627.         analyzer.fileSize);
  1628.  
  1629.     if (!pNames || !pNameOrdinals || !pFunctions) {
  1630.         OUTPUT("[-] Invalid export address tables!\n");
  1631.         return;
  1632.     }
  1633.  
  1634.     OUTPUT("\tExported Functions:\n\n");
  1635.     for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {
  1636.         if (IsBadReadPtr(pNames + i, sizeof(DWORD)) ||
  1637.             IsBadReadPtr(pNameOrdinals + i, sizeof(WORD))) {
  1638.             break;
  1639.         }
  1640.  
  1641.         const char* functionName = (const char*)PEHelpers::GetRvaPtr(
  1642.             pNames[i],
  1643.             IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1644.             analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1645.             analyzer.lpFileContent,
  1646.             analyzer.fileSize);
  1647.  
  1648.         if (functionName && !IsBadReadPtr(functionName, 1)) {
  1649.             WORD ordinal = pNameOrdinals[i];
  1650.             if (ordinal < pExportDir->NumberOfFunctions) {
  1651.                 DWORD functionRva = pFunctions[ordinal];
  1652.  
  1653.                 // Check for forwarded export
  1654.                 if (functionRva >= exportDir.VirtualAddress &&
  1655.                     functionRva < (exportDir.VirtualAddress + exportDir.Size)) {
  1656.  
  1657.                     const char* forwardName = (const char*)PEHelpers::GetRvaPtr(
  1658.                         functionRva,
  1659.                         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1660.                         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1661.                         analyzer.lpFileContent,
  1662.                         analyzer.fileSize);
  1663.  
  1664.                     if (forwardName && !IsBadReadPtr(forwardName, 1)) {
  1665.                         std::vector<wchar_t> wideForwardName(MAX_PATH);
  1666.                         MultiByteToWideChar(CP_ACP, 0, forwardName, -1,
  1667.                             wideForwardName.data(), MAX_PATH);
  1668.                         OUTPUT("\t\t%ls (Ordinal: %d) -> Forward to: %ls\n",
  1669.                             functionName,
  1670.                             ordinal + pExportDir->Base,
  1671.                             wideForwardName.data());
  1672.                     }
  1673.                 }
  1674.                 else {
  1675.                     OUTPUT("\t\t%ls (Ordinal: %d, RVA: 0x%08X)\n",
  1676.                         functionName,
  1677.                         ordinal + pExportDir->Base,
  1678.                         functionRva);
  1679.                 }
  1680.             }
  1681.         }
  1682.     }
  1683. }
  1684.  
  1685. void ParseExportDirectory64(const PEAnalyzer& analyzer) {
  1686.     const auto& exportDir = analyzer.pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
  1687.     if (!exportDir.VirtualAddress || !exportDir.Size) return;
  1688.  
  1689.     if (!PEHelpers::IsRvaValid(exportDir.VirtualAddress, analyzer.fileSize,
  1690.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders64))) {
  1691.         OUTPUT("[-] Invalid export directory RVA!\n");
  1692.         throw std::runtime_error("RVA out of bounds");
  1693.         return;
  1694.     }
  1695.  
  1696.     OUTPUT("\n[+] EXPORT DIRECTORY (64-bit)\n");
  1697.     // Rest of the implementation is identical to 32-bit version
  1698.     // Just using pNtHeaders64 instead of pNtHeaders64
  1699.     auto pExportDir = (PIMAGE_EXPORT_DIRECTORY)PEHelpers::GetRvaPtr(
  1700.         exportDir.VirtualAddress,
  1701.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1702.         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1703.         analyzer.lpFileContent,
  1704.         analyzer.fileSize);
  1705.  
  1706.     if (!pExportDir || IsBadReadPtr(pExportDir, sizeof(IMAGE_EXPORT_DIRECTORY))) {
  1707.         OUTPUT("[-] Invalid export directory structure!\n");
  1708.         return;
  1709.     }
  1710.  
  1711.     OUTPUT("\tCharacteristics: 0x%X\n", pExportDir->Characteristics);
  1712.     OUTPUT("\tTimeDateStamp: 0x%X\n", pExportDir->TimeDateStamp);
  1713.     OUTPUT("\tMajorVersion: %d\n", pExportDir->MajorVersion);
  1714.     OUTPUT("\tMinorVersion: %d\n", pExportDir->MinorVersion);
  1715.     OUTPUT("\tName: 0x%X\n", pExportDir->Name);
  1716.     OUTPUT("\tBase: %d\n", pExportDir->Base);
  1717.     OUTPUT("\tNumberOfFunctions: %d\n", pExportDir->NumberOfFunctions);
  1718.     OUTPUT("\tNumberOfNames: %d\n", pExportDir->NumberOfNames);
  1719.     OUTPUT("\tAddressOfFunctions: 0x%X\n", pExportDir->AddressOfFunctions);
  1720.     OUTPUT("\tAddressOfNames: 0x%X\n", pExportDir->AddressOfNames);
  1721.     OUTPUT("\tAddressOfNameOrdinals: 0x%X\n\n", pExportDir->AddressOfNameOrdinals);
  1722.  
  1723.     auto pFunctions = (PDWORD)PEHelpers::GetRvaPtr(
  1724.         pExportDir->AddressOfFunctions,
  1725.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1726.         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1727.         analyzer.lpFileContent,
  1728.         analyzer.fileSize);
  1729.  
  1730.     auto pNames = (PDWORD)PEHelpers::GetRvaPtr(
  1731.         pExportDir->AddressOfNames,
  1732.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1733.         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1734.         analyzer.lpFileContent,
  1735.         analyzer.fileSize);
  1736.  
  1737.     auto pNameOrdinals = (PWORD)PEHelpers::GetRvaPtr(
  1738.         pExportDir->AddressOfNameOrdinals,
  1739.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1740.         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1741.         analyzer.lpFileContent,
  1742.         analyzer.fileSize);
  1743.  
  1744.     if (!pNames || !pNameOrdinals || !pFunctions) {
  1745.         OUTPUT("[-] Invalid export address tables!\n");
  1746.         return;
  1747.     }
  1748.  
  1749.     OUTPUT("\tExported Functions:\n\n");
  1750.     for (DWORD i = 0; i < pExportDir->NumberOfNames; i++) {
  1751.         if (IsBadReadPtr(pNames + i, sizeof(DWORD)) ||
  1752.             IsBadReadPtr(pNameOrdinals + i, sizeof(WORD))) {
  1753.             break;
  1754.         }
  1755.  
  1756.         const char* functionName = (const char*)PEHelpers::GetRvaPtr(
  1757.             pNames[i],
  1758.             IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1759.             analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1760.             analyzer.lpFileContent,
  1761.             analyzer.fileSize);
  1762.  
  1763.         if (functionName && !IsBadReadPtr(functionName, 1)) {
  1764.             WORD ordinal = pNameOrdinals[i];
  1765.             if (ordinal < pExportDir->NumberOfFunctions) {
  1766.                 DWORD functionRva = pFunctions[ordinal];
  1767.  
  1768.                 // Check for forwarded export
  1769.                 if (functionRva >= exportDir.VirtualAddress &&
  1770.                     functionRva < (exportDir.VirtualAddress + exportDir.Size)) {
  1771.  
  1772.                     const char* forwardName = (const char*)PEHelpers::GetRvaPtr(
  1773.                         functionRva,
  1774.                         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  1775.                         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  1776.                         analyzer.lpFileContent,
  1777.                         analyzer.fileSize);
  1778.  
  1779.                     if (forwardName && !IsBadReadPtr(forwardName, 1)) {
  1780.                         std::vector<wchar_t> wideForwardName(MAX_PATH);
  1781.                         MultiByteToWideChar(CP_ACP, 0, forwardName, -1,
  1782.                             wideForwardName.data(), MAX_PATH);
  1783.                         OUTPUT("\t\t%ls (Ordinal: %d) -> Forward to: %ls\n",
  1784.                             functionName,
  1785.                             ordinal + pExportDir->Base,
  1786.                             wideForwardName.data());
  1787.                     }
  1788.                 }
  1789.                 else {
  1790.                     OUTPUT("\t\t%ls (Ordinal: %d, RVA: 0x%08X)\n",
  1791.                         functionName,
  1792.                         ordinal + pExportDir->Base,
  1793.                         functionRva);
  1794.                 }
  1795.             }
  1796.         }
  1797.     }
  1798. }
  1799. // Copying the same logic as ParseExportDirectory32 but with 64-bit headers
  1800. // ... [Same implementation as above, just using pNtHeaders64]
  1801.  
  1802. /*void ParseExportDirectory(const PEAnalyzer& analyzer) {
  1803.     if (analyzer.is64Bit) {
  1804.         ParseExportDirectory64(analyzer);
  1805.     }
  1806.     else {
  1807.         ParseExportDirectory32(analyzer);
  1808.     }
  1809. }*/ //removing this duplicate
  1810.  
  1811. void ProcessResourceDirectory32(
  1812.     PIMAGE_RESOURCE_DIRECTORY resDir,
  1813.     int level,
  1814.     const wchar_t* type,
  1815.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  1816.     const wchar_t* resourceTypes[],
  1817.     const PEAnalyzer& analyzer)
  1818. {
  1819.     if (IsBadReadPtr(resDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
  1820.         return;
  1821.     }
  1822.  
  1823.     auto entry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resDir + 1);
  1824.     WORD totalEntries = resDir->NumberOfNamedEntries + resDir->NumberOfIdEntries;
  1825.  
  1826.     for (WORD i = 0; i < totalEntries; i++) {
  1827.         if (IsBadReadPtr(entry + i, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))) {
  1828.             break;
  1829.         }
  1830.  
  1831.         for (int indent = 0; indent < level; indent++) {
  1832.             OUTPUT("\t");
  1833.         }
  1834.  
  1835.         if (entry[i].NameIsString) {
  1836.             auto nameEntry = (PIMAGE_RESOURCE_DIR_STRING_U)((BYTE*)baseResourceDir + entry[i].NameOffset);
  1837.             if (!IsBadReadPtr(nameEntry, sizeof(IMAGE_RESOURCE_DIR_STRING_U))) {
  1838.                 std::vector<wchar_t> resourceName(nameEntry->Length + 1);
  1839.                 wcsncpy_s(resourceName.data(), nameEntry->Length + 1,
  1840.                     nameEntry->NameString, nameEntry->Length);
  1841.                 resourceName[nameEntry->Length] = L'\0';
  1842.  
  1843.                 if (level == 0) {
  1844.                     OUTPUT("Resource Type: Custom (%ls)\n", resourceName.data());
  1845.                 }
  1846.                 else {
  1847.                     OUTPUT("Name: %ls\n", resourceName.data());
  1848.                 }
  1849.             }
  1850.         }
  1851.         else {
  1852.             if (level == 0) {
  1853.                 DWORD resourceType = entry[i].Id;
  1854.                 if (resourceType < 16) {
  1855.                     OUTPUT("Resource Type: %ls (ID: %d)\n", resourceTypes[resourceType], resourceType);
  1856.                 }
  1857.                 else {
  1858.                     OUTPUT("Resource Type: Custom (ID: %d)\n", resourceType);
  1859.                 }
  1860.             }
  1861.             else {
  1862.                 OUTPUT("ID: %d\n", entry[i].Id);
  1863.             }
  1864.         }
  1865.  
  1866.         if (entry[i].DataIsDirectory) {
  1867.             auto nextDir = (PIMAGE_RESOURCE_DIRECTORY)((BYTE*)baseResourceDir + entry[i].OffsetToDirectory);
  1868.             if (!IsBadReadPtr(nextDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
  1869.                 ProcessResourceDirectory32(nextDir, level + 1,
  1870.                     level == 0 ? resourceTypes[min(entry[i].Id, 15)] : type,
  1871.                     baseResourceDir, resourceTypes, analyzer);
  1872.             }
  1873.         }
  1874.         else {
  1875.             auto dataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((BYTE*)baseResourceDir + entry[i].OffsetToData);
  1876.             if (!IsBadReadPtr(dataEntry, sizeof(IMAGE_RESOURCE_DATA_ENTRY))) {
  1877.                 for (int indent = 0; indent < level + 1; indent++) {
  1878.                     OUTPUT("\t");
  1879.                 }
  1880.                 OUTPUT("Size: %d bytes, RVA: 0x%X\n", dataEntry->Size, dataEntry->OffsetToData);
  1881.  
  1882.                 // Special handling for Version resources
  1883.                 if (type && wcscmp(type, L"Version") == 0) {
  1884.                     auto versionData = (BYTE*)PEHelpers::GetRvaPtr(
  1885.                         dataEntry->OffsetToData,
  1886.                         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1887.                         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1888.                         analyzer.lpFileContent,
  1889.                         analyzer.fileSize);
  1890.  
  1891.                     if (versionData && !IsBadReadPtr(versionData, sizeof(VS_FIXEDFILEINFO))) {
  1892.                         auto versionInfo = (VS_FIXEDFILEINFO*)(versionData + 40);
  1893.                         if (versionInfo->dwSignature == 0xFEEF04BD) {
  1894.                             for (int indent = 0; indent < level + 2; indent++) {
  1895.                                 OUTPUT("\t");
  1896.                             }
  1897.                             OUTPUT("File Version: %d.%d.%d.%d\n",
  1898.                                 HIWORD(versionInfo->dwFileVersionMS),
  1899.                                 LOWORD(versionInfo->dwFileVersionMS),
  1900.                                 HIWORD(versionInfo->dwFileVersionLS),
  1901.                                 LOWORD(versionInfo->dwFileVersionLS));
  1902.                         }
  1903.                     }
  1904.                 }
  1905.             }
  1906.         }
  1907.     }
  1908. }
  1909.  
  1910. void ProcessResourceDirectory64(
  1911.     PIMAGE_RESOURCE_DIRECTORY resDir,
  1912.     int level,
  1913.     const wchar_t* type,
  1914.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  1915.     const wchar_t* resourceTypes[],
  1916.     const PEAnalyzer& analyzer)
  1917. {
  1918.     // Similar to ProcessResourceDirectory32 but using 64-bit structures
  1919.     // Main difference is using analyzer.pNtHeaders64 instead of analyzer.pNtHeaders32
  1920.     if (IsBadReadPtr(resDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
  1921.         return;
  1922.         // Rest of the implementation follows the same pattern
  1923.     }
  1924.  
  1925.     auto entry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(resDir + 1);
  1926.     WORD totalEntries = resDir->NumberOfNamedEntries + resDir->NumberOfIdEntries;
  1927.  
  1928.     for (WORD i = 0; i < totalEntries; i++) {
  1929.         if (IsBadReadPtr(entry + i, sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY))) {
  1930.             break;
  1931.         }
  1932.  
  1933.         for (int indent = 0; indent < level; indent++) {
  1934.             OUTPUT("\t");
  1935.         }
  1936.  
  1937.         if (entry[i].NameIsString) {
  1938.             auto nameEntry = (PIMAGE_RESOURCE_DIR_STRING_U)((BYTE*)baseResourceDir + entry[i].NameOffset);
  1939.             if (!IsBadReadPtr(nameEntry, sizeof(IMAGE_RESOURCE_DIR_STRING_U))) {
  1940.                 std::vector<wchar_t> resourceName(nameEntry->Length + 1);
  1941.                 wcsncpy_s(resourceName.data(), nameEntry->Length + 1,
  1942.                     nameEntry->NameString, nameEntry->Length);
  1943.                 resourceName[nameEntry->Length] = L'\0';
  1944.  
  1945.                 if (level == 0) {
  1946.                     OUTPUT("Resource Type: Custom (%ls)\n", resourceName.data());
  1947.                 }
  1948.                 else {
  1949.                     OUTPUT("Name: %ls\n", resourceName.data());
  1950.                 }
  1951.             }
  1952.         }
  1953.         else {
  1954.             if (level == 0) {
  1955.                 DWORD resourceType = entry[i].Id;
  1956.                 if (resourceType < 16) {
  1957.                     OUTPUT("Resource Type: %ls (ID: %d)\n", resourceTypes[resourceType], resourceType);
  1958.                 }
  1959.                 else {
  1960.                     OUTPUT("Resource Type: Custom (ID: %d)\n", resourceType);
  1961.                 }
  1962.             }
  1963.             else {
  1964.                 OUTPUT("ID: %d\n", entry[i].Id);
  1965.             }
  1966.         }
  1967.  
  1968.         if (entry[i].DataIsDirectory) {
  1969.             auto nextDir = (PIMAGE_RESOURCE_DIRECTORY)((BYTE*)baseResourceDir + entry[i].OffsetToDirectory);
  1970.             if (!IsBadReadPtr(nextDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
  1971.                 ProcessResourceDirectory32(nextDir, level + 1,
  1972.                     level == 0 ? resourceTypes[min(entry[i].Id, 15)] : type,
  1973.                     baseResourceDir, resourceTypes, analyzer);
  1974.             }
  1975.         }
  1976.         else {
  1977.             auto dataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((BYTE*)baseResourceDir + entry[i].OffsetToData);
  1978.             if (!IsBadReadPtr(dataEntry, sizeof(IMAGE_RESOURCE_DATA_ENTRY))) {
  1979.                 for (int indent = 0; indent < level + 1; indent++) {
  1980.                     OUTPUT("\t");
  1981.                 }
  1982.                 OUTPUT("Size: %d bytes, RVA: 0x%X\n", dataEntry->Size, dataEntry->OffsetToData);
  1983.  
  1984.                 // Special handling for Version resources
  1985.                 if (type && wcscmp(type, L"Version") == 0) {
  1986.                     auto versionData = (BYTE*)PEHelpers::GetRvaPtr(
  1987.                         dataEntry->OffsetToData,
  1988.                         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  1989.                         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  1990.                         analyzer.lpFileContent,
  1991.                         analyzer.fileSize);
  1992.  
  1993.                     if (versionData && !IsBadReadPtr(versionData, sizeof(VS_FIXEDFILEINFO))) {
  1994.                         auto versionInfo = (VS_FIXEDFILEINFO*)(versionData + 40);
  1995.                         if (versionInfo->dwSignature == 0xFEEF04BD) {
  1996.                             for (int indent = 0; indent < level + 2; indent++) {
  1997.                                 OUTPUT("\t");
  1998.                             }
  1999.                             OUTPUT("File Version: %d.%d.%d.%d\n",
  2000.                                 HIWORD(versionInfo->dwFileVersionMS),
  2001.                                 LOWORD(versionInfo->dwFileVersionMS),
  2002.                                 HIWORD(versionInfo->dwFileVersionLS),
  2003.                                 LOWORD(versionInfo->dwFileVersionLS));
  2004.                         }
  2005.                     }
  2006.                 }
  2007.             }
  2008.         }
  2009.     }
  2010. }
  2011.  
  2012. void ParseResourceDirectory32(const PEAnalyzer& analyzer) {
  2013.     const auto& resourceDir = analyzer.pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
  2014.     if (!resourceDir.VirtualAddress || !resourceDir.Size) return;
  2015.  
  2016.     if (!PEHelpers::IsRvaValid(resourceDir.VirtualAddress, analyzer.fileSize,
  2017.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32))) {
  2018.         OUTPUT("[-] Invalid resource directory RVA!\n");
  2019.         throw std::runtime_error("RVA out of bounds");
  2020.         return;
  2021.     }
  2022.  
  2023.     OUTPUT("\n[+] RESOURCE DIRECTORY (32-bit)\n");
  2024.     auto pResourceDir = (PIMAGE_RESOURCE_DIRECTORY)PEHelpers::GetRvaPtr(
  2025.         resourceDir.VirtualAddress,
  2026.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  2027.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  2028.         analyzer.lpFileContent,
  2029.         analyzer.fileSize);
  2030.  
  2031.     if (!pResourceDir || IsBadReadPtr(pResourceDir, sizeof(IMAGE_RESOURCE_DIRECTORY))) {
  2032.         OUTPUT("[-] Invalid or corrupted resource directory\n");
  2033.         return;
  2034.     }
  2035.  
  2036.     const wchar_t* resourceTypes[] = {
  2037.         L"Unknown",     L"Cursor",      L"Bitmap",      L"Icon",
  2038.         L"Menu",        L"Dialog",      L"String",      L"FontDir",
  2039.         L"Font",        L"Accelerator", L"RCData",      L"MessageTable",
  2040.         L"GroupCursor", L"GroupIcon",   L"Version",     L"DlgInclude"
  2041.     };
  2042.  
  2043.     ProcessResourceDirectory32(pResourceDir, 0, nullptr, pResourceDir, resourceTypes, analyzer);
  2044. }
  2045.  
  2046. void ParseDebugDirectory32(const PEAnalyzer& analyzer) {
  2047.     const auto& debugDir = analyzer.pNtHeaders32->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
  2048.     if (!debugDir.VirtualAddress || !debugDir.Size) return;
  2049.  
  2050.     if (!PEHelpers::IsRvaValid(debugDir.VirtualAddress, analyzer.fileSize,
  2051.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders32))) {
  2052.         OUTPUT("[-] Invalid debug directory RVA!\n");
  2053.         throw std::runtime_error("RVA out of bounds");
  2054.         return;
  2055.     }
  2056.  
  2057.     OUTPUT("\n[+] DEBUG DIRECTORY (32-bit)\n");
  2058.     auto pDebugDir = (PIMAGE_DEBUG_DIRECTORY)PEHelpers::GetRvaPtr(
  2059.         debugDir.VirtualAddress,
  2060.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders32),
  2061.         analyzer.pNtHeaders32->FileHeader.NumberOfSections,
  2062.         analyzer.lpFileContent,
  2063.         analyzer.fileSize);
  2064.  
  2065.     if (!pDebugDir || IsBadReadPtr(pDebugDir, sizeof(IMAGE_DEBUG_DIRECTORY))) {
  2066.         OUTPUT("[-] Invalid debug directory structure!\n");
  2067.         return;
  2068.     }
  2069.  
  2070.     DWORD numEntries = min(debugDir.Size / sizeof(IMAGE_DEBUG_DIRECTORY), 16);
  2071.     for (DWORD i = 0; i < numEntries; i++) {
  2072.         OUTPUT("\tDebug Entry %d:\n", i + 1);
  2073.         OUTPUT("\tCharacteristics: 0x%X\n", pDebugDir[i].Characteristics);
  2074.         OUTPUT("\tTimeDateStamp: 0x%X\n", pDebugDir[i].TimeDateStamp);
  2075.         OUTPUT("\tMajorVersion: %d\n", pDebugDir[i].MajorVersion);
  2076.         OUTPUT("\tMinorVersion: %d\n", pDebugDir[i].MinorVersion);
  2077.         OUTPUT("\tType: 0x%X", pDebugDir[i].Type);
  2078.  
  2079.         switch (pDebugDir[i].Type) {
  2080.         case IMAGE_DEBUG_TYPE_COFF:
  2081.             OUTPUT(" (COFF)\n"); break;
  2082.         case IMAGE_DEBUG_TYPE_CODEVIEW:
  2083.             OUTPUT(" (CodeView)\n"); break;
  2084.         case IMAGE_DEBUG_TYPE_FPO:
  2085.             OUTPUT(" (FPO)\n"); break;
  2086.         case IMAGE_DEBUG_TYPE_MISC:
  2087.             OUTPUT(" (Misc)\n"); break;
  2088.         case IMAGE_DEBUG_TYPE_EXCEPTION:
  2089.             OUTPUT(" (Exception)\n"); break;
  2090.         case IMAGE_DEBUG_TYPE_FIXUP:
  2091.             OUTPUT(" (Fixup)\n"); break;
  2092.         case IMAGE_DEBUG_TYPE_OMAP_TO_SRC:
  2093.             OUTPUT(" (OMAP to Src)\n"); break;
  2094.         case IMAGE_DEBUG_TYPE_OMAP_FROM_SRC:
  2095.             OUTPUT(" (OMAP from Src)\n"); break;
  2096.         case IMAGE_DEBUG_TYPE_BORLAND:
  2097.             OUTPUT(" (Borland)\n"); break;
  2098.         default:
  2099.             OUTPUT(" (Unknown)\n"); break;
  2100.         }
  2101.  
  2102.         OUTPUT("\tSizeOfData: 0x%X\n", pDebugDir[i].SizeOfData);
  2103.         OUTPUT("\tAddressOfRawData: 0x%X\n", pDebugDir[i].AddressOfRawData);
  2104.         OUTPUT("\tPointerToRawData: 0x%X\n\n", pDebugDir[i].PointerToRawData);
  2105.  
  2106.         // Special handling for CodeView debug information
  2107.         if (pDebugDir[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW &&
  2108.             pDebugDir[i].PointerToRawData != 0 &&
  2109.             pDebugDir[i].SizeOfData >= sizeof(DWORD)) {
  2110.  
  2111.             auto pCVHeader = (DWORD*)((BYTE*)analyzer.lpFileContent + pDebugDir[i].PointerToRawData);
  2112.             if (!IsBadReadPtr(pCVHeader, sizeof(DWORD))) {
  2113.                 switch (*pCVHeader) {
  2114.                 case 0x53445352: // 'RSDS'
  2115.                     if (pDebugDir[i].SizeOfData >= (sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD) + 1)) {
  2116.                         auto pCVData = (char*)(pCVHeader + 1);
  2117.                         if (!IsBadReadPtr(pCVData + 16, 1)) {
  2118.                             auto guid = (GUID*)pCVData;
  2119.                             DWORD age = *(DWORD*)(pCVData + 16);
  2120.                             const char* pdbPath = pCVData + 20;
  2121.  
  2122.                             OUTPUT("\tPDB Information:\n");
  2123.                             OUTPUT("\tGUID: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
  2124.                                 guid->Data1, guid->Data2, guid->Data3,
  2125.                                 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
  2126.                                 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
  2127.                             OUTPUT("\tAge: %d\n", age);
  2128.                             OUTPUT("\tPDB Path: %ls\n\n", pdbPath);
  2129.                         }
  2130.                     }
  2131.                     break;
  2132.  
  2133.                 case 0x3031424E: // 'NB10'
  2134.                     if (pDebugDir[i].SizeOfData >= 16) {
  2135.                         auto pNB10Data = (char*)(pCVHeader + 1);
  2136.                         DWORD offset = *(DWORD*)pNB10Data;
  2137.                         DWORD timestamp = *(DWORD*)(pNB10Data + 4);
  2138.                         DWORD age = *(DWORD*)(pNB10Data + 8);
  2139.                         const char* pdbPath = pNB10Data + 12;
  2140.  
  2141.                         OUTPUT("\tPDB Information (NB10):\n");
  2142.                         OUTPUT("\tOffset: 0x%X\n", offset);
  2143.                         OUTPUT("\tTimestamp: 0x%X\n", timestamp);
  2144.                         OUTPUT("\tAge: %d\n", age);
  2145.                         OUTPUT("\tPDB Path: %ls\n\n", pdbPath);
  2146.                     }
  2147.                     break;
  2148.                 }
  2149.             }
  2150.         }
  2151.     }
  2152. }
  2153.  
  2154. void ParseDebugDirectory64(const PEAnalyzer& analyzer) {
  2155.     const auto& debugDir = analyzer.pNtHeaders64->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
  2156.     if (!debugDir.VirtualAddress || !debugDir.Size) return;
  2157.  
  2158.     if (!PEHelpers::IsRvaValid(debugDir.VirtualAddress, analyzer.fileSize,
  2159.         reinterpret_cast<PIMAGE_NT_HEADERS>(analyzer.pNtHeaders64))) {
  2160.         OUTPUT("[-] Invalid debug directory RVA!\n");
  2161.         throw std::runtime_error("RVA out of bounds");
  2162.         return;
  2163.     }
  2164.  
  2165.     OUTPUT("\n[+] DEBUG DIRECTORY (64-bit)\n");
  2166.     // Rest of implementation follows same pattern as 32-bit version
  2167.     // Just using pNtHeaders64 instead of pNtHeaders32
  2168.     auto pDebugDir = (PIMAGE_DEBUG_DIRECTORY)PEHelpers::GetRvaPtr(
  2169.         debugDir.VirtualAddress,
  2170.         IMAGE_FIRST_SECTION(analyzer.pNtHeaders64),
  2171.         analyzer.pNtHeaders64->FileHeader.NumberOfSections,
  2172.         analyzer.lpFileContent,
  2173.         analyzer.fileSize);
  2174.  
  2175.     if (!pDebugDir || IsBadReadPtr(pDebugDir, sizeof(IMAGE_DEBUG_DIRECTORY))) {
  2176.         OUTPUT("[-] Invalid debug directory structure!\n");
  2177.         return;
  2178.     }
  2179.  
  2180.     DWORD numEntries = min(debugDir.Size / sizeof(IMAGE_DEBUG_DIRECTORY), 16);
  2181.     for (DWORD i = 0; i < numEntries; i++) {
  2182.         OUTPUT("\tDebug Entry %d:\n", i + 1);
  2183.         OUTPUT("\tCharacteristics: 0x%X\n", pDebugDir[i].Characteristics);
  2184.         OUTPUT("\tTimeDateStamp: 0x%X\n", pDebugDir[i].TimeDateStamp);
  2185.         OUTPUT("\tMajorVersion: %d\n", pDebugDir[i].MajorVersion);
  2186.         OUTPUT("\tMinorVersion: %d\n", pDebugDir[i].MinorVersion);
  2187.         OUTPUT("\tType: 0x%X", pDebugDir[i].Type);
  2188.  
  2189.         switch (pDebugDir[i].Type) {
  2190.         case IMAGE_DEBUG_TYPE_COFF:
  2191.             OUTPUT(" (COFF)\n"); break;
  2192.         case IMAGE_DEBUG_TYPE_CODEVIEW:
  2193.             OUTPUT(" (CodeView)\n"); break;
  2194.         case IMAGE_DEBUG_TYPE_FPO:
  2195.             OUTPUT(" (FPO)\n"); break;
  2196.         case IMAGE_DEBUG_TYPE_MISC:
  2197.             OUTPUT(" (Misc)\n"); break;
  2198.         case IMAGE_DEBUG_TYPE_EXCEPTION:
  2199.             OUTPUT(" (Exception)\n"); break;
  2200.         case IMAGE_DEBUG_TYPE_FIXUP:
  2201.             OUTPUT(" (Fixup)\n"); break;
  2202.         case IMAGE_DEBUG_TYPE_OMAP_TO_SRC:
  2203.             OUTPUT(" (OMAP to Src)\n"); break;
  2204.         case IMAGE_DEBUG_TYPE_OMAP_FROM_SRC:
  2205.             OUTPUT(" (OMAP from Src)\n"); break;
  2206.         case IMAGE_DEBUG_TYPE_BORLAND:
  2207.             OUTPUT(" (Borland)\n"); break;
  2208.         default:
  2209.             OUTPUT(" (Unknown)\n"); break;
  2210.         }
  2211.  
  2212.         OUTPUT("\tSizeOfData: 0x%X\n", pDebugDir[i].SizeOfData);
  2213.         OUTPUT("\tAddressOfRawData: 0x%X\n", pDebugDir[i].AddressOfRawData);
  2214.         OUTPUT("\tPointerToRawData: 0x%X\n\n", pDebugDir[i].PointerToRawData);
  2215.  
  2216.         // Special handling for CodeView debug information
  2217.         if (pDebugDir[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW &&
  2218.             pDebugDir[i].PointerToRawData != 0 &&
  2219.             pDebugDir[i].SizeOfData >= sizeof(DWORD)) {
  2220.  
  2221.             auto pCVHeader = (DWORD*)((BYTE*)analyzer.lpFileContent + pDebugDir[i].PointerToRawData);
  2222.             if (!IsBadReadPtr(pCVHeader, sizeof(DWORD))) {
  2223.                 switch (*pCVHeader) {
  2224.                 case 0x53445352: // 'RSDS'
  2225.                     if (pDebugDir[i].SizeOfData >= (sizeof(DWORD) + sizeof(GUID) + sizeof(DWORD) + 1)) {
  2226.                         auto pCVData = (char*)(pCVHeader + 1);
  2227.                         if (!IsBadReadPtr(pCVData + 16, 1)) {
  2228.                             auto guid = (GUID*)pCVData;
  2229.                             DWORD age = *(DWORD*)(pCVData + 16);
  2230.                             const char* pdbPath = pCVData + 20;
  2231.  
  2232.                             OUTPUT("\tPDB Information:\n");
  2233.                             OUTPUT("\tGUID: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\n",
  2234.                                 guid->Data1, guid->Data2, guid->Data3,
  2235.                                 guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
  2236.                                 guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
  2237.                             OUTPUT("\tAge: %d\n", age);
  2238.                             OUTPUT("\tPDB Path: %ls\n\n", pdbPath);
  2239.                         }
  2240.                     }
  2241.                     break;
  2242.  
  2243.                 case 0x3031424E: // 'NB10'
  2244.                     if (pDebugDir[i].SizeOfData >= 16) {
  2245.                         auto pNB10Data = (char*)(pCVHeader + 1);
  2246.                         DWORD offset = *(DWORD*)pNB10Data;
  2247.                         DWORD timestamp = *(DWORD*)(pNB10Data + 4);
  2248.                         DWORD age = *(DWORD*)(pNB10Data + 8);
  2249.                         const char* pdbPath = pNB10Data + 12;
  2250.  
  2251.                         OUTPUT("\tPDB Information (NB10):\n");
  2252.                         OUTPUT("\tOffset: 0x%X\n", offset);
  2253.                         OUTPUT("\tTimestamp: 0x%X\n", timestamp);
  2254.                         OUTPUT("\tAge: %d\n", age);
  2255.                         OUTPUT("\tPDB Path: %ls\n\n", pdbPath);
  2256.                     }
  2257.                     break;
  2258.                 }
  2259.             }
  2260.         }
  2261.     }
  2262. }
  2263. // ... [Same implementation as ParseDebugDirectory32]
  2264.  
  2265. //newfunctionshere (lateest fixes)
  2266.  
  2267.  
  2268. void ProcessResourceDirectory32(
  2269.     PIMAGE_RESOURCE_DIRECTORY resDir,
  2270.     int level,
  2271.     const wchar_t* type,
  2272.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  2273.     const wchar_t* resourceTypes[],
  2274.     const PEAnalyzer& analyzer);
  2275.  
  2276. void ProcessResourceDirectory64(
  2277.     PIMAGE_RESOURCE_DIRECTORY resDir,
  2278.     int level,
  2279.     const wchar_t* type,
  2280.     PIMAGE_RESOURCE_DIRECTORY baseResourceDir,
  2281.     const wchar_t* resourceTypes[],
  2282.     const PEAnalyzer& analyzer);
  2283.  
  2284. // Main window class name
  2285. //const char* const WINDOW_CLASS_NAME = "PEAnalyzerWindow";
  2286.  
  2287. //new inserted here >>
  2288.  
  2289. // Page Break
  2290.  
  2291. //here
  2292.  
  2293. // Page Break
  2294.  
  2295. void AddMenus(HWND hwnd) {
  2296.     HMENU hMenuBar = CreateMenu();
  2297.     HMENU hFileMenu = CreateMenu();
  2298.     AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hFileMenu, L"&File");
  2299.     AppendMenu(hFileMenu, MF_STRING, 1, L"&Open\tCtrl+O");  // Updated to show shortcut
  2300.     AppendMenu(hFileMenu, MF_STRING, 2, L"&Select All\tCtrl+A");
  2301.     AppendMenu(hFileMenu, MF_STRING, 3, L"E&xit\tAlt+F4");
  2302.     EnableMenuItem(hFileMenu, 2, MF_BYCOMMAND | MF_GRAYED);
  2303.     //EnableMenuItem(hFileMenu, ID_FILE_SELECTALL, MF_BYCOMMAND | MF_GRAYED);
  2304.     SetMenu(hwnd, hMenuBar);
  2305. }
  2306.  
  2307. /*void AddMenus(HWND hwnd) {
  2308.     HMENU hMenuBar = CreateMenu();
  2309.     HMENU hFileMenu = CreateMenu();
  2310.  
  2311.     // Create the File menu using the defined IDs.
  2312.     AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hFileMenu, L"&File");
  2313.     AppendMenu(hFileMenu, MF_STRING, ID_FILE_OPEN, L"&Open\tCtrl+O");
  2314.     AppendMenu(hFileMenu, MF_STRING, ID_FILE_SELECTALL, L"&Select All");
  2315.     AppendMenu(hFileMenu, MF_STRING, ID_FILE_EXIT, L"E&xit");
  2316.  
  2317.     // Initially disable the "Select All" menu item.
  2318.     EnableMenuItem(hFileMenu, ID_FILE_SELECTALL, MF_BYCOMMAND | MF_GRAYED);
  2319.     SetMenu(hwnd, hMenuBar);
  2320. }*/
  2321.  
  2322. // First, add this helper function to determine if the PE file is 64-bit
  2323. bool Is64BitPE(PIMAGE_NT_HEADERS pNtHeaders) {
  2324.     return pNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;
  2325. } //removing this duplicate
  2326.  
  2327. // Helper function to safely get file size
  2328. /*DWORD GetFileSizeCustom(const wchar_t* filePath) {
  2329.     HANDLE hFile = CreateFileW(filePath, GENERIC_READ, FILE_SHARE_READ,
  2330.         nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  2331.  
  2332.     if (hFile == INVALID_HANDLE_VALUE) {
  2333.         return 0;
  2334.     }
  2335.  
  2336.     DWORD fileSize = ::GetFileSize(hFile, nullptr);
  2337.     CloseHandle(hFile);
  2338.     return fileSize;
  2339. }*/ //removing this duplicate instead
  2340.  
  2341. // Add this helper function
  2342. void SafeOutput(const std::wstring& text) {
  2343.     try {
  2344.         g_OutputText << text;
  2345.         UpdateEditControl();
  2346.     }
  2347.     catch (...) {
  2348.         SetStatusText(L"Error writing output");
  2349.     }
  2350. }
  2351.  
  2352. void UpdateStatusBar(const wchar_t* text, int progress = -1) {
  2353.     if (text) {
  2354.         SetStatusText(text);
  2355.     }
  2356.     if (progress >= 0) {
  2357.         ShowProgress(progress);
  2358.     }
  2359. }
  2360.  
  2361. void ClearProgress() {
  2362.     ShowWindow(g_hProgressBar, SW_HIDE);
  2363.     SetStatusText(L"Ready");
  2364. }
  2365.  
  2366.  
  2367.  
  2368. void SetStatusText(const wchar_t* text) {
  2369.     SendMessage(g_hStatusBar, SB_SETTEXT, 0, (LPARAM)text);
  2370. }
  2371.  
  2372. void ShowProgress(int percentage) {
  2373.     if (percentage < 0 || percentage > 100) {
  2374.         OUTPUT("[-] Invalid progress percentage: %d\n", percentage);
  2375.         return;
  2376.     }
  2377.  
  2378.     SendMessage(g_hProgressBar, PBM_SETPOS, (WPARAM)percentage, 0);
  2379.     wchar_t status[256];
  2380.     swprintf_s(status, L"Analyzing... %d%%", percentage);
  2381.     SetStatusText(status);
  2382.     SendMessage(g_hStatusBar, SB_SETTEXT, 0, (LPARAM)status);
  2383. }
  2384.  
  2385. void OpenFileDialog(HWND hwnd) {
  2386.     WCHAR fileName[MAX_PATH] = L"";
  2387.     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 };
  2388.     if (GetOpenFileNameW(&ofn)) {
  2389.         SetWindowTextW(g_hEditControl, L"");
  2390.         g_OutputText.str(L"");
  2391.         g_OutputText.clear();
  2392.         AnalyzePEFile(ofn.lpstrFile);
  2393.         UpdateEditControl();
  2394.     }
  2395. }
  2396.  
  2397.  
  2398. // Modified AppendToOutput to handle newlines properly:
  2399. void AppendToOutput(const wchar_t* format, ...) {
  2400.     std::vector<wchar_t> buffer(4096); //recent 19/2/25 (1024)*
  2401.     va_list args;
  2402.     va_start(args, format);
  2403.  
  2404.     while (true) {
  2405.         va_list argsCopy;
  2406.         va_copy(argsCopy, args);
  2407.         int result = _vsnwprintf(buffer.data(), buffer.size(), format, argsCopy);
  2408.         va_end(argsCopy);
  2409.         if (result >= 0) break;
  2410.         buffer.resize(buffer.size() * 2);
  2411.     }
  2412.     va_end(args);
  2413.  
  2414.     // Convert \n to \r\n
  2415.     std::wstring output = buffer.data();
  2416.     size_t pos = 0;
  2417.     while ((pos = output.find(L'\n', pos)) != std::wstring::npos) {
  2418.         if (pos == 0 || output[pos - 1] != L'\r') {
  2419.             output.insert(pos, L"\r");
  2420.             pos += 2;
  2421.         }
  2422.         else {
  2423.             pos++;
  2424.         }
  2425.     }
  2426.  
  2427.     g_OutputText << output;
  2428.     UpdateEditControl();
  2429. }
  2430.  
  2431.  
  2432. //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    
  2433.  
  2434. //adding here
  2435. // Line Break
  2436. // new code below starting here vv
  2437.  
  2438.  
  2439.  
  2440. DWORD GetFileSize(const wchar_t* filePath) {
  2441.     HANDLE hFile = CreateFileW(filePath, GENERIC_READ, FILE_SHARE_READ,
  2442.         nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  2443.     if (hFile == INVALID_HANDLE_VALUE) return 0;
  2444.  
  2445.     DWORD fileSize = ::GetFileSize(hFile, nullptr);
  2446.     CloseHandle(hFile);
  2447.     return fileSize;
  2448. }
  2449. //}
  2450. // Page Break
  2451.  
  2452. //}
  2453.  
  2454. //UpdateEditControl();
  2455. //}
  2456.  
  2457. // new code upto here ending here ^^
  2458. // Line Break
  2459. //  //end adding here
  2460.  
  2461.  
  2462.  
  2463. //filePathW
  2464. //lpFilePath
  2465. /*
  2466. HANDLE GetFileContent(const wchar_t* lpFilePath) {
  2467.     HANDLE hFile = CreateFileW(lpFilePath, GENERIC_READ, 0, nullptr, OPEN_EXISTING, 0, nullptr);
  2468.     if (hFile == INVALID_HANDLE_VALUE) return nullptr;
  2469.     DWORD fileSize = ::GetFileSize(hFile, nullptr);
  2470.     auto lpFileContent = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, fileSize);
  2471.     DWORD bytesRead;
  2472.     ReadFile(hFile, lpFileContent, fileSize, &bytesRead, nullptr);
  2473.     CloseHandle(hFile);
  2474.     return lpFileContent;
  2475. }
  2476. */
  2477.  
  2478. void UpdateEditControl() {
  2479.     SetWindowTextW(g_hEditControl, g_OutputText.str().c_str());
  2480.     SendMessage(g_hEditControl, EM_SETSEL, -1, -1);
  2481.     SendMessage(g_hEditControl, EM_SCROLLCARET, 0, 0);
  2482. }
  2483. //}
  2484.  
  2485. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
  2486.     INITCOMMONCONTROLSEX icc = { sizeof(INITCOMMONCONTROLSEX), ICC_WIN95_CLASSES };
  2487.     InitCommonControlsEx(&icc);
  2488.  
  2489.     // Get command line parameters in Unicode
  2490.     int argc;
  2491.     LPWSTR* argv = CommandLineToArgvW(GetCommandLineW(), &argc);
  2492.  
  2493.     CreateMainWindow(hInstance);
  2494.     if (!g_hMainWindow) {
  2495.         LocalFree(argv);
  2496.         return -1;
  2497.     }
  2498.  
  2499.     ShowWindow(g_hMainWindow, nCmdShow);
  2500.     UpdateWindow(g_hMainWindow);
  2501.     SetWindowPos(g_hMainWindow, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  2502.  
  2503.     // If there's a command line parameter, process it
  2504.     if (argc > 1) {
  2505.         // Process the first parameter as file path
  2506.         SetWindowTextW(g_hEditControl, L"");
  2507.         g_OutputText.str(L"");
  2508.         g_OutputText.clear();
  2509.         AnalyzePEFile(argv[1]);
  2510.         UpdateEditControl();
  2511.     }
  2512.  
  2513.     LocalFree(argv);
  2514.  
  2515.     MSG msg = {};
  2516.     while (GetMessage(&msg, NULL, 0, 0)) {
  2517.         TranslateMessage(&msg);
  2518.         DispatchMessage(&msg);
  2519.     }
  2520.  
  2521.     if (g_hFont) DeleteObject(g_hFont);
  2522.     return (int)msg.wParam;
  2523. }
  2524.  
  2525. void CreateMainWindow(HINSTANCE hInstance) {
  2526.     WNDCLASSEXW wc = { sizeof(WNDCLASSEXW), 0, WindowProc, 0, 0, hInstance,
  2527.         LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)),
  2528.         LoadCursor(NULL, IDC_ARROW),
  2529.         (HBRUSH)(COLOR_WINDOW + 1),
  2530.         NULL, WINDOW_CLASS_NAME,
  2531.         LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1)) };
  2532.     RegisterClassExW(&wc);
  2533.  
  2534.     // Get screen dimensions
  2535.     int screenWidth = GetSystemMetrics(SM_CXSCREEN);
  2536.     int screenHeight = GetSystemMetrics(SM_CYSCREEN);
  2537.  
  2538.     // Calculate center position
  2539.     int windowX = (screenWidth - WINDOW_WIDTH) / 2;
  2540.     int windowY = (screenHeight - WINDOW_HEIGHT) / 2;
  2541.  
  2542.     // Remove WS_MAXIMIZEBOX and WS_THICKFRAME from the window style
  2543.     DWORD style = (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX) & ~WS_THICKFRAME;
  2544.     //WS_OVERLAPPEDWINDOW ~~> style
  2545.     g_hMainWindow = CreateWindowExW(0, WINDOW_CLASS_NAME, L"PE File Analyzer v6.6",
  2546.         style, windowX, windowY, WINDOW_WIDTH, WINDOW_HEIGHT,
  2547.         nullptr, nullptr, hInstance, nullptr);
  2548. }
  2549.  
  2550. void InitializeControls(HWND hwnd) {
  2551.     // Create status bar
  2552.     g_hStatusBar = CreateWindowEx(0, STATUSCLASSNAME, NULL,
  2553.         WS_CHILD | WS_VISIBLE,
  2554.         0, 0, 0, 0, hwnd, NULL,
  2555.         (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
  2556.  
  2557.     // Set up status bar parts
  2558.     RECT rcClient;
  2559.     GetClientRect(hwnd, &rcClient);
  2560.     int statusParts[2] = { 150, rcClient.right };
  2561.     SendMessage(g_hStatusBar, SB_SETPARTS, 2, (LPARAM)statusParts);
  2562.  
  2563.     // Create progress bar in the second part of status bar
  2564.     RECT rcPart;
  2565.     SendMessage(g_hStatusBar, SB_GETRECT, 1, (LPARAM)&rcPart);
  2566.  
  2567.     g_hProgressBar = CreateWindowEx(0, PROGRESS_CLASS, NULL,
  2568.         WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
  2569.         rcPart.left + 5, rcPart.top + 2,
  2570.         rcPart.right - rcPart.left - 10, rcPart.bottom - rcPart.top - 4,
  2571.         g_hStatusBar, NULL,
  2572.         (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
  2573.  
  2574.     // Set blue color and range
  2575.     SendMessage(g_hProgressBar, PBM_SETBARCOLOR, 0, (LPARAM)RGB(0, 120, 215));  // Windows 10 blue
  2576.     SendMessage(g_hProgressBar, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
  2577.     SendMessage(g_hProgressBar, PBM_SETSTEP, 1, 0);
  2578.  
  2579.     // Get status bar height for edit control positioning
  2580.     RECT rcStatus;
  2581.     GetWindowRect(g_hStatusBar, &rcStatus);
  2582.     int statusHeight = rcStatus.bottom - rcStatus.top;
  2583.  
  2584.     // Create edit control
  2585.     g_hEditControl = CreateWindowExW(WS_EX_CLIENTEDGE, L"EDIT", L"",
  2586.         WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL |
  2587.         ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL,
  2588.         EDIT_MARGIN, EDIT_MARGIN,
  2589.         rcClient.right - (2 * EDIT_MARGIN),
  2590.         rcClient.bottom - statusHeight - (2 * EDIT_MARGIN),
  2591.         hwnd, nullptr,
  2592.         (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), nullptr);
  2593.  
  2594.     // Allow the edit control to accept dropped files.
  2595.     DragAcceptFiles(g_hEditControl, TRUE);
  2596.  
  2597.     // Create and set font
  2598.     g_hFont = CreateFont(-14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, 0,
  2599.         ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
  2600.         DEFAULT_QUALITY, DEFAULT_PITCH | FF_MODERN, L"Consolas");
  2601.  
  2602.     if (g_hFont)
  2603.         SendMessage(g_hEditControl, WM_SETFONT, (WPARAM)g_hFont, TRUE);
  2604.  
  2605.     SetWindowSubclass(g_hEditControl, EditSubclassProc, 0, 0);
  2606. }
  2607.  
  2608. LRESULT CALLBACK EditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData) {
  2609.     if (uMsg == WM_KEYDOWN) {
  2610.         if ((GetKeyState(VK_CONTROL) & 0x8000) && wParam == 'O') {
  2611.             SendMessage(GetParent(hwnd), WM_COMMAND, 1, 0);
  2612.             return 0;
  2613.         }
  2614.         switch (wParam) {
  2615.         case VK_F1:
  2616.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_F1, 0);
  2617.             return 0;
  2618.         case VK_ESCAPE:
  2619.             SendMessage(GetParent(hwnd), WM_KEYDOWN, VK_ESCAPE, 0);
  2620.             return 0;
  2621.         case VK_PRIOR:
  2622.             // Scroll up
  2623.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
  2624.             return 0;
  2625.         case VK_NEXT:
  2626.             // Scroll down
  2627.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
  2628.             return 0;
  2629.         case VK_UP:
  2630.             // Scroll one line up
  2631.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0);
  2632.             return 0;
  2633.         case VK_DOWN:
  2634.             // Scroll one line down
  2635.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0);
  2636.             return 0;
  2637.         }
  2638.     }
  2639.     if (uMsg == WM_MOUSEWHEEL) {
  2640.         int delta = GET_WHEEL_DELTA_WPARAM(wParam);
  2641.         if (delta > 0) {
  2642.             // Scroll up
  2643.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
  2644.         }
  2645.         else {
  2646.             // Scroll down
  2647.             SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
  2648.         }
  2649.         return 0;
  2650.     }
  2651.     // Check for Ctrl+A: the 'A' key (wParam == 'A') along with the CTRL key held down.
  2652.     if (wParam == 'A' && (GetKeyState(VK_CONTROL) & 0x8000))
  2653.     {
  2654.         // Select all text in the edit control.
  2655.         SendMessage(hwnd, EM_SETSEL, 0, -1);
  2656.         return 0; // indicate that the message has been handled.
  2657.     }
  2658.     // Handle file drops
  2659.     if (uMsg == WM_DROPFILES) {
  2660.         HDROP hDrop = (HDROP)wParam;
  2661.         UINT fileCount = DragQueryFileW(hDrop, 0xFFFFFFFF, NULL, 0);
  2662.         if (fileCount > 0) {
  2663.             wchar_t filePath[MAX_PATH];
  2664.             if (DragQueryFileW(hDrop, 0, filePath, MAX_PATH)) {
  2665.                 // Call your file analysis function with the dropped file path.
  2666.                 AnalyzePEFile(filePath);
  2667.             }
  2668.         }
  2669.         DragFinish(hDrop);
  2670.         return 0; // Indicate that the message was handled.
  2671.     }
  2672.     return DefSubclassProc(hwnd, uMsg, wParam, lParam);
  2673. }
  2674.  
  2675. LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  2676.     switch (uMsg) {
  2677.     case WM_CREATE: InitializeControls(hwnd); AddMenus(hwnd); return 0;
  2678.     case WM_SIZE:
  2679.     {
  2680.         RECT rcClient;
  2681.         GetClientRect(hwnd, &rcClient);
  2682.  
  2683.         // Resize status bar
  2684.         SendMessage(g_hStatusBar, WM_SIZE, 0, 0);
  2685.  
  2686.         // Recalculate status bar parts
  2687.         int statusParts[2] = { 150, rcClient.right };
  2688.         SendMessage(g_hStatusBar, SB_SETPARTS, 2, (LPARAM)statusParts);
  2689.  
  2690.         // Reposition progress bar
  2691.         RECT rcPart;
  2692.         SendMessage(g_hStatusBar, SB_GETRECT, 1, (LPARAM)&rcPart);
  2693.         SetWindowPos(g_hProgressBar, NULL,
  2694.             rcPart.left + 5, rcPart.top + 2,
  2695.             rcPart.right - rcPart.left - 10, rcPart.bottom - rcPart.top - 4,
  2696.             SWP_NOZORDER);
  2697.  
  2698.         // Get status bar height
  2699.         RECT rcStatus;
  2700.         GetWindowRect(g_hStatusBar, &rcStatus);
  2701.         int statusHeight = rcStatus.bottom - rcStatus.top;
  2702.  
  2703.         // Resize edit control
  2704.         SetWindowPos(g_hEditControl, NULL,
  2705.             EDIT_MARGIN,
  2706.             EDIT_MARGIN,
  2707.             rcClient.right - (2 * EDIT_MARGIN),
  2708.             rcClient.bottom - statusHeight - (2 * EDIT_MARGIN),
  2709.             SWP_NOZORDER);
  2710.  
  2711.         if (wParam == SIZE_MINIMIZED)
  2712.         {
  2713.             SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  2714.         }
  2715.         else
  2716.         {
  2717.             SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
  2718.         }
  2719.  
  2720.         return 0;
  2721.     }
  2722.  
  2723.     case WM_KEYDOWN:
  2724.     {
  2725.         if (GetKeyState(VK_CONTROL) & 0x8000) {
  2726.             switch (wParam) {
  2727.             case 'O':
  2728.                 OpenFileDialog(hwnd);
  2729.                 return 0;
  2730.             }
  2731.         }
  2732.         switch (wParam) {
  2733.         case VK_F1:
  2734.             MessageBoxW(hwnd,
  2735.                 L"PE Header Parser 6.6 GUI-based Programmed in C++ Win32 API (2834+ lines of code) by Entisoft Software (c) Evans Thorpemorton.\nFiles can be #1 Drag & Dropped #2 File Menu > Open Dialog #3 Command-Line Argument FilePath #4 Ctrl+O Hotkey",
  2736.                 L"About",
  2737.                 MB_OK | MB_ICONINFORMATION);
  2738.             return 0;
  2739.         case VK_ESCAPE:
  2740.             PostQuitMessage(0);
  2741.             return 0;
  2742.         case VK_PRIOR:
  2743.             // Scroll up
  2744.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
  2745.             return 0;
  2746.         case VK_NEXT:
  2747.             // Scroll down
  2748.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
  2749.             return 0;
  2750.         case VK_UP:
  2751.             // Scroll one line up
  2752.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_LINEUP, 0), 0);
  2753.             return 0;
  2754.         case VK_DOWN:
  2755.             // Scroll one line down
  2756.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_LINEDOWN, 0), 0);
  2757.             return 0;
  2758.         }
  2759.         break;
  2760.     }
  2761.     case WM_MOUSEWHEEL:
  2762.     {
  2763.         int delta = GET_WHEEL_DELTA_WPARAM(wParam);
  2764.         if (delta > 0) {
  2765.             // Scroll up
  2766.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
  2767.         }
  2768.         else {
  2769.             // Scroll down
  2770.             SendMessage(g_hEditControl, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
  2771.         }
  2772.         return 0;
  2773.     }
  2774.     case WM_COMMAND:
  2775.         if (LOWORD(wParam) == 1) OpenFileDialog(hwnd); if (LOWORD(wParam) == 2) { if (g_hEditControl) { SetFocus(g_hEditControl); SendMessage(g_hEditControl, EM_SETSEL, 0, -1); } } if (LOWORD(wParam) == 3) PostQuitMessage(0); return 0;
  2776.  
  2777. /*        switch (LOWORD(wParam)) {
  2778.         case ID_FILE_OPEN:
  2779.             OpenFileDialog(hwnd);
  2780.             break;
  2781.         case ID_FILE_SELECTALL:
  2782.             if (g_hEditControl) {
  2783.                 // Set focus to the edit control if needed.
  2784.                 SetFocus(g_hEditControl);
  2785.                 // Select all text.
  2786.                 SendMessage(g_hEditControl, EM_SETSEL, 0, -1);
  2787.                 UpdateEditControl();
  2788.             }
  2789.             break;
  2790.         case ID_FILE_EXIT:
  2791.             PostQuitMessage(0);
  2792.             break;
  2793.         }
  2794.         return 0; */        
  2795.        
  2796.         /* {
  2797.         int cmd = LOWORD(wParam);
  2798.         if (cmd == 1) {
  2799.             OpenFileDialog(hwnd);
  2800.         }
  2801.         else if (cmd == 2) {  // This is your Select All command.
  2802.             if (g_hEditControl) {
  2803.                 SetFocus(g_hEditControl);
  2804.                 SendMessage(g_hEditControl, EM_SETSEL, 0, -1);
  2805.                 UpdateEditControl();  // if necessary to refresh display
  2806.             }
  2807.         }
  2808.         else if (cmd == 3) {  // This is your Exit command.
  2809.             PostQuitMessage(0);
  2810.         }
  2811.         return 0;
  2812.     } */
  2813.        
  2814. /*        switch (LOWORD(wParam)) {
  2815.         case ID_FILE_OPEN:
  2816.             OpenFileDialog(hwnd);
  2817.             break;
  2818.         case ID_FILE_SELECTALL:
  2819.             if (g_hEditControl) {
  2820.                 // Set focus to the edit control
  2821.                 SetFocus(g_hEditControl);
  2822.                 // Select all text
  2823.                 SendMessage(g_hEditControl, EM_SETSEL, 0, -1);
  2824.                 UpdateEditControl();
  2825.             }
  2826.             break;
  2827.         case ID_FILE_EXIT:
  2828.             PostQuitMessage(0);
  2829.             break;
  2830.         }
  2831.         return 0;
  2832. */
  2833.     case WM_DESTROY:
  2834.         if (g_hStatusBar) DestroyWindow(g_hStatusBar);
  2835.         PostQuitMessage(0);
  2836.         return 0;
  2837.     }
  2838.     return DefWindowProc(hwnd, uMsg, wParam, lParam);
  2839. }
  2840. ```
  2841.  
  2842. ==++Here's is file 2/4++==::
  2843. ```PEHeaders.h
  2844. #pragma once
  2845. #ifndef PE_ANALYZER_STRUCT_H
  2846. #define PE_ANALYZER_STRUCT_H
  2847. #include <Windows.h>
  2848. #include <winternl.h>
  2849. #include <memory>
  2850. class FileMapper;
  2851.  
  2852. // Core PE analysis structure
  2853. struct PEAnalyzer {
  2854.    LPVOID lpFileContent;
  2855.    DWORD fileSize;
  2856.    bool is64Bit;
  2857.    PIMAGE_NT_HEADERS32 pNtHeaders32;
  2858.    PIMAGE_NT_HEADERS64 pNtHeaders64;
  2859.    PIMAGE_DOS_HEADER pDosHeader;
  2860.    FileMapper* pMapper; // <<-- inserted
  2861.  
  2862.    PEAnalyzer() : lpFileContent(nullptr), fileSize(0), is64Bit(false),
  2863.        pNtHeaders32(nullptr), pNtHeaders64(nullptr), pDosHeader(nullptr), pMapper(nullptr) {}
  2864.  
  2865.    // Remove destructor as FileMapper will handle cleanup
  2866. };
  2867. //struct PEAnalyzer;  // Add this before the namespace
  2868. // Declare functions that use PEAnalyzer
  2869.    template<typename T>
  2870.    bool IsSafeToRead(const PEAnalyzer& analyzer, const T* ptr, size_t size);
  2871. #endif // PE_ANALYZER_STRUCT_H
  2872. namespace PEHelpers {
  2873. //ifndef OUTPUT was here
  2874.  
  2875.    // Inline function to prevent multiple definition
  2876.    inline bool Is64BitPE(PIMAGE_NT_HEADERS pNtHeaders) {
  2877.        return pNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;
  2878.    }
  2879.    //bool ValidateFileSize(const PEAnalyzer& analyzer, DWORD expectedSize, DWORD fileSize);
  2880.    bool ValidateFileSize(DWORD expectedSize, DWORD fileSize);
  2881.    // Add the template function declaration here
  2882.    //template<typename T>
  2883.    //bool IsSafeToRead(const PEAnalyzer& analyzer, const T* ptr, size_t size);
  2884.    bool IsRvaValid(DWORD rva, DWORD fileSize, PIMAGE_NT_HEADERS pNtHeaders);
  2885.    DWORD_PTR GetImageBase(PIMAGE_NT_HEADERS pNtHeaders);
  2886.    DWORD GetSizeOfImage(PIMAGE_NT_HEADERS pNtHeaders);
  2887.    DWORD_PTR GetRvaPtr(DWORD rva, PIMAGE_SECTION_HEADER pSectionHeader,
  2888.        WORD numberOfSections, LPVOID baseAddress);
  2889.    DWORD RvaToOffset(DWORD rva, PIMAGE_SECTION_HEADER pSectionHeader,
  2890.        WORD numberOfSections);
  2891.    std::wstring GetImageCharacteristics(DWORD characteristics);
  2892.    std::wstring GetSubsystem(WORD subsystem);
  2893.    std::wstring GetDataDirectoryName(int DirectoryNumber);
  2894.    std::wstring GetSectionProtection(DWORD characteristics);
  2895.  
  2896.    //    using namespace std;
  2897.    //    using namespace PEAnalyzer;
  2898.        // Core PE validation functions
  2899.    // Ensure this function is defined exactly once
  2900.    /*inline bool Is64BitPE(PIMAGE_NT_HEADERS pNtHeaders) {
  2901.        return pNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;
  2902.    }*/
  2903.  
  2904. /*bool Is64BitPE(PIMAGE_NT_HEADERS pNtHeaders) {
  2905.    return pNtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC;
  2906. }*/
  2907.  
  2908. bool ValidateFileSize(DWORD expectedSize, DWORD fileSize) {
  2909.    return expectedSize > 0 && expectedSize <= fileSize;
  2910. }
  2911.  
  2912. template<typename T>
  2913. bool IsSafeToRead(const PEAnalyzer& analyzer, const T* ptr, size_t size = sizeof(T)) {
  2914.    // Check if pointer is null
  2915.    if (!ptr) {
  2916.        OUTPUT("[-] Null pointer detected\n");
  2917.        return false;
  2918.    }
  2919.  
  2920.    // Calculate pointer ranges
  2921.    DWORD_PTR startAddress = reinterpret_cast<DWORD_PTR>(analyzer.lpFileContent);
  2922.    DWORD_PTR endAddress = startAddress + analyzer.fileSize;
  2923.    DWORD_PTR ptrAddress = reinterpret_cast<DWORD_PTR>(ptr);
  2924.    DWORD_PTR ptrEndAddress = ptrAddress + size;
  2925.  
  2926.    // Comprehensive pointer validation
  2927.    bool isValidPointer = (
  2928.        ptr != nullptr &&                  // Not null
  2929.        ptrAddress >= startAddress &&       // Above file start
  2930.        ptrEndAddress <= endAddress &&      // Below file end
  2931.        ptrAddress < ptrEndAddress          // Prevent integer overflow
  2932.        );
  2933.  
  2934.    if (!isValidPointer) {
  2935.        OUTPUT("[-] Pointer validation failed\n");
  2936.        OUTPUT("    Pointer: 0x%p\n", ptr);
  2937.        OUTPUT("    File Start: 0x%p\n", reinterpret_cast<void*>(startAddress));
  2938.        OUTPUT("    File End: 0x%p\n", reinterpret_cast<void*>(endAddress));
  2939.        OUTPUT("    Pointer Start: 0x%p\n", reinterpret_cast<void*>(ptrAddress));
  2940.        OUTPUT("    Pointer End: 0x%p\n", reinterpret_cast<void*>(ptrEndAddress));
  2941.        return false;
  2942.    }
  2943.  
  2944.    return true;
  2945. }
  2946.  
  2947. bool IsRvaValid(DWORD rva, DWORD fileSize, PIMAGE_NT_HEADERS pNtHeaders) {
  2948.    if (!pNtHeaders) {
  2949.        OUTPUT("[-] Invalid NT Headers for RVA validation\n");
  2950.        return false;
  2951.    }
  2952.  
  2953.    DWORD sizeOfImage = PEHelpers::Is64BitPE(pNtHeaders) ?
  2954.        reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders)->OptionalHeader.SizeOfImage :
  2955.        reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders)->OptionalHeader.SizeOfImage;
  2956.  
  2957.    bool isValid = (
  2958.        rva > 0 &&                  // RVA is non-zero
  2959.        rva < sizeOfImage&&         // RVA is within image size
  2960.        rva < fileSize               // RVA is within file size
  2961.        );
  2962.  
  2963.    if (!isValid) {
  2964.        OUTPUT("[-] Invalid RVA: 0x%X\n", rva);
  2965.        OUTPUT("    Size of Image: 0x%X\n", sizeOfImage);
  2966.        OUTPUT("    File Size: 0x%X\n", fileSize);
  2967.    }
  2968.  
  2969.    return isValid;
  2970. }
  2971.  
  2972. /*bool IsRvaValid(DWORD rva, DWORD fileSize, PIMAGE_NT_HEADERS pNtHeaders) {
  2973.    return rva < pNtHeaders->OptionalHeader.SizeOfImage&& rva < fileSize;
  2974. }*/
  2975.  
  2976. DWORD_PTR GetImageBase(PIMAGE_NT_HEADERS pNtHeaders) {
  2977.    if (PEHelpers::Is64BitPE(pNtHeaders)) {  // Add PEHelpers:: namespace qualifier
  2978.        auto pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
  2979.        return static_cast<DWORD_PTR>(pNtHeaders64->OptionalHeader.ImageBase);
  2980.    }
  2981.    auto pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
  2982.    return static_cast<DWORD_PTR>(pNtHeaders32->OptionalHeader.ImageBase);
  2983. }
  2984.  
  2985. DWORD GetSizeOfImage(PIMAGE_NT_HEADERS pNtHeaders) {
  2986.    if (PEHelpers::Is64BitPE(pNtHeaders)) {  // Add PEHelpers:: namespace qualifier
  2987.        auto pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
  2988.        return pNtHeaders64->OptionalHeader.SizeOfImage;
  2989.    }
  2990.    auto pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
  2991.    return pNtHeaders32->OptionalHeader.SizeOfImage;
  2992. }
  2993.  
  2994. /* // RVA and address conversion helpers
  2995. DWORD_PTR GetImageBase(PIMAGE_NT_HEADERS pNtHeaders) {
  2996.    if (Is64BitPE(pNtHeaders)) {
  2997.        auto pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
  2998.        return static_cast<DWORD_PTR>(pNtHeaders64->OptionalHeader.ImageBase);
  2999.    }
  3000.    auto pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
  3001.    return static_cast<DWORD_PTR>(pNtHeaders32->OptionalHeader.ImageBase);
  3002. }
  3003.  
  3004. DWORD GetSizeOfImage(PIMAGE_NT_HEADERS pNtHeaders) {
  3005.    if (Is64BitPE(pNtHeaders)) {
  3006.        auto pNtHeaders64 = reinterpret_cast<PIMAGE_NT_HEADERS64>(pNtHeaders);
  3007.        return pNtHeaders64->OptionalHeader.SizeOfImage;
  3008.    }
  3009.    auto pNtHeaders32 = reinterpret_cast<PIMAGE_NT_HEADERS32>(pNtHeaders);
  3010.    return pNtHeaders32->OptionalHeader.SizeOfImage;
  3011. }*/
  3012.  
  3013. DWORD_PTR GetRvaPtr(
  3014.    DWORD rva,
  3015.    PIMAGE_SECTION_HEADER pSectionHeader,
  3016.    WORD numberOfSections,
  3017.    LPVOID baseAddress,
  3018.    DWORD fileSize  // Add file size as a parameter
  3019. ) {
  3020.    if (!rva || !pSectionHeader || !baseAddress) {
  3021.        OUTPUT("[-] Invalid parameters in GetRvaPtr\n");
  3022.        return 0;
  3023.    }
  3024.  
  3025.    for (WORD i = 0; i < numberOfSections; i++) {
  3026.        // Check if RVA falls within this section
  3027.        if (rva >= pSectionHeader[i].VirtualAddress &&
  3028.            rva < (pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData)) {
  3029.  
  3030.            // Calculate pointer
  3031.            DWORD_PTR delta = reinterpret_cast<DWORD_PTR>(baseAddress) +
  3032.                pSectionHeader[i].PointerToRawData;
  3033.  
  3034.            DWORD_PTR result = delta + (rva - pSectionHeader[i].VirtualAddress);
  3035.  
  3036.            // Additional validation
  3037.            if (result < reinterpret_cast<DWORD_PTR>(baseAddress) ||
  3038.                result >= (reinterpret_cast<DWORD_PTR>(baseAddress) + fileSize)) {
  3039.                OUTPUT("[-] RVA pointer out of bounds\n");
  3040.                return 0;
  3041.            }
  3042.  
  3043.            return result;
  3044.        }
  3045.    }
  3046.  
  3047.    OUTPUT("[-] RVA not found in any section: 0x%X\n", rva);
  3048.    return 0;
  3049. }
  3050. //}
  3051. //}
  3052.  
  3053. /* DWORD_PTR GetRvaPtr(DWORD rva, PIMAGE_SECTION_HEADER pSectionHeader,
  3054.    WORD numberOfSections, LPVOID baseAddress) {
  3055.    if (!rva || !pSectionHeader || !baseAddress) return 0;
  3056.  
  3057.    for (WORD i = 0; i < numberOfSections; i++) {
  3058.        if (rva >= pSectionHeader[i].VirtualAddress &&
  3059.            rva < (pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData)) {
  3060.            DWORD_PTR delta = (DWORD_PTR)baseAddress + pSectionHeader[i].PointerToRawData;
  3061.            return delta + (rva - pSectionHeader[i].VirtualAddress);
  3062.        }
  3063.    }
  3064.    OUTPUT("[-] Failed to map RVA: 0x%X\n", rva);
  3065.    return 0;
  3066. } */
  3067.  
  3068. DWORD RvaToOffset(DWORD rva, PIMAGE_SECTION_HEADER pSectionHeader, WORD numberOfSections) {
  3069.    if (!rva || !pSectionHeader) return 0;
  3070.  
  3071.    for (WORD i = 0; i < numberOfSections; i++) {
  3072.        if (rva >= pSectionHeader[i].VirtualAddress &&
  3073.            rva < (pSectionHeader[i].VirtualAddress + pSectionHeader[i].SizeOfRawData)) {
  3074.            return (rva - pSectionHeader[i].VirtualAddress) + pSectionHeader[i].PointerToRawData;
  3075.        }
  3076.    }
  3077.    OUTPUT("[-] Failed to map RVA: 0x%X\n", rva);
  3078.    return 0;
  3079. }
  3080.  
  3081. // PE information helper functions
  3082. std::wstring GetImageCharacteristics(DWORD characteristics) {
  3083.    if (characteristics & IMAGE_FILE_DLL) return L"(DLL)";
  3084.    if (characteristics & IMAGE_FILE_SYSTEM) return L"(DRIVER)";
  3085.    if (characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) return L"(EXE)";
  3086.    return L"(UNKNOWN)";
  3087. }
  3088.  
  3089. std::wstring GetSubsystem(WORD subsystem) {
  3090.    switch (subsystem) {
  3091.    case IMAGE_SUBSYSTEM_NATIVE: return L"(NATIVE/DRIVER)";
  3092.    case IMAGE_SUBSYSTEM_WINDOWS_GUI: return L"(GUI)";
  3093.    case IMAGE_SUBSYSTEM_WINDOWS_CUI: return L"(CONSOLE)";
  3094.    default: return L"(UNKNOWN)";
  3095.    }
  3096. }
  3097.  
  3098. std::wstring GetDataDirectoryName(int DirectoryNumber) {
  3099.    static const wchar_t* names[] = {
  3100.        L"Export Table", L"Import Table", L"Resource Table",
  3101.        L"Exception Entry", L"Security Entry", L"Relocation Table",
  3102.        L"Debug Entry", L"Copyright Entry", L"Global PTR Entry",
  3103.        L"TLS Entry", L"Configuration Entry", L"Bound Import Entry",
  3104.        L"IAT", L"Delay Import Descriptor", L"COM Descriptor"
  3105.    };
  3106.    return (DirectoryNumber < 15) ? names[DirectoryNumber] : L"Unknown";
  3107. }
  3108.  
  3109. std::wstring GetSectionProtection(DWORD characteristics) {
  3110.    std::wstring protection = L"(";
  3111.    bool needsSeparator = false;
  3112.  
  3113.    if (characteristics & IMAGE_SCN_MEM_EXECUTE) {
  3114.        protection += L"EXECUTE";
  3115.        needsSeparator = true;
  3116.    }
  3117.    if (characteristics & IMAGE_SCN_MEM_READ) {
  3118.        if (needsSeparator) protection += L" | ";
  3119.        protection += L"READ";
  3120.        needsSeparator = true;
  3121.    }
  3122.    if (characteristics & IMAGE_SCN_MEM_WRITE) {
  3123.        if (needsSeparator) protection += L" | ";
  3124.        protection += L"WRITE";
  3125.    }
  3126.    protection += L")";
  3127.    return protection;
  3128. }
  3129. }
  3130. ```
  3131.  
  3132. ==++Here's is file 3/4++==::
  3133. ```resource.h
  3134. //{{NO_DEPENDENCIES}}
  3135. // Microsoft Visual C++ generated include file.
  3136. // Used by PE-Explorer.rc
  3137. //
  3138. #pragma once
  3139. #define IDI_ICON1                       101
  3140. // resource.h
  3141. #define ID_FILE_OPEN    1001
  3142. #define ID_FILE_SELECTALL 1002   // New "Select All" command
  3143. #define ID_FILE_EXIT    1003
  3144.  
  3145. // Next default values for new objects
  3146. //
  3147. #ifdef APSTUDIO_INVOKED
  3148. #ifndef APSTUDIO_READONLY_SYMBOLS
  3149. #define _APS_NEXT_RESOURCE_VALUE        102
  3150. #define _APS_NEXT_COMMAND_VALUE         40001
  3151. #define _APS_NEXT_CONTROL_VALUE         1001
  3152. #define _APS_NEXT_SYMED_VALUE           101
  3153. #endif
  3154. #endif
  3155.  
  3156. ```
  3157.  
  3158. ==++Here's is file 4/4++==::
  3159. ```PE Explorer.rc
  3160. // Microsoft Visual C++ generated resource script.
  3161. //
  3162. #include "resource.h"
  3163.  
  3164. #define APSTUDIO_READONLY_SYMBOLS
  3165. /////////////////////////////////////////////////////////////////////////////
  3166. //
  3167. // Generated from the TEXTINCLUDE 2 resource.
  3168. //
  3169. #include "winres.h"
  3170.  
  3171. /////////////////////////////////////////////////////////////////////////////
  3172. #undef APSTUDIO_READONLY_SYMBOLS
  3173.  
  3174. /////////////////////////////////////////////////////////////////////////////
  3175. // English (United States) resources
  3176.  
  3177. #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
  3178. LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
  3179. #pragma code_page(1252)
  3180.  
  3181. #ifdef APSTUDIO_INVOKED
  3182. /////////////////////////////////////////////////////////////////////////////
  3183. //
  3184. // TEXTINCLUDE
  3185. //
  3186.  
  3187. 1 TEXTINCLUDE
  3188. BEGIN
  3189.    "resource.h\0"
  3190. END
  3191.  
  3192. 2 TEXTINCLUDE
  3193. BEGIN
  3194.    "#include ""winres.h""\r\n"
  3195.    "\0"
  3196. END
  3197.  
  3198. 3 TEXTINCLUDE
  3199. BEGIN
  3200.    "\r\n"
  3201.    "\0"
  3202. END
  3203.  
  3204. #endif    // APSTUDIO_INVOKED
  3205.  
  3206.  
  3207. /////////////////////////////////////////////////////////////////////////////
  3208. //
  3209. // Icon
  3210. //
  3211.  
  3212. // Icon with lowest ID value placed first to ensure application icon
  3213. // remains consistent on all systems.
  3214. IDI_ICON1               ICON                    "D:\\Download\\cpp-projekt\\FuzenOp_SiloTest\\icons\\shell32_317.ico"
  3215.  
  3216. #endif    // English (United States) resources
  3217. /////////////////////////////////////////////////////////////////////////////
  3218.  
  3219.  
  3220.  
  3221. #ifndef APSTUDIO_INVOKED
  3222. /////////////////////////////////////////////////////////////////////////////
  3223. //
  3224. // Generated from the TEXTINCLUDE 3 resource.
  3225. //
  3226.  
  3227.  
  3228. /////////////////////////////////////////////////////////////////////////////
  3229. #endif    // not APSTUDIO_INVOKED
  3230.  
  3231.  
  3232. ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement