PE-sieve
Scans all running processes. Recognizes and dumps a variety of potentially malicious implants (replaced/implanted PEs, shellcodes, hooks, in-memory patches).
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
syscall_extractor.cpp
Go to the documentation of this file.
1#include "syscall_extractor.h"
2
3#include <windows.h>
4#include <peconv.h> // include libPeConv header
5#include <iostream>
6#include "process_util.h"
7
8namespace pesieve {
9 namespace util {
10
11 size_t extract_syscalls(BYTE* pe_buf, size_t pe_size, std::map<DWORD, std::string>& syscallToName, size_t startID = 0)
12 {
13 std::vector<std::string> names_list;
14 if (!peconv::get_exported_names(pe_buf, names_list)) {
15 return 0;
16 }
17
18 std::map<DWORD, std::string> sys_functions;
19 for (auto itr = names_list.begin(); itr != names_list.end(); ++itr) {
20 std::string funcName = *itr;
21 if (SyscallTable::isSyscallFunc(funcName, true)) {
22 ULONG_PTR va = (ULONG_PTR)peconv::get_exported_func(pe_buf, funcName.c_str());
23 if (!va) continue;
24
25 DWORD rva = DWORD(va - (ULONG_PTR)pe_buf);
26 sys_functions[rva] = funcName;
27 }
28 }
29 size_t id = startID;
30 for (auto itr = sys_functions.begin(); itr != sys_functions.end(); ++itr) {
31 std::string funcName = itr->second;
32 syscallToName[id++] = funcName;
33 }
34 return id;
35 }
36
37 size_t extract_from_dll(IN const std::string& path, size_t startSyscallID, OUT std::map<DWORD, std::string>& syscallToName)
38 {
39 size_t bufsize = 0;
40 BYTE* buffer = peconv::load_pe_module(path.c_str(), bufsize, false, false);
41
42 if (!buffer) {
43#ifdef _DEBUG
44 std::cerr << "Failed to load the PE: " << path << "\n";
45#endif
46 return 0;
47 }
48
49 size_t extracted_count = extract_syscalls(buffer, bufsize, syscallToName, startSyscallID);
50 peconv::free_pe_buffer(buffer);
51
52 if (!extracted_count) {
53#ifdef _DEBUG
54 std::cerr << "No syscalls extracted from: " << path << "\n";
55#endif
56 }
57 return extracted_count;
58 }
59
60 }; //namespace util
61
62}; //namespace pesieve
63
64size_t pesieve::util::extract_syscall_table(OUT std::map<DWORD, std::string>& syscallToName)
65{
66 PVOID old_val = NULL;
68
69 std::stringstream outs;
70 size_t extracted_count = 0;
71
72 char ntdll_path[MAX_PATH] = { 0 };
73 ExpandEnvironmentStringsA("%SystemRoot%\\system32\\ntdll.dll", ntdll_path, MAX_PATH);
74 extracted_count += extract_from_dll(ntdll_path, 0, syscallToName);
75
76 char win32u_path[MAX_PATH] = { 0 };
77 ExpandEnvironmentStringsA("%SystemRoot%\\system32\\win32u.dll", win32u_path, MAX_PATH);
78 extracted_count += extract_from_dll(win32u_path, 0x1000, syscallToName);
79
81
82 if (!extracted_count) {
83#ifdef _DEBUG
84 std::cerr << "Failed to extract syscalls.\n";
85#endif
86 return 0;
87 }
88 return syscallToName.size();
89}
BOOL wow64_disable_fs_redirection(OUT PVOID *OldValue)
size_t extract_from_dll(IN const std::string &path, size_t startSyscallID, OUT std::map< DWORD, std::string > &syscallToName)
DWORD(__stdcall *_PssCaptureSnapshot)(HANDLE ProcessHandle
size_t extract_syscall_table(OUT std::map< DWORD, std::string > &syscallToName)
size_t extract_syscalls(BYTE *pe_buf, size_t pe_size, std::map< DWORD, std::string > &syscallToName, size_t startID=0)
BOOL wow64_revert_fs_redirection(IN PVOID OldValue)
int MAX_PATH
Definition pesieve.py:10
static bool isSyscallFunc(const std::string &funcName, bool NtOnly=false)