进程强杀

强杀进程

PsTerminateProcessPspTerminateProcess
PspTerminateThreadByPointerPspExitThread
未导出函数
暴力搜索
特征值 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->Parameters.DeviceIoControl.InputBufferLength;
    outputBuffer            = Irp->AssociatedIrp.SystemBuffer;
    outputBufferLength      = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode           = irpStack->Parameters.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("Process 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("PspFunc Not Find!\n");
	}
	return STATUS_SUCCESS;
}


下面一种就方便很多
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
);


根据反汇编代码可以看出 PspTerminateThreadByPointer 的特征码是 01e8,于是有了
以下代码:
	ULONG32 callcode=0;
	ULONG64 AddressOfPspTTBP=0, AddressOfPsTST=0, i=0;
	AddressOfPsTST=(ULONG64)GetFunctionAddr(L"PsTerminateSystemThread");
	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;
		


接下来就是调用 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);
		}
	}


驱动部分基本写好了,最后在分发函数里获得 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;
		}


输入 ZhuDongFangYu.exe 的 PID,大概过了 20 秒,
ZhuDongFangYu.exe 就退出了。在测试例如 360safe.exe 之类的 GUI 进程,也可以结束



你可能感兴趣的:(内核,windbg,进程强杀)