mirror of
https://github.com/HyperDbg/HyperDbg.git
synced 2026-07-21 23:14:30 +00:00
153 lines
4.7 KiB
C++
153 lines
4.7 KiB
C++
/**
|
|
* @file pe.cpp
|
|
* @author Sina Karvandi (sina@hyperdbg.org)
|
|
* @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"
|
|
|
|
/**
|
|
* @brief help of the .pe command
|
|
*
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
CommandPeHelp()
|
|
{
|
|
ShowMessages(".pe : parses portable executable (PE) files, displays header metadata, and dumps sections.\n\n");
|
|
|
|
ShowMessages("syntax : \t.pe [header] [FilePath (string)]\n");
|
|
ShowMessages("syntax : \t.pe [section] [SectionName (string)] [FilePath (string)]\n");
|
|
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");
|
|
}
|
|
|
|
/**
|
|
* @brief .pe command handler
|
|
*
|
|
* @param CommandTokens
|
|
* @param Command
|
|
* @return VOID
|
|
*/
|
|
VOID
|
|
CommandPe(vector<CommandToken> CommandTokens, string Command)
|
|
{
|
|
BOOLEAN Is32Bit = FALSE;
|
|
wstring Filepath;
|
|
string TempFilePath;
|
|
BOOLEAN ShowDumpOfSection = FALSE;
|
|
|
|
if (CommandTokens.size() <= 2)
|
|
{
|
|
ShowMessages("err, incorrect use of the '%s' command\n\n",
|
|
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
|
|
CommandPeHelp();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Check for first option
|
|
//
|
|
if (CompareLowerCaseStrings(CommandTokens.at(1), "section"))
|
|
{
|
|
if (CommandTokens.size() == 3)
|
|
{
|
|
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());
|
|
CommandPeHelp();
|
|
return;
|
|
}
|
|
ShowDumpOfSection = TRUE;
|
|
TempFilePath = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(3));
|
|
}
|
|
else if (CompareLowerCaseStrings(CommandTokens.at(1), "header"))
|
|
{
|
|
if (CommandTokens.size() != 3)
|
|
{
|
|
ShowMessages("err, incorrect use of the '%s' command\n\n",
|
|
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
|
|
CommandPeHelp();
|
|
return;
|
|
}
|
|
|
|
ShowDumpOfSection = FALSE;
|
|
TempFilePath = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2));
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Couldn't resolve or unknown parameter
|
|
//
|
|
ShowMessages("err, couldn't resolve error at '%s'\n\n",
|
|
GetCaseSensitiveStringFromCommandToken(CommandTokens.at(1)).c_str());
|
|
CommandPeHelp();
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Convert path to wstring
|
|
//
|
|
StringToWString(Filepath, TempFilePath);
|
|
|
|
//
|
|
// 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
|
|
|
|
//
|
|
// Detect whether PE is 32-bit or 64-bit
|
|
//
|
|
if (!PeIsPE32BitOr64Bit(FilepathW, &Is32Bit))
|
|
{
|
|
//
|
|
// File was invalid, the error message is shown in the above function
|
|
//
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Parse PE file
|
|
//
|
|
if (!ShowDumpOfSection)
|
|
{
|
|
PeShowSectionInformationAndDump(FilepathW, NULL, Is32Bit);
|
|
}
|
|
else
|
|
{
|
|
PeShowSectionInformationAndDump(FilepathW, GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str(), Is32Bit);
|
|
}
|
|
}
|