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.h
Go to the documentation of this file.
1#pragma once
2
3#include <windows.h>
4#include <iostream>
5#include <string>
6#include <map>
7
8namespace pesieve {
9 namespace util {
10 size_t extract_syscall_table(OUT std::map<DWORD, std::string>& syscallToName);
11 }; //namespace util
12
13 struct SyscallTable {
14
15 static bool isSyscallDll(const std::string& libName)
16 {
17 if (libName == "ntdll.dll" || libName == "win32u.dll") {
18 return true;
19 }
20 if (libName == "ntdll" || libName == "win32u") {
21 return true;
22 }
23 return false;
24 }
25
26 static bool isSyscallFunc(const std::string& funcName, bool NtOnly = false)
27 {
28 if (funcName.empty() || funcName.length() < 3) {
29 return false;
30 }
31 bool hasPrefix = false;
32 if (!NtOnly) {
33 if (funcName[0] == 'Z' && funcName[1] == 'w') {
34 hasPrefix = true;
35 }
36 }
37 if (funcName[0] == 'N' && funcName[1] == 't') {
38 hasPrefix = true;
39 }
40 if (!hasPrefix) {
41 return false;
42 }
43 if (funcName[2] >= 'A' && funcName[2] <= 'Z') {
44 // the name of the function after the Nt prefix should start in uppercase,
45 // syscalls are in functions like: NtUserSetWindowLongPtr, but not: NtdllDefWindowProc_A
46 return true;
47 }
48 return false;
49 }
50
51 static bool isSameSyscallFunc(const std::string &func1, const std::string &func2)
52 {
53 if (func1 == func2) return true;
54
55 std::string prefix1 = func1.substr(0, 2);
56 std::string prefix2 = func2.substr(0, 2);
57
58 if ((prefix1 == "Zw" || prefix1 == "Nt") && (prefix2 == "Zw" || prefix2 == "Nt")) {
59 std::string body1 = func1.substr(2);
60 std::string body2 = func2.substr(2);
61 if (body1 == body2) {
62 return true;
63 }
64 if (body1.length() == body2.length()) {
65 return false;
66 }
67 // the difference may be in the suffix
68 std::string* smaller_ptr = body1.length() < body2.length() ? &body1 : &body2;
69 size_t smaller_size = smaller_ptr->length();
70 if (body1.substr(0, smaller_size) == body2.substr(0, smaller_size)) {
71 std::string* bigger_ptr = body1.length() > body2.length() ? &body1 : &body2;
72 std::string suffix = bigger_ptr->substr(smaller_size);
73 if (suffix == "32") {
74 return true;
75 }
76 }
77 }
78 return false;
79 }
80
82 {
84#ifdef _DEBUG
85 std::cout << "Extracted syscalls: " << syscallToName.size() << "\n";
86#endif
87 }
88
89 bool isReady()
90 {
91 return syscallToName.size() ? true : false;
92 }
93
94 std::string getSyscallName(DWORD id)
95 {
96 auto itr = syscallToName.find(id);
97 if (itr != syscallToName.end()) {
98 return itr->second;
99 }
100 return "";
101 }
102
103 std::map<DWORD, std::string> syscallToName;
104 }; //struct SyscallTable
105
106}; // namespace pesieve
size_t extract_syscall_table(OUT std::map< DWORD, std::string > &syscallToName)
std::map< DWORD, std::string > syscallToName
static bool isSyscallFunc(const std::string &funcName, bool NtOnly=false)
static bool isSameSyscallFunc(const std::string &func1, const std::string &func2)
std::string getSyscallName(DWORD id)
static bool isSyscallDll(const std::string &libName)