- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
强杀进程
PsTerminateProcess?PspTerminateProcess?
PspTerminateThreadByPointer?PspExitThread[/code]未导出函数
暴力搜索
特征值 xp的
0x8B55ff8B
0xA16456EC
0x00000124
0x3B08758B
内核地址空间NtQueryXXX / AuxKlibQueryModuleInformation
ntosknlEndAddr
ntosknlBase
以下代码效率很低 而且只支持XP
#include <ntddk.h>
#include <ntimage.h>
#include <ntdef.h>
#include "Ioctlcmd.h"
const WCHAR deviceLinkBuffer[] = L"\\DosDevices\\KillProc";
const WCHAR deviceNameBuffer[] = L"\\Device\\KillProc";
typedef NTSTATUS (*NTQUERYSYSTEMINFORMATION)(
IN ULONG SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL );
typedef unsigned long DWORD;
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
#define SystemModuleInformation 11
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
PDEVICE_OBJECT g_HookDevice;
NTSTATUS PsLookupProcessByProcessId(ULONG ProcessId,PEPROCESS *Process);
typedef NTSTATUS (*PSPTERPROC) ( PEPROCESS Process, NTSTATUS ExitStatus );
PSPTERPROC MyPspTerminateProcess = NULL ;
NTSTATUS OnUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING deviceLinkUnicodeString;
PDEVICE_OBJECT p_NextObj;
DbgPrint("OnUnload called\n");
p_NextObj = DriverObject->DeviceObject;
if (p_NextObj != NULL)
{
RtlInitUnicodeString( &deviceLinkUnicodeString, deviceLinkBuffer );
IoDeleteSymbolicLink( &deviceLinkUnicodeString );
IoDeleteDevice( DriverObject->DeviceObject );
}
return STATUS_SUCCESS;
}
NTSTATUS
DispatchControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION irpStack;
PVOID inputBuffer;
PVOID outputBuffer;
PVOID userBuffer;
ULONG inputBufferLength;
ULONG outputBufferLength;
ULONG ioControlCode;
NTSTATUS ntstatus;
unsigned int i;
unsigned total = 0;
ULONG count = 0;
HANDLE handle;
ULONG cnt;
PEPROCESS Eprocess = NULL;
DWORD pid;
ntstatus = Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
irpStack = IoGetCurrentIrpStackLocation (Irp);
inputBuffer = Irp->AssociatedIrp.SystemBuffer;
inputBufferLength = irpStack->arameters.DeviceIoControl.InputBufferLength;
outputBuffer = Irp->AssociatedIrp.SystemBuffer;
outputBufferLength = irpStack->arameters.DeviceIoControl.OutputBufferLength;
ioControlCode = irpStack->arameters.DeviceIoControl.IoControlCode;
switch (irpStack->MajorFunction)
{
case IRP_MJ_CREATE:
break;
case IRP_MJ_SHUTDOWN:
break;
case IRP_MJ_CLOSE:
break;
case IRP_MJ_DEVICE_CONTROL:
if(IOCTL_TRANSFER_TYPE(ioControlCode) == METHOD_NEITHER)
{
outputBuffer = Irp->UserBuffer;
}
switch (ioControlCode )
{
case IOCTL_PROC_KILL:
if(MyPspTerminateProcess==NULL)
{
*(DWORD*)outputBuffer = -1;
Irp->IoStatus.Information = sizeof(DWORD);
}
else
{
pid = *(DWORD*)inputBuffer;
{
ntstatus = PsLookupProcessByProcessId(pid , &Eprocess);
if(!NT_SUCCESS(ntstatus))
{
DbgPrint("Failed to lookup process 0x%x, status %8.8x\n", pid , ntstatus);
*(DWORD*)outputBuffer = 1;
Irp->IoStatus.Information = sizeof(DWORD);
break;
}
DbgPrint("Lookup of process 0x%x, PEPROCESS at %8.8x\n", pid, Eprocess);
ntstatus = MyPspTerminateProcess(Eprocess, 0);
if(!NT_SUCCESS(ntstatus))
{
DbgPrint("Failed to terminate process 0x%x, status %8.8x\n", pid, ntstatus);
*(DWORD*)outputBuffer = 2;
Irp->IoStatus.Information = sizeof(DWORD);
break;
}
*(DWORD*)outputBuffer = 0;
Irp->IoStatus.Information = sizeof(DWORD);
DbgPrint("rocess 0x%x terminated\n", pid);
}
}
break;
default:
break;
}
IoCompleteRequest( Irp, IO_NO_INCREMENT );
}
return ntstatus;
}
NTSTATUS DispatchCreate (
IN PDEVICE_OBJECT pDevObj,
IN PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );
}
VOID DoFind(IN PVOID pContext)
{
NTSTATUS ret;
PSYSTEM_MODULE_INFORMATION module = NULL;
ULONG n=0;
void *buf = NULL;
ULONG ntosknlBase;
ULONG ntosknlEndAddr;
ULONG curAddr;
ULONG code1_sp3=0x8b55ff8b,code2_sp3=0xA16456EC,code3_sp3=0x00000124,code4_sp3=0x3B08758B;
ULONG i;
NtQuerySystemInformation=(NTQUERYSYSTEMINFORMATION)GetFunctionAddr(L"NtQuerySystemInformation");
if (!NtQuerySystemInformation)
{
DbgPrint("Find NtQuerySystemInformation faild!");
goto Ret;
}
ret=NtQuerySystemInformation(SystemModuleInformation,&n,0,&n);
if (NULL==( buf=ExAllocatePoolWithTag(NonPagedPool, n, 'DFSP')))
{
DbgPrint("ExAllocatePool() failed\n" );
goto Ret;
}
ret=NtQuerySystemInformation(SystemModuleInformation,buf,n,NULL);
if (!NT_SUCCESS(ret)) {
DbgPrint("NtQuerySystemInformation faild!");
goto Ret;
}
module=(PSYSTEM_MODULE_INFORMATION)((PULONG)buf+1);
ntosknlEndAddr=(ULONG)module->Base+(ULONG)module->Size;
ntosknlBase=(ULONG)module->Base;
curAddr=ntosknlBase;
ExFreePool(buf);
for (i=curAddr;i<=ntosknlEndAddr;i++)
{
if (*((ULONG *)i)==code1_sp3)
{
if (*((ULONG *)(i+4))==code2_sp3)
{
if (*((ULONG *)(i+8))==code3_sp3)
{
if (*((ULONG *)(i+12))==code4_sp3)
{
MyPspTerminateProcess=(PSPTERPROC)i;
break;
}
}
}
}
}
Ret:
PsTerminateSystemThread(STATUS_SUCCESS);
}
VOID GetPspAddr()
{
HANDLE hThread;
PVOID objtowait=0;
NTSTATUS dwStatus =
PsCreateSystemThread(
&hThread,
0,
NULL,
(HANDLE)0,
NULL,
DoFind,
NULL
);
NTSTATUS st;
if ((KeGetCurrentIrql())!=PASSIVE_LEVEL)
{
st=KfRaiseIrql(PASSIVE_LEVEL);
}
if ((KeGetCurrentIrql())!=PASSIVE_LEVEL)
{
return;
}
ObReferenceObjectByHandle(
hThread,
THREAD_ALL_ACCESS,
NULL,
KernelMode,
&objtowait,
NULL
);
st=KeWaitForSingleObject(objtowait,Executive,KernelMode,FALSE,NULL); //NULL表示无限期等待.
return;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
NTSTATUS rc;
RTL_OSVERSIONINFOW osvi;
NTSTATUS ntStatus;
UNICODE_STRING deviceNameUnicodeString;
UNICODE_STRING deviceLinkUnicodeString;
RtlInitUnicodeString (&deviceNameUnicodeString,
deviceNameBuffer );
RtlInitUnicodeString (&deviceLinkUnicodeString,
deviceLinkBuffer );
ntStatus = IoCreateDevice ( DriverObject,
0,
&deviceNameUnicodeString,
FILE_DEVICE_SWAP,
0,
TRUE,
&g_HookDevice );
if(! NT_SUCCESS(ntStatus))
{
DbgPrint(("Failed to create device!\n"));
return ntStatus;
}
ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
&deviceNameUnicodeString );
if(! NT_SUCCESS(ntStatus))
{
IoDeleteDevice(DriverObject->DeviceObject);
DbgPrint("Failed to create symbolic link!\n");
return ntStatus;
}
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl;
DriverObject->DriverUnload = OnUnload;
GetPspAddr();
if(MyPspTerminateProcess == NULL)
{
DbgPrint("spFunc Not Find!\n");
}
return STATUS_SUCCESS;
}
[/code]
下面一种就方便很多
Win7 x64下强制结束进程
对于用 ObRegisterCallbacks 进行自我保护的进程,要杀死他们的方法只有两种:一种
是温柔的方法,一种是暴力的方法。温柔的方法就是移除对象回调,而暴力的方法,就是找
到更底层的结束进程函数并调用。对付“保护句柄”类的进程保护手段,比较好的方法循坏
调 用 PspTerminateThreadByPointer 来 结 束 进 程 的 每 一 个线 程 。 下 文 拿 360 的
ZhuDongFangYu.exe举例,因为360在Win64上实现自我保护就是使用ObRegisterCallbacks。
总体思路很简单:通过 NTOSKRNL.EXE 导出的 PsTerminateSystemThread 动态定位未导出的
PspTerminateThreadByPointer 。 再 用 PspTerminateThreadByPointer 依 次 结 束
ZhuDongFangYu.exe 的每一个线程。
首先对 PsTerminateSystemThread 进行反汇编:
lkd> uf PsTerminateSystemThread
nt!PsTerminateSystemThread:
fffff800`03f65860 4883ec28 sub rsp,28h
fffff800`03f65864 8bd1 mov edx,ecx
fffff800`03f65866 65488b0c2588010000 mov rcx,qword ptr gs:[188h]
fffff800`03f6586f f6814804000010 test byte ptr [rcx+448h],10h
fffff800`03f65876 0f8485cd0200 je nt! ?? ::NNGAKEGL::`string'+0x29eb0
(fffff800`03f92601)
nt!PsTerminateSystemThread+0x1c:
fffff800`03f6587c 41b001 mov r8b,1
fffff800`03f6587f e8d0590500 call nt!PspTerminateThreadByPointer (fffff800`03fbb254)
fffff800`03f65884 90 nop
fffff800`03f65885 e97ccd0200 jmp nt! ?? ::NNGAKEGL::`string'+0x29eb5
(fffff800`03f92606)
nt! ?? ::NNGAKEGL::`string'+0x29eb0:
fffff800`03f92601 b80d0000c0 mov eax,0C000000Dh
nt! ?? ::NNGAKEGL::`string'+0x29eb5:
fffff800`03f92606 4883c428 add rsp,28h
fffff800`03f9260a c3 ret
注意染成蓝色的那两行,除了告诉我们 PsTerminateSystemThread 调用了
PspTerminateThreadByPointer 外,还提示了一个重要的信息:在 Windows 7 x64 上的
PspTerminateThreadByPointer 有三个参数,不同于 Windows XP x86 上的
PspTerminateThreadByPointer 只有两个参数。因为根据 WIN64 上的__fastcall 调用约
定,函数的前四个参数分别放在 rcx、rdx、r8、r9 里(r8b 是一个新增加的寄存器,长度
为 1 字节,是 r8 的低 8 位),从第五个参数开始才放在堆栈里。然后查了一下 WRK,估计
它的原型是:
typedef NTSTATUS (__fastcall *PSPTERMINATETHREADBYPOINTER)
(
IN PETHREAD Thread,
IN NTSTATUS ExitStatus,
IN BOOLEAN DirectTerminate
);[/code]
根据反汇编代码可以看出 PspTerminateThreadByPointer 的特征码是 01e8,于是有了
以下代码:
ULONG32 callcode=0;
ULONG64 AddressOfPspTTBP=0, AddressOfPsTST=0, i=0;
AddressOfPsTST=(ULONG64)GetFunctionAddr(L"sTerminateSystemThread");
if(AddressOfPsTST==0)
return STATUS_UNSUCCESSFUL;
for(i=1;i<0xff;i++)
{
if(MmIsAddressValid((PVOID)(AddressOfPsTST+i))!=FALSE)
{
if(*(BYTE *)(AddressOfPsTST+i)==0x01 && *(BYTE *)(AddressOfPsTST+i+1)==0xe8) //目标地址-原始地址-5=机器码 ==> 目标地址=机器码+5+原始地址
{
RtlMoveMemory(&callcode,(PVOID)(AddressOfPsTST+i+2),4);
AddressOfPspTTBP=(ULONG64)callcode + 5 + AddressOfPsTST+i+1;
}
}
}
PspTerminateThreadByPointer=(PSPTERMINATETHREADBYPOINTER)AddressOfPspTTBP;
[/code]
接下来就是调用 PspTerminateThreadByPointer 干掉制定进程的所有线程即可。我的
办法是用 PsLookupThreadByThreadId 查询 0x4 至 0x40000 之间所有能被 4 整除的数字,如
果查询成功,就使用 IoThreadToProcess 得到此线程所属的进程。如果它是属于要干掉的
进程,就调用 PspTerminateThreadByPointer 结束之,否则不做处理。另外要注意的是,
但凡 Lookup,必需 Dereference,否则在某些时候会造成蓝屏的后果。代码如下:
PETHREAD Thread=NULL;
PEPROCESS tProcess=NULL;
NTSTATUS status=0;
for(i=4;i<0x40000;i+=4)
{
status=PsLookupThreadByThreadId((HANDLE)i, &Thread);
if(NT_SUCCESS(status))
{
tProcess=IoThreadToProcess(Thread);
if(tProcess==Process)
PspTerminateThreadByPointer(Thread,0,1);
ObDereferenceObject(Thread);
}
}[/code]
驱动部分基本写好了,最后在分发函数里获得 PID,并通过 PID 得到 EPROCESS 再调用
HwlTerminateProcess64 即可(以上两段代码是为了讲解方便才分开的,实际上它们在一
个函数里):
case IOCTL_KILLPROCESS:
{
__try
{
Inbuff = *(ULONG*)pIoBuffer;
KdPrint(("Kill Process:%d",Inbuff));
Eprocess = (ULONGLONG)GetEProcessByPid((HANDLE)Inbuff);
if(Eprocess != 0){
MyPsTerminateSystemProcess((PEPROCESS)Eprocess);
ObDereferenceObject((PEPROCESS)Eprocess);
RtlCopyMemory(
pIrp->AssociatedIrp.SystemBuffer,
&Eprocess,
sizeof(ULONGLONG)
);
}else
{
RtlCopyMemory(
pIrp->AssociatedIrp.SystemBuffer,
&Eprocess,
sizeof(ULONGLONG)
);
}
status = STATUS_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("结束进程出现异常!"));
}
break;
}[/code]
输入 ZhuDongFangYu.exe 的 PID,大概过了 20 秒,
ZhuDongFangYu.exe 就退出了。在测试例如 360safe.exe 之类的 GUI 进程,也可以结束 |
|