000nico/watchdog-process-protection
GitHub: 000nico/watchdog-process-protection
这是一个面向 Windows x64 的轻量级用户态 C++ 进程保护库,通过 TLS 回调自动初始化反调试、反挂起和句柄清理机制。
Stars: 4 | Forks: 1
# Watchdog 🐕🦺 — 用户态进程保护
面向 Windows x64 的轻量级 C++ 进程保护库。保护通过 TLS 回调在 `main()` 之前自动激活 —— 无需手动初始化。
## 用法
```
#include "upp.hpp"
```
引入头文件后会自动注册 TLS 回调。在任何用户代码运行之前,保护即已启动。
## 工作原理
Windows 在进程入口点之前执行 TLS 回调。`upp` 利用此机制在尽可能早的时刻初始化所有保护。
```
process launched
│
▼
TLS callback → upp::init() ← protection active here
│
▼
main()
```
## 演示
https://github.com/user-attachments/assets/4a637035-a4ba-4271-a2af-1247559acc5d
## API 参考
### upp
```
namespace upp {
bool init(bool crash);
bool exit();
}
```
| 参数 | 描述 |
|-----------|-------------|
| `crash` | 如果为 `true`,则在检测到调试器时自动崩溃 |
由 TLS 回调自动调用。如有需要,也可以手动调用。
| 函数 | 描述 |
|----------|-------------|
| `exit` | 终止看门狗线程,释放 `explorer.exe` 中分配的内存并关闭句柄 |
### sdk
```
namespace sdk {
bool enableSeDebugPrivilege();
DWORD WINAPI protectedThread(LPVOID param);
}
```
- `enableSeDebugPrivilege` — 为当前进程获取 `SeDebugPrivilege`,这是句柄枚举和远程线程注入所必需的
- `protectedThread` — 专用保护线程,每 1000 毫秒循环运行所有检测和缓解模块
### findTarget
```
namespace findTarget {
std::vector find(bool revokeHandle);
}
```
使用 `NtQuerySystemInformation` 枚举所有系统句柄。检测外部进程持有的指向受保护进程的句柄。如果 `revokeHandle` 为 `true`,则复制并关闭这些句柄以撤销外部访问。
### antiDebug
```
namespace antiDebug {
bool setDebugPortCheck();
bool threadHideFromDebugger();
bool rdtsc();
bool deletePe();
bool parentProcessCheck();
bool scyllaCheck();
bool hookCheck();
bool exceptionThrow();
void crash();
bool DoS();
}
```
## | 函数 | 描述 |
|----------|-------------|
| `setDebugPortCheck` | 通过 `NtQueryInformationProcess` 查询 `ProcessDebugPort`。如果附加了调试器,则返回 `true` |
| `threadHideFromDebugger` | 使用 `ThreadHideFromDebugger` 调用 `NtSetInformationThread`。破坏断点,并从调试器中隐藏异常和线程事件 |
| `rdtsc` | 使用 CPU 时间戳计数器测量指令之间的周期差值。差值增大表明正在单步执行或进行插桩 |
| `deletePe` | 从内存中擦除 PE 头,使二进制重构和内存映像分析更加困难 |
| `parentProcessCheck` | 通过 `NtQueryInformationProcess` 查询父进程 PID。对照白名单(`explorer.exe`、`cmd.exe`、`powershell.exe`、`WindowsTerminal.exe`)验证父进程。如果父进程未知,则设置 `problemDebuggerPresent` |
| `scyllaCheck` | 通过类名搜索已知的调试器和反调试绕过工具窗口(`ScyllaHide`、`OLLYDBG`、`x64dbg`、`WinDbgFrameClass`、`ID`) |
| `hookCheck` | 检查 `ntdll.dll`、`kernel32.dll` 和 `kernelbase.dll` 中关键函数的第一个字节是否存在内联 hook(`0xE9` jmp 或 `0xFF`)。涵盖 `NtQueryInformationProcess`、`NtSetInformationThread`、`NtCreateThreadEx`、`DuplicateHandle`、`OpenProcess` 等 |
| `exceptionThrow` | 注册向量化异常处理程序并使用无效句柄调用 `CloseHandle`。如果附加了调试器,Windows 会引发 `0xC0000008` (STATUS_INVALID_HANDLE) —— 若没有调试器,该调用会静默失败 |
| `crash` | 通过 `__fastfail` 终止。免疫于 `try/catch`,不可拦截,使用空工作集进行原子终止,以阻碍事后分析 |
| `DoS` | 通过强制 CPU 读取 12tb 空白内存来冻结调试器 |
### antiSuspend
```
namespace antiSuspend {
bool bypassFreeze();
bool resumeMainThread();
bool watchDog();
void checkWatchDog();
}
```
| 函数 | 描述 |
|----------|-------------|
| `bypassFreeze` | 防止保护线程在进程被完全冻结时被挂起(冻结整个进程,而非单个线程挂起) |
| `resumeMainThread` | 定期恢复主线程,以抵消外部挂起尝试 |
| `watchDog` | 向 `explorer.exe` 注入一个线程,该线程独立恢复受保护的进程线程。注入的线程通过 `watchdogStruct` 接收复制的句柄 |
| `checkWatchDog` | 每个周期检查看门狗线程是否仍然存活。如果已终止,则无条件调用 `crash()` |
#### watchdogStruct
```
struct watchdogStruct {
HANDLE mainThreadHandle;
HANDLE protectThreadHandle;
pDuplicateHandle dup;
pNtResumeThread resume;
};
```
传递给 `explorer.exe` 中注入的看门狗线程。包含 `NtResumeThread` 和 `DuplicateHandle` 的复制句柄以及解析后的函数指针。
### dllProtection
```
namespace dllProtection {
bool processDynamicCodePolicy();
}
```
应用进程缓解策略,防止在运行时创建新的可执行代码。阻止代码注入和动态修补。
## 架构
```
TLS callback
└── upp::init()
├── enableSeDebugPrivilege
└── bypassFreeze
sdk::protectedThread (dedicated thread)
├── threadHideFromDebugger
├── processDynamicCodePolicy
├── deletePe
├── watchDog ──► injected thread in explorer.exe
│ └── resumes mainThread + protectThread
└── loop every 1000ms
├── findTarget — revoke external handles
├── rdtsc — timing detection
├── setDebugPortCheck — debug port detection
├── parentProcessCheck — parent process validation
├── scyllaCheck — debugger window detection
├── hookCheck — ntdll/kernel32 hook detection
├── exceptionThrow — invalid handle exception detection
├── crash — if debugger detected
├── resumeMainThread — anti-suspend
└── checkWatchDog — watchdog liveness check
```
## 系统要求
- Windows x64
- MinGW-w64 或 MSVC
- 运行时需要 `SeDebugPrivilege`(自动获取)
## 说明
- 仅限用户态 —— 无需内核驱动程序
- 看门狗运行在 `explorer.exe` 内部,在正常的系统操作下该进程从不关闭
- `crash()` 使用空工作集调用 `__fastfail`,使转储分析变得复杂
- 由于 TLS 回调,`upp::init` 会被自动调用 —— 如有需要,可直接在 TLS 回调中修改 `crash` 参数
- `processDynamicCodePolicy` 一旦应用即不可逆 —— 此后进程中无法再分配新的可执行内存
- `hookCheck` 涵盖 `ntdll.dll`、`kernel32.dll` 和 `kernelbase.dll`,因为在现代 Windows 版本中,某些函数(如 `DuplicateHandle`)已被移至 `kernelbase`
标签:Awesome列表, Conpot, C++开发, DOM解析, SeDebugPrivilege, TLS回调, Windows安全, x64, XML 请求, 元数据提取, 内存保护, 内核开发, 协议分析, 反调试, 反逆向, 句柄保护, 安全开发, 安全意识培训, 恶意软件防御, 权限提升, 游戏安全, 端点可见性, 系统编程, 进程保护