关于进程保护的探究
字数 984 2025-08-09 13:33:44
Windows进程保护技术探究与实现
一、前言
本文基于对某数字杀软自我保护功能的研究,探讨Windows平台下进程保护技术的实现原理与方法。该杀软的自我保护功能通过加载360SelfProtection.sys驱动(可能还有360SelfProtection_win10.sys),在Ring 0(内核层)通过hook等技术保护注册表项和重要进程。
二、基本原理
2.1 进程终止机制
Windows提供了以下API用于终止进程:
TerminateProcess: 终止其他进程ExitProcess: 终止自身进程
无论是通过taskkill命令还是任务管理器等GUI工具结束进程,本质上都是调用TerminateProcess或更底层的ZwTerminateProcess。
2.2 保护思路
通过hook TerminateProcess API,在函数执行时进行拦截,对受保护进程直接返回拒绝访问,从而实现进程保护。
三、用户层实现方法
3.1 API Hook技术
3.1.1 函数原型声明
static BOOL(WINAPI* OldTerminateProcess)(
HANDLE hProcess,
UINT uExitCode) = TerminateProcess;
3.1.2 自定义处理函数
BOOL WINAPI New_TerminateProcess(
_In_ HANDLE hProcess,
_In_ UINT uExitCode
) {
unhookTerminateProcess();
MessageBox(NULL,L"该进程受保护!", L"Access Denied",NULL);
hookTerminateProcess();
return false;
}
3.2 64位系统hook实现
64位系统需要修改12字节的硬编码:
48 b8 _dwNewAddress(0x1122334455667788)
ff e0
; 对应汇编指令:
; mov rax, _dwNewAddress(0x1122334455667788)
; jmp rax
3.2.1 Hook函数实现
void hookTerminateProcess() {
DWORD dwTerminateProcessOldProtect;
BYTE pData[12] = { 0x48,0xb8,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xFF,0xE0 };
ULONGLONG ullNewFuncAddr = (ULONGLONG)New_TerminateProcess;
// 保存原始字节
::RtlCopyMemory(g_OldTerminateProcess, OldTerminateProcess, sizeof(pData));
// 更改内存权限
VirtualProtect(OldTerminateProcess, 12, PAGE_EXECUTE_READWRITE, &dwTerminateProcessOldProtect);
// 修改机器码,指向我们的函数
::RtlCopyMemory(&pData[2], &ullNewFuncAddr, sizeof(ullNewFuncAddr));
::RtlCopyMemory(OldTerminateProcess, pData, sizeof(pData));
// 恢复内存属性
VirtualProtect(OldTerminateProcess, 12, dwTerminateProcessOldProtect, &dwTerminateProcessOldProtect);
}
3.2.2 解除Hook
void unhookTerminateProcess() {
DWORD dwOldProtect = NULL;
VirtualProtect(OldTerminateProcess, 12, PAGE_EXECUTE_READWRITE, &dwOldProtect);
RtlCopyMemory(OldTerminateProcess, g_OldTerminateProcess, sizeof(g_OldTerminateProcess));
VirtualProtect(OldTerminateProcess, 12, dwOldProtect, &dwOldProtect);
}
3.3 DLL注入实现
将hook代码封装为DLL,通过注入到目标进程(如任务管理器)实现保护:
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hookTerminateProcess();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
unhookTerminateProcess();
break;
}
return TRUE;
}
3.4 注入工具实现
使用突破Session 0的注入方法:
DWORD _InjectThread(DWORD _Pid, LPCSTR psDllPath) {
// 打开目标进程
HANDLE hprocess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, _Pid);
// 在目标进程分配内存
_SIZE = strlen(psDllPath)+1;
pAlloc = ::VirtualAllocEx(hprocess, NULL, _SIZE, MEM_COMMIT, PAGE_READWRITE);
// 写入DLL路径
::WriteProcessMemory(hprocess, pAlloc, psDllPath, _SIZE, NULL);
// 获取LoadLibraryA地址
pThreadFunction = ::GetProcAddress(::GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
// 使用ZwCreateThreadEx创建远程线程
typedef DWORD(WINAPI* typedef_ZwCreateThreadEx)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
LPVOID ObjectAttributes,
HANDLE ProcessHandle,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
ULONG CreateThreadFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
LPVOID pUnkown
);
ZwCreateThreadEx = (typedef_ZwCreateThreadEx)::GetProcAddress(hNtdll, "ZwCreateThreadEx");
ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, hprocess,
(LPTHREAD_START_ROUTINE)pThreadFunction, pAlloc, 0, 0, 0, 0, NULL);
// 检查注入结果
if (EnumModules(_Pid, psDllPath)) {
printf("[√] 注入成功");
}
}
四、选择性进程保护
4.1 问题分析
单纯hook TerminateProcess会导致所有进程都无法终止,需要结合OpenProcess hook实现选择性保护。
4.2 使用Detours库
微软Detours库提供了更稳定的API hook方案:
void Hook() {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)&OldOpenProcess, New_OpenProcess);
DetourAttach((PVOID*)&OldTerminateProcess, New_TerminateProcess);
DetourTransactionCommit();
}
void UnHook() {
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach((PVOID*)&OldTerminateProcess, New_TerminateProcess);
DetourDetach((PVOID*)&OldOpenProcess, New_OpenProcess);
DetourTransactionCommit();
}
4.3 选择性保护实现
HANDLE g_handle = NULL;
HANDLE WINAPI New_OpenProcess(DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwProcessId) {
if (dwProcessId == 5568) { // 保护特定PID的进程
g_handle = OldOpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
return g_handle;
}
else {
return OldOpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
}
}
BOOL WINAPI New_TerminateProcess(_In_ HANDLE hProcess, _In_ UINT uExitCode) {
if (g_handle == hProcess) { // 检查是否为受保护进程
MessageBox(NULL, L"该进程受保护!", L"Access Denied", NULL);
g_handle = NULL;
return false;
}
return OldTerminateProcess(hProcess, uExitCode);
}
五、总结
本文详细介绍了Windows平台下通过用户层API hook实现进程保护的技术方案,包括:
TerminateProcess和OpenProcess的hook原理- 64位系统下的inline hook实现
- DLL注入技术
- 使用Detours库的稳定hook方案
- 选择性进程保护的实现方法
实际应用中,商业安全软件通常在内核层(Ring 0)实现更全面的保护机制,但用户层方案对于特定场景下的进程保护已经足够有效。