看流星社区

 找回密码
 注册账号
查看: 2248|回复: 0

进程强杀

[复制链接]

该用户从未签到

发表于 2017-6-1 13:34:11 | 显示全部楼层 |阅读模式
强杀进程
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-&gtarameters.DeviceIoControl.InputBufferLength;
    outputBuffer            = Irp->AssociatedIrp.SystemBuffer;
    outputBufferLength      = irpStack-&gtarameters.DeviceIoControl.OutputBufferLength;
    ioControlCode           = irpStack-&gtarameters.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(&quotrocess 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(&quotspFunc 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&quotsTerminateSystemThread");
        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 进程,也可以结束
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 19:09

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表