mirror of
https://github.com/hasherezade/pe-sieve
synced 2026-06-08 14:34:52 +00:00
90 lines
2.5 KiB
C++
90 lines
2.5 KiB
C++
#include "syscall_extractor.h"
|
|
|
|
#include <windows.h>
|
|
#include <peconv.h> // include libPeConv header
|
|
#include <iostream>
|
|
#include "process_util.h"
|
|
|
|
namespace pesieve {
|
|
namespace util {
|
|
|
|
size_t extract_syscalls(BYTE* pe_buf, size_t pe_size, std::map<DWORD, std::string>& syscallToName, size_t startID = 0)
|
|
{
|
|
std::vector<std::string> names_list;
|
|
if (!peconv::get_exported_names(pe_buf, names_list)) {
|
|
return 0;
|
|
}
|
|
|
|
std::map<DWORD, std::string> sys_functions;
|
|
for (auto itr = names_list.begin(); itr != names_list.end(); ++itr) {
|
|
std::string funcName = *itr;
|
|
if (SyscallTable::isSyscallFunc(funcName, true)) {
|
|
ULONG_PTR va = (ULONG_PTR)peconv::get_exported_func(pe_buf, funcName.c_str());
|
|
if (!va) continue;
|
|
|
|
DWORD rva = DWORD(va - (ULONG_PTR)pe_buf);
|
|
sys_functions[rva] = funcName;
|
|
}
|
|
}
|
|
size_t id = startID;
|
|
for (auto itr = sys_functions.begin(); itr != sys_functions.end(); ++itr) {
|
|
std::string funcName = itr->second;
|
|
syscallToName[id++] = funcName;
|
|
}
|
|
return id;
|
|
}
|
|
|
|
size_t extract_from_dll(IN const std::string& path, size_t startSyscallID, OUT std::map<DWORD, std::string>& syscallToName)
|
|
{
|
|
size_t bufsize = 0;
|
|
BYTE* buffer = peconv::load_pe_module(path.c_str(), bufsize, false, false);
|
|
|
|
if (!buffer) {
|
|
#ifdef _DEBUG
|
|
std::cerr << "Failed to load the PE: " << path << "\n";
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
size_t extracted_count = extract_syscalls(buffer, bufsize, syscallToName, startSyscallID);
|
|
peconv::free_pe_buffer(buffer);
|
|
|
|
if (!extracted_count) {
|
|
#ifdef _DEBUG
|
|
std::cerr << "No syscalls extracted from: " << path << "\n";
|
|
#endif
|
|
}
|
|
return extracted_count;
|
|
}
|
|
|
|
}; //namespace util
|
|
|
|
}; //namespace pesieve
|
|
|
|
size_t pesieve::util::extract_syscall_table(OUT std::map<DWORD, std::string>& syscallToName)
|
|
{
|
|
PVOID old_val = NULL;
|
|
pesieve::util::wow64_disable_fs_redirection(&old_val);
|
|
|
|
std::stringstream outs;
|
|
size_t extracted_count = 0;
|
|
|
|
char ntdll_path[MAX_PATH] = { 0 };
|
|
ExpandEnvironmentStringsA("%SystemRoot%\\system32\\ntdll.dll", ntdll_path, MAX_PATH);
|
|
extracted_count += extract_from_dll(ntdll_path, 0, syscallToName);
|
|
|
|
char win32u_path[MAX_PATH] = { 0 };
|
|
ExpandEnvironmentStringsA("%SystemRoot%\\system32\\win32u.dll", win32u_path, MAX_PATH);
|
|
extracted_count += extract_from_dll(win32u_path, 0x1000, syscallToName);
|
|
|
|
pesieve::util::wow64_revert_fs_redirection(old_val);
|
|
|
|
if (!extracted_count) {
|
|
#ifdef _DEBUG
|
|
std::cerr << "Failed to extract syscalls.\n";
|
|
#endif
|
|
return 0;
|
|
}
|
|
return syscallToName.size();
|
|
}
|