feat: Ryujin pdb parsing
Finishing the Ryujin PDB parsing feature implementation.
This commit is contained in:
@@ -10,7 +10,32 @@ m_strInputFilePath(strInputFilePath), m_strOutputFilePath(strOutputFilePath), m_
|
||||
|
||||
if (!m_isInitialized) {
|
||||
|
||||
OutputDebugStringA("Ryujin::Ryujin: failed to initilize.\n");
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: failed to initilize.\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
m_ryujinProcedures = RyujinPdbParsing::ExtractProceduresFromPdb(
|
||||
|
||||
reinterpret_cast<uintptr_t>(m_mappedPE.get()),
|
||||
m_szFile,
|
||||
m_strInputFilePath,
|
||||
m_strPdbFilePath
|
||||
|
||||
);
|
||||
|
||||
if (m_ryujinProcedures.size() == 0) {
|
||||
|
||||
m_isInitialized = FALSE;
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: No Associate PDB file found for the input binary.."
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +47,7 @@ bool Ryujin::run() {
|
||||
|
||||
if (imgDos->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
|
||||
OutputDebugStringA(
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::run: Invalid PE File.\n"
|
||||
|
||||
@@ -35,7 +60,7 @@ bool Ryujin::run() {
|
||||
|
||||
if (imgNt->Signature != IMAGE_NT_SIGNATURE) {
|
||||
|
||||
OutputDebugStringA(
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::run: Invalid NT headers for the input PE File.\n"
|
||||
|
||||
@@ -46,7 +71,7 @@ bool Ryujin::run() {
|
||||
|
||||
if (!m_isInitialized) {
|
||||
|
||||
OutputDebugStringA(
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: not initilized.\n"
|
||||
|
||||
@@ -55,14 +80,26 @@ bool Ryujin::run() {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto syms = RyujinPdbParsing::ExtractProceduresFromPdb(
|
||||
|
||||
reinterpret_cast<uintptr_t>(m_mappedPE.get()),
|
||||
m_szFile,
|
||||
m_strInputFilePath,
|
||||
m_strPdbFilePath
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void Ryujin::listRyujinProcedures() {
|
||||
|
||||
if (!m_isInitialized) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: not initilized.\n"
|
||||
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& procedure : m_ryujinProcedures) {
|
||||
|
||||
std::printf("%s - 0x%llx - 0x%llx\n", procedure.name.c_str(), procedure.address, procedure.size);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,12 @@ private:
|
||||
const std::string& m_strOutputFilePath;
|
||||
uintptr_t m_szFile;
|
||||
BOOL m_isInitialized;
|
||||
std::vector<RyujinProcedure> m_ryujinProcedures;
|
||||
|
||||
public:
|
||||
Ryujin(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath);
|
||||
bool run();
|
||||
void listRyujinProcedures();
|
||||
~Ryujin();
|
||||
|
||||
};
|
||||
|
||||
@@ -7,6 +7,8 @@ auto main() -> int {
|
||||
|
||||
std::unique_ptr<Ryujin> ryujin = std::make_unique<Ryujin>("C:\\Users\\Keowu\\Documents\\GitHub\\MoFei\\x64\\Debug\\DemoObfuscation.exe", "C:\\Users\\Keowu\\Documents\\GitHub\\MoFei\\x64\\Debug\\DemoObfuscation.pdb", "C:\\Users\\Keowu\\Documents\\GitHub\\MoFei\\x64\\Debug\\DemoObfuscation2.exe");
|
||||
|
||||
ryujin.get()->listRyujinProcedures();
|
||||
|
||||
ryujin.get()->run();
|
||||
|
||||
ryujin.reset();
|
||||
|
||||
@@ -1,18 +1,116 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#pragma comment(lib, "DbgHelp.lib")
|
||||
#include "RyujinProcedure.hh"
|
||||
//#include <dbghelp.h>
|
||||
|
||||
//#pragma comment(lib, "DbgHelp.lib")
|
||||
#define SymTagFunction 5
|
||||
|
||||
class RyujinPdbParsing {
|
||||
|
||||
private:
|
||||
|
||||
static BOOL CALLBACK EnumSymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext) {
|
||||
|
||||
auto* vecSymbols = reinterpret_cast<std::vector<RyujinProcedure>*>(UserContext);
|
||||
|
||||
//Daddy, is this symbol a function entry ?!
|
||||
if (pSymInfo->Tag == SymTagFunction) {
|
||||
|
||||
RyujinProcedure proc;
|
||||
proc.name = pSymInfo->Name;
|
||||
proc.address = pSymInfo->Address;
|
||||
proc.size = pSymInfo->Size;
|
||||
vecSymbols->emplace_back(proc);
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
||||
static std::vector<RyujinProcedure> ExtractProceduresFromPdb(uintptr_t mappedPebase, uintptr_t m_szFile, const std::string& m_strInputFilePath, const std::string& m_strPdbFilePath) {
|
||||
static std::vector<RyujinProcedure> ExtractProceduresFromPdb(uintptr_t mappedPebase, uintptr_t szFile, const std::string& strInputFilePath, const std::string& strPdbFilePath) {
|
||||
|
||||
std::vector<RyujinProcedure> procs;
|
||||
|
||||
::SymSetOptions(
|
||||
|
||||
_In_ SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME
|
||||
|
||||
);
|
||||
|
||||
if (!::SymInitialize(
|
||||
|
||||
_In_ ::GetCurrentProcess(),
|
||||
_In_opt_ nullptr,
|
||||
_In_ NULL
|
||||
|
||||
)) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "RyujinPdbParsing::ExtractProceduresFromPdb: SymInitialize failed..\n"
|
||||
|
||||
);
|
||||
|
||||
return procs;
|
||||
}
|
||||
|
||||
auto strPdbDirectory = strPdbFilePath.substr(0, strPdbFilePath.find_last_of("\\/"));
|
||||
|
||||
::SymSetSearchPath(
|
||||
|
||||
::GetCurrentProcess(),
|
||||
strPdbDirectory.c_str()
|
||||
|
||||
);
|
||||
|
||||
auto loadedModuleBase = ::SymLoadModule64(
|
||||
|
||||
_In_ ::GetCurrentProcess(),
|
||||
_In_opt_ nullptr,
|
||||
_In_opt_ strInputFilePath.c_str(),
|
||||
_In_opt_ nullptr,
|
||||
_In_ mappedPebase,
|
||||
_In_ szFile
|
||||
|
||||
);
|
||||
|
||||
if (loadedModuleBase == 0) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "RyujinPdbParsing::ExtractProceduresFromPdb: Failed to load SymLoadModule64..\n"
|
||||
|
||||
);
|
||||
|
||||
::SymCleanup(
|
||||
|
||||
_In_ ::GetCurrentProcess()
|
||||
|
||||
);
|
||||
|
||||
return procs;
|
||||
}
|
||||
|
||||
::SymEnumSymbols(
|
||||
|
||||
_In_ ::GetCurrentProcess(),
|
||||
_In_ loadedModuleBase,
|
||||
_In_opt_ nullptr,
|
||||
_In_ RyujinPdbParsing::EnumSymbolsCallback,
|
||||
_In_opt_ &procs
|
||||
|
||||
);
|
||||
|
||||
::SymCleanup(
|
||||
|
||||
_In_::GetCurrentProcess()
|
||||
|
||||
);
|
||||
|
||||
return procs;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user