HyperDbg/hyperdbg/libhyperdbg/code/debugger/commands/meta-commands/pe.cpp

154 lines
4.7 KiB
C++
Raw Permalink Normal View History

2021-12-28 01:14:56 +03:30
/**
* @file pe.cpp
2022-01-18 22:38:56 +03:30
* @author Sina Karvandi (sina@hyperdbg.org)
2021-12-28 01:14:56 +03:30
* @brief .pe command
* @details
* @version 0.1
* @date 2021-12-27
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
2021-12-28 01:14:56 +03:30
/**
2023-07-13 16:05:42 +09:00
* @brief help of the .pe command
2021-12-28 01:14:56 +03:30
*
* @return VOID
*/
VOID
CommandPeHelp()
{
2026-06-02 12:26:20 +01:00
ShowMessages(".pe : parses portable executable (PE) files, displays header metadata, and dumps sections.\n\n");
2026-06-02 19:28:19 +02:00
ShowMessages("syntax : \t.pe [header] [FilePath (string)]\n");
ShowMessages("syntax : \t.pe [section] [SectionName (string)] [FilePath (string)]\n");
2026-06-02 12:37:30 +01:00
ShowMessages("\n.pe section dumps are capped at 1 MiB per matching section and 4 MiB total.\n");
ShowMessages("\n");
ShowMessages("\t\te.g : .pe header c:\\reverse\\myfile.exe\n");
ShowMessages("\t\te.g : .pe section .text \"c:\\reverse files\\myfile.exe\"\n");
ShowMessages("\t\te.g : .pe section .rdata \"c:\\reverse files\\myfile.exe\"\n");
2021-12-28 01:14:56 +03:30
}
/**
* @brief .pe command handler
*
* @param CommandTokens
2021-12-28 01:14:56 +03:30
* @param Command
* @return VOID
*/
VOID
CommandPe(vector<CommandToken> CommandTokens, string Command)
2021-12-28 01:14:56 +03:30
{
BOOLEAN Is32Bit = FALSE;
wstring Filepath;
string TempFilePath;
2021-12-28 01:14:56 +03:30
BOOLEAN ShowDumpOfSection = FALSE;
if (CommandTokens.size() <= 2)
2021-12-28 01:14:56 +03:30
{
ShowMessages("err, incorrect use of the '%s' command\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
2021-12-28 01:14:56 +03:30
CommandPeHelp();
return;
}
//
// Check for first option
//
if (CompareLowerCaseStrings(CommandTokens.at(1), "section"))
2021-12-28 01:14:56 +03:30
{
if (CommandTokens.size() == 3)
2021-12-28 01:14:56 +03:30
{
2026-06-02 12:37:30 +01:00
ShowMessages("err, incorrect use of the '%s' command\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandPeHelp();
return;
}
if (CommandTokens.size() != 4)
{
ShowMessages("err, incorrect use of the '%s' command\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
2021-12-28 01:14:56 +03:30
CommandPeHelp();
return;
}
ShowDumpOfSection = TRUE;
TempFilePath = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(3));
2021-12-28 01:14:56 +03:30
}
else if (CompareLowerCaseStrings(CommandTokens.at(1), "header"))
2021-12-28 01:14:56 +03:30
{
2026-06-02 12:37:30 +01:00
if (CommandTokens.size() != 3)
{
ShowMessages("err, incorrect use of the '%s' command\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
CommandPeHelp();
return;
}
2021-12-28 01:14:56 +03:30
ShowDumpOfSection = FALSE;
TempFilePath = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2));
2021-12-28 01:14:56 +03:30
}
else
{
//
2024-03-17 01:01:22 +09:00
// Couldn't resolve or unknown parameter
2021-12-28 01:14:56 +03:30
//
ShowMessages("err, couldn't resolve error at '%s'\n\n",
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(1)).c_str());
2021-12-28 01:14:56 +03:30
CommandPeHelp();
return;
}
//
// Convert path to wstring
//
StringToWString(Filepath, TempFilePath);
2021-12-28 01:14:56 +03:30
//
// TEMPORARY LINUX SHIM:
// std::wstring stores native wchar_t, which is 4 bytes on Linux, but the
// HyperDbg WCHAR type is 2 bytes (UINT16) and the PE-parser path APIs take
// a const WCHAR *. The cast below exists ONLY so the project compiles on
// Linux. On Linux it produces a bogus 2-byte reinterpretation of the 4-byte
// buffer; that is acceptable for now only because Linux file I/O is still
// stubbed (the path is never actually opened). On Windows WCHAR == wchar_t,
// so it is a plain, correct pointer with no reinterpretation.
//
// TODO (Linux): remove this cast once real Linux file I/O lands. The proper
// fix is to convert the 4-byte wchar_t path into a 2-byte WCHAR/UTF-16
// buffer (e.g. a std::wstring -> WCHAR helper) and pass that, so the PE
// parser receives a valid path. The same conversion is needed by
// PlatformMapFileReadOnly / PlatformOpenFileForWriting.
//
#ifdef __linux__
const WCHAR * FilepathW = (const WCHAR *)Filepath.c_str();
#else
const WCHAR * FilepathW = Filepath.c_str();
#endif
2021-12-28 01:14:56 +03:30
//
// Detect whether PE is 32-bit or 64-bit
//
if (!PeIsPE32BitOr64Bit(FilepathW, &Is32Bit))
2021-12-28 01:14:56 +03:30
{
//
// File was invalid, the error message is shown in the above function
//
return;
}
//
// Parse PE file
//
if (!ShowDumpOfSection)
{
PeShowSectionInformationAndDump(FilepathW, NULL, Is32Bit);
2021-12-28 01:14:56 +03:30
}
else
{
PeShowSectionInformationAndDump(FilepathW, GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str(), Is32Bit);
2021-12-28 01:14:56 +03:30
}
}