关于win7下r3窗口进程保护的一些方式
背景
随着Windows PG保护的出现,过去内核挂钩inline hook的时代逐渐远去,hook OpenProcess的日子也一去不复返了。那么,如果想在Windows操作系统上不那么轻易的被结束掉(这里主要考虑不在r3被结束,都在内核还干不掉你),有没有什么方法?
常见方式
通常情况下如果是在r0,注册一个ObRegisterCallbacks回调,对PROCESS_TERMINATE权限进行限制,就能解决别人调用TerminateProcess结束进程的情况。
if (pOperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)
{
if (pOperationInformation->Parameters->DuplicateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE)
pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
if (pOperationInformation->Parameters->DuplicateHandleInformation.OriginalDesiredAccess & PROCESS_DUP_HANDLE)
pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= ~PROCESS_DUP_HANDLE;
}
if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
{
if (pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE)
pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
if (pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_DUP_HANDLE)
pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_DUP_HANDLE;
}
但是,对进程的运行原理有个基本了解的同学都知道,进程只是分配了一个'车间'的资源,最后还是线程去工作,结束掉你的线程,你的进程一样说再见,所以还得加上线程的限制,这样别人使用terminateThread也结束不了你的线程。
if (pOperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE)
{
if (pOperationInformation->Parameters->DuplicateHandleInformation.OriginalDesiredAccess & THREAD_TERMINATE)
pOperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess &= ~THREAD_TERMINATE;
}
if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
{
if (pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & THREAD_TERMINATE)
pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~THREAD_TERMINATE;
}
上述描述的都是常见进程的保护手段,当然还有一些属性是可以进行修改的,比如THREAD_SUSPEND_RESUME,暂停你的线程,只要把你暂停了,就算没有结束你,你的进程不是一样的没法工作;还有就是PROCESS_VM_OPERATION,修改你的进程内存,制造一个异常,如果进程中没有hand,进程就会崩溃,从而导致进程死掉,当然还有很多的方法。这里不详细的展开,因为这不是本次想叙述的重点。
Win7 窗口进程保护
大多数同学都用过任务管理器,可能有的同学注意到,任务管理有两种结束进程的方式,第一种是在应用程序中去结束任务,这里出现的任务都是窗口程序。
第二种就是在进程中找到对应的进程去结束。
第一种方式和第二种方式有什么区别?通过对taskmgr(任务管理器)的简单逆向,不难发现
任务管理器先调用了endtask,之后在调用 SendMessageTimeoutW往目标窗口发送了一个WM_CLOSE的消息,通知程序关闭窗口(Win10 有一点变更)
关于消息的拦截,这里简单说明一下,不能使用WH_CALLWNDPROC消息钩子去拦截,虽然能够获取到消息,但是这里并不能删除和替换这个消息,这个消息依然会被窗口回调函数所获取。所以这里可以通过替换窗口回调函数过滤掉WM_CLOSE消息,使用GetWindowLongA和SetWindowLongA进行替换。
EndTask的实现
该函数只是将消息发送到csrss进程中
endtask在winsrv.dll中实现,csrss会去加载这个dll。其中需要注意的是ReportHangInternal
ReportHangInternal函数调用WersvcSendMessage,通过rpc的方式,发送异常到\\KernelObjects\\SystemErrorPortReady对象。
\\KernelObjects\\SystemErrorPortReady对象被wersvc.dll所注册,这是windows的一个服务。在服务收到异常的时候会创建一个werfault.exe进程,并且提示你是否立刻结束这个进程(能够到达这里的前提是我们处理了WM_CLOSE消息,此时才会出现异常)
点击立即结束之后werfault.exe进程通过setevent将消息告诉wersvc.dll服务,对应的是svchost进程。
wersvc.dll服务会再次尝试结束掉进程。
最后简单梳理一下流程,taskmgr告诉csrss有一个窗口程序不关闭(当前窗口回调被hook,过滤了WM_CLOSE的消息),csrss接收之后往wersvc服务继续发消息,wersvc创建一个werfault.exe,werfault.exe在创建一个窗口告诉用户是否关闭程序,werfault.exe将结果告诉wersvc,wersvc最后尝试结束进程。
在此次流程中我们只需要先hook窗口的回调函数,接着添加ObRegisterCallbacks回调,处理TerminateProcess和terminateThread就能完成保护。
程序的保护
其实,还有一种方式进行保护,(运行程序的时候记得用管理员身份打开)那就是把当前进程设置为受保护进程,当进程死掉的时候就蓝屏,多的话不说,看下面的代码,其实RtlSetProcessIsCritical的实现也很简单,有兴趣的可以拿ida看一下,但是如果你用任务管理器结束窗口试试看,不会触发蓝屏?(想想为什么,多试试)。
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef NTSTATUS(__cdecl* PRTLSETPROCESSISCRITICAL)(IN BOOLEAN NewValue, OUT PBOOLEAN OldValue OPTIONAL, IN BOOLEAN NeedBreaks);
BOOLEAN EnableDebugPrivilege()
{
HANDLE hToken = NULL;
LUID debugPrivilegeValueLuid = { 0 };
TOKEN_PRIVILEGES tokenPrivilege = { 0 };
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
return FALSE;
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &debugPrivilegeValueLuid))
{
CloseHandle(hToken);
return FALSE;
}
tokenPrivilege.PrivilegeCount = 1;
tokenPrivilege.Privileges[0].Luid = debugPrivilegeValueLuid;
tokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (!AdjustTokenPrivileges(hToken, FALSE, &tokenPrivilege, sizeof(tokenPrivilege), NULL, NULL))
{
CloseHandle(hToken);
return FALSE;
}
return TRUE;
}
BOOLEAN BSODCriticalProtect()
{
if (!EnableDebugPrivilege())
return FALSE;
HMODULE hNtdllMod = GetModuleHandleA("ntdll.dll");
if (!hNtdllMod)
return FALSE;
PRTLSETPROCESSISCRITICAL pRtlSetProcessIsCritical;
pRtlSetProcessIsCritical = (PRTLSETPROCESSISCRITICAL)GetProcAddress(hNtdllMod, "RtlSetProcessIsCritical");
if (!pRtlSetProcessIsCritical)
return FALSE;
NTSTATUS status = pRtlSetProcessIsCritical(TRUE, NULL, FALSE);
printf("你结束我你试试 status: %x\n", status);
system("pause");
status = pRtlSetProcessIsCritical(FALSE, NULL, FALSE);
printf("别现在不行 status: %x\n", status);
return TRUE;
}
int main(void)
{
BSODCriticalProtect();
system("pause");
return 0;
}
相关文章
- [反调试&进程保护] 使用 hook 的方式保护自身进程
- 进程保护原理Hook函数Openprocess
- 《信息存储与管理(第二版):数字信息的存储、管理和保护》—— 第1部分 存储系统
- 银行业应如何加强信息安全保护?
- QWaitCondition 的正确使用方法(通过 mutex 把有严格时序要求的代码保护起来,同时把 wakeAll() 也用同一个 mutex 保护起来)
- 保护手机隐私最关键是提高全民信息安全意识
- 研究人员使用RFID技术保护濒危植物
- 云安全:现有安全流程和技术无法保护
- 暗网不只是黑产基地 Facebook从黑市购买口令以保护账户安全
- 政务新媒体遇上大数据个人信息如何保护?
- 监守自盗,公民个人信息急需法律保护