-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDefense.cpp
More file actions
194 lines (164 loc) · 5.48 KB
/
Copy pathDefense.cpp
File metadata and controls
194 lines (164 loc) · 5.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include "Defense.h"
#include <windows.h>
#include <intrin.h> // __readgsqword / __readfsdword
#include <tlhelp32.h>
#include <psapi.h> // 用于 GetModuleBaseName
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
#ifdef _MSC_VER
#pragma comment(lib, "psapi.lib")
#endif
// ---------- 内置黑名单 ----------
static const std::vector<std::string> 调试器黑名单 = {
"x64dbg.exe", "x32dbg.exe",
"ollydbg.exe", "ollyice.exe",
"ida.exe", "idag.exe", "ida64.exe",
"windbg.exe",
"cheatengine.exe", "cheat engine.exe",
"immunitydebugger.exe",
"dnspy.exe",
"de4dot.exe"
};
static const std::vector<std::string> 抓包黑名单 = {
"wireshark.exe",
"fiddler.exe", "fiddler everywhere.exe",
"charles.exe",
"httpdebugger.exe",
"burpsuite.exe",
"mitmproxy.exe"
};
// ---------- 内部工具函数 ----------
// 将字符串转为小写(用于不区分大小写比较)
static std::string toLower(const std::string& str) {
std::string lower = str;
std::transform(lower.begin(), lower.end(), lower.begin(),
[](unsigned char c) { return std::tolower(c); });
return lower;
}
// 获取当前进程文件名(用于排除自身)
static std::string 获取当前进程名() {
char path[MAX_PATH];
GetModuleFileNameA(NULL, path, MAX_PATH);
std::string full(path);
size_t pos = full.find_last_of("\\/");
if (pos != std::string::npos)
return full.substr(pos + 1);
return full;
}
// ---------- 核心检测函数 ----------
bool 防破解::进程存在(const std::vector<std::string>& 黑名单) {
// 获取当前进程名,排除自身(避免误杀)
std::string 自身进程名 = 获取当前进程名();
std::string 自身小写 = toLower(自身进程名);
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE)
return false;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
bool found = false;
if (Process32First(hSnapshot, &pe32)) {
do {
std::string 进程名(pe32.szExeFile);
std::string 进程名小写 = toLower(进程名);
// 跳过自身进程
if (进程名小写 == 自身小写)
continue;
for (const auto& 黑 : 黑名单) {
std::string 黑小写 = toLower(黑);
if (进程名小写 == 黑小写) {
found = true;
break;
}
}
if (found) break;
} while (Process32Next(hSnapshot, &pe32));
}
CloseHandle(hSnapshot);
return found;
}
bool 防破解::检测调试器进程() {
return 进程存在(调试器黑名单);
}
bool 防破解::检测抓包进程() {
return 进程存在(抓包黑名单);
}
bool 防破解::检测指定进程(const std::vector<std::string>& 进程名列表) {
return 进程存在(进程名列表);
}
// ---------- Windows API 反调试 ----------
bool 防破解::检测调试标志() {
return IsDebuggerPresent() == TRUE;
}
bool 防破解::检测PEB标志() {
unsigned char beingDebugged = 0;
#ifdef _WIN64
// x64: GS[0x60] 指向 PEB,+0x02 为 BeingDebugged
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
beingDebugged = *(unsigned char*)(__readgsqword(0x60) + 0x02);
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#else
// x86: FS[0x30] 指向 PEB,+0x02 为 BeingDebugged
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
#endif
beingDebugged = *(unsigned char*)(__readfsdword(0x30) + 0x02);
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#endif
return beingDebugged == 1;
}
bool 防破解::检测调试端口() {
// 动态获取 NtQueryInformationProcess
HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
if (!hNtdll) return false;
typedef NTSTATUS(WINAPI* pNtQueryInformationProcess)(
HANDLE, DWORD, PVOID, ULONG, PULONG
);
auto NtQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");
if (!NtQueryInformationProcess) return false;
DWORD debugPort = 0;
NTSTATUS status = NtQueryInformationProcess(
GetCurrentProcess(),
7, // ProcessDebugPort
&debugPort,
sizeof(debugPort),
nullptr
);
return (status == 0 && debugPort != 0);
}
bool 防破解::检测硬件断点() {
// 读取当前线程的调试寄存器
// Dr0~Dr3 保存硬件断点地址,Dr7 低 8 位控制各断点是否启用
CONTEXT ctx;
ZeroMemory(&ctx, sizeof(ctx));
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
if (!GetThreadContext(GetCurrentThread(), &ctx))
return false;
// 任一调试地址寄存器非零,说明设置了硬件断点
if (ctx.Dr0 != 0 || ctx.Dr1 != 0 || ctx.Dr2 != 0 || ctx.Dr3 != 0)
return true;
// 即使 Dr0~Dr3 为 0,也检查 Dr7 的启用位(L0~L3 / G0~G3)
const DWORD dr7EnableMask = 0x000000FF;
if ((ctx.Dr7 & dr7EnableMask) != 0)
return true;
return false;
}
// ---------- 综合检测 ----------
bool 防破解::综合检测() {
if (检测调试器进程()) return true;
if (检测抓包进程()) return true;
if (检测调试标志()) return true;
if (检测PEB标志()) return true;
if (检测调试端口()) return true;
if (检测硬件断点()) return true;
return false;
}