进程防结束之PS_CROSS_THREAD_FLAGS_SYSTEM
来源:互联网 发布:威少11赛季数据 编辑:程序博客网 时间:2024/06/03 16:11
这种方法的关键在于给线程的ETHREAD.CrossThreadFlags设置PS_CROSS_THREAD_FLAGS_SYSTEM值,这样其它进程就无法结束它了,包括IceSword、RkU。至于原理,那就先看看wrk里结束进程的那几个内核函数源码,NtTerminateProcess、PsTerminateProcess、PspTerminateProcess最终都是调用PspTerminateThreadByPointer来将每个线程杀死,而在PspTerminateThreadByPointer里,如果线程是被其它进程强x结束的,就会有个这样的判断:
- if (IS_SYSTEM_THREAD(Thread)){
- return STATUS_ACCESS_DENIED;
- }
Thread类型是PETHREAD,IS_SYSTEM_THREAD是个宏,如下:
- #define IS_SYSTEM_THREAD(Thread) (((Thread)->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_SYSTEM)!= 0)
也就是说当线程的ETHREAD.CrossThreadFlags包含PS_CROSS_THREAD_FLAGS_SYSTEM位时,就直接返回拒绝访问,这样线程就不会被结束了。具体参考代码请看wrk 1.2里的文件base\ntos\ps\psdelete.c。
好,现在只要给我们的进程里的每个线程都设置PS_CROSS_THREAD_FLAGS_SYSTEM,进程就不会被结束掉了。但是ETHREAD的结构没有文档化,所以还得自己找到CrossThreadFlags成员在ETHREAD结构里的偏移。可以通过在已导出的相关函数中找一些特征来定位CrossThreadFlags,黑防中是在PsIsSystemThread里找,但是这个函数在Windows 2000里没有,所以我们换个,换成PsTerminateSystemThread,先看下PsTerminateSystemThread的源码:
- NTSTATUS
- PsTerminateSystemThread(
- __in NTSTATUS ExitStatus
- )
- {
- PETHREAD Thread = PsGetCurrentThread();
- if (!IS_SYSTEM_THREAD(Thread)){
- return STATUS_INVALID_PARAMETER;
- }
- return PspTerminateThreadByPointer (Thread, ExitStatus, TRUE);
- }
这里也用到了IS_SYSTEM_THREAD,那么也一定会有定位CrossThreadFlags的代码,如下:
- kd> u PsTerminateSystemThread
- nt!PsTerminateSystemThread:
- 805c89f8 8bff mov edi,edi
- 805c89fa 55 push ebp
- 805c89fb 8bec mov ebp,esp
- 805c89fd 64a124010000 mov eax,dwordptr fs:[00000124h]
- 805c8a03 f6804802000010 test byteptr [eax+248h],10h
- 805c8a0a 7507 jne nt!PsTerminateSystemThread+0x1b(805c8a13)
- 805c8a0c b80d0000c0 mov eax,0C000000Dh
- 805c8a11 eb09 jmp nt!PsTerminateSystemThread+0x24(805c8a1c)
- 805c8a13 ff7508 push dwordptr [ebp+8]
- 805c8a16 50 push eax
- 805c8a17 e828fcffff call nt!PspTerminateThreadByPointer(805c8644)
- 805c8a1c 5d pop ebp
- 805c8a1d c20400 ret 4
得到了偏移,下面就是写代码了,驱动部分:
- #include <ntifs.h>
- #include <ntddk.h>
- #define PS_CROSS_THREAD_FLAGS_SYSTEM 0x00000010UL //form wrk 1.2 base\ntos\inc\ps.h
- #define IOCTL_THREAD_PROTECT CTL_CODE(FILE_DEVICE_UNKNOWN,0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
- VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
- {
- UNICODE_STRING usSymLink;
- RtlInitUnicodeString(&usSymLink, L"\\??\\ThreadProtect");
- IoDeleteSymbolicLink(&usSymLink);
- IoDeleteDevice(pDriverObject->DeviceObject);
- }
- NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- pIrp->IoStatus.Status= STATUS_SUCCESS;
- pIrp->IoStatus.Information= 0;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- NTSTATUS nRet = STATUS_UNSUCCESSFUL;
- ULONG_PTR uInf = 0;
- PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation(pIrp);
- PVOID pSysBuff = pIrp->AssociatedIrp.SystemBuffer;
- switch (pIoStack->Parameters.DeviceIoControl.IoControlCode)
- {
- case IOCTL_THREAD_PROTECT:
- PETHREAD pEThread;
- PsLookupThreadByThreadId(HANDLE(*(PULONG)pSysBuff),&pEThread);
- UNICODE_STRING usName;
- RtlInitUnicodeString(&usName, L"PsTerminateSystemThread");
- PUSHORT pOffset = (PUSHORT)MmGetSystemRoutineAddress(&usName);
- //search "test byte ptr [eax+xxxxxxxx],10h",hex:f680xxxxxxxx10
- while (*pOffset!= 0x80f6)
- pOffset = PUSHORT((PUCHAR)pOffset+ 1);
- PULONG pFlags = PULONG((PUCHAR)pEThread+ *(PULONG)(pOffset+ 1));
- DbgPrint("pOffset:%08x, CrossFlagOffset:%08x\r\n", pOffset,*(PULONG)(pOffset+ 1));
- *pFlags |= PS_CROSS_THREAD_FLAGS_SYSTEM; //set PS_CROSS_THREAD_FLAGS_SYSTEM bit
- nRet = STATUS_SUCCESS;
- uInf = 0;
- break;
- }
- pIrp->IoStatus.Status= nRet;
- pIrp->IoStatus.Information= uInf;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return nRet;
- }
- extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
- {
- pDriverObject->DriverUnload= DriverUnload;
- pDriverObject->MajorFunction[IRP_MJ_CREATE]= DispatchCreateClose;
- pDriverObject->MajorFunction[IRP_MJ_CLOSE]= DispatchCreateClose;
- pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DispatchControl;
- UNICODE_STRING usDeviceName;
- RtlInitUnicodeString(&usDeviceName, L"\\Device\\ThreadProtect");
- NTSTATUS nRet;
- PDEVICE_OBJECT pDeviceObject;
- nRet = IoCreateDevice(pDriverObject,0, &usDeviceName, FILE_DEVICE_UNKNOWN,
- FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
- if (!NT_SUCCESS(nRet))
- return nRet;
- UNICODE_STRING usSymLink;
- RtlInitUnicodeString(&usSymLink, L"\\??\\ThreadProtect");
- nRet = IoCreateSymbolicLink(&usSymLink,&usDeviceName);
- if (!NT_SUCCESS(nRet))
- {
- IoDeleteDevice(pDeviceObject);
- return nRet;
- }
- return STATUS_SUCCESS;
- }
这段代码要解释的都在上面了。EXE部分的代码就不用帖了,只要将每个线程的ID通过DeviceIoControl传入驱动即可:
- #define IOCTL_THREAD_PROTECT CTL_CODE(FILE_DEVICE_UNKNOWN,0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
- DeviceIoControl(hDevice, IOCTL_THREAD_PROTECT, &nThreadId, sizeof(nThreadId),0, 0, &nByteRet, 0);
点击这里下载文件: ThreadProtect.rar
运行后果自行负责,运行不了自行想办法到注册表里删除先前的ThreadProtect键值。
最后,怎么结束用这种方法保护的进程?方法大大的有,插入APC,然后PspExitThread就不会经过PspTerminateThreadByPointer了。
- 进程防结束之PS_CROSS_THREAD_FLAGS_SYSTEM
- 批处理之结束进程
- C# 保护进程不被结束(源代码)防任务管理器结束进程
- C#之结束指定进程!...
- 应用层结束进程之ExitProcess
- windows API学习笔记 之 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- NuGet 发布类库,依赖项的问题
- vim之三--字符的替换和撤销
- 转载: Linux伙伴系统(二)--伙伴系统的初始化
- Linux下编辑文件方式Emacs 操作快速指南,快捷键速记
- svn post-commit hook failed error output could not be translated from the native locale to UTF-8
- 进程防结束之PS_CROSS_THREAD_FLAGS_SYSTEM
- CF 510A(Fox And Snake-模拟)
- Java系统程序员修炼之道
- 第五篇 设计模式--饿汉单例模式
- 正则表达式30分钟入门教程
- Oracle中审计功能
- BZOJ大视野 1088: [SCOI2005]扫雷Mine 解题报告
- 教你写Android网络框架之Request、Response类与请求队列
- Java调用bat文件