C/C++知识点之InlineHookPsTerminateProcess(0环)
小标 2019-03-01 来源 : 阅读 1692 评论 0

摘要:本文主要向大家介绍了 C/C++知识点之InlineHookPsTerminateProcess(0环),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了 C/C++知识点之InlineHookPsTerminateProcess(0环),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之InlineHookPsTerminateProcess(0环)

PsTerminateProcess函数用于结束一个进程。


#include <ntddk.h>

typedef NTSTATUS (*PSPTERMINATETPROCESS)(
                    PEPROCESS Process,
                    NTSTATUS ExitStatus
                    );
PSPTERMINATETPROCESS PspTerminateProcess;

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;

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) 
                            {
                                PspTerminateProcess=(PSPTERMINATETPROCESS)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 CheckPspTerminateProcessIsHook()
{
    int             i       = 0;
    char            *addr   = (char *)PspTerminateProcess;
    char            code[]  = { 0x8b, 0xff, 0x55, 0x8b, 0xec};

    while(i<5)
    {
        DbgPrint("0x%02X", (unsigned char)addr[i]);
        if(addr[i] != code[i])
        {
            return STATUS_UNSUCCESSFUL;
        }
        i++;
    }
    return STATUS_SUCCESS;
}

int MyPspTerminateProcess(
                          PEPROCESS Process,
                          NTSTATUS ExitStatus
                          )
{
    DbgPrint("PspTerminateProcess hello\n");
    return 1;
}

_declspec(naked) T_PspTerminateProcess(
                                       PEPROCESS Process,
                                       NTSTATUS ExitStatus
                                       )
{
    _asm
    {
        mov edi, edi
            push ebp
            mov ebp ,esp
            push [ebp+0ch]
            push [ebp+8]
            call MyPspTerminateProcess 
            cmp eax,1
            jz end
            mov eax,PspTerminateProcess 
            add eax,5 
            jmp eax

end:
        pop ebp
            retn 8
    }
}

VOID InlineHookPspTerminateProcess()


    int             JmpOffSet = 0;
    unsigned char   JmpCode[5] = { 0xe9, 0x00, 0x00, 0x00, 0x00 };
    KIRQL           oldIrql;

    if (PspTerminateProcess == 0)
    {
        DbgPrint("PspTerminateProcess NOT FOUND\n");
        return;
    }

    DbgPrint("PspTerminateProcess is found at:0x%08x\n", (ULONG)PspTerminateProcess );

    DbgPrint("T_PspTerminateProcess is:%x\n",T_PspTerminateProcess);
    JmpOffSet= (char*)T_PspTerminateProcess - (char*)PspTerminateProcess - 5;
    DbgPrint("JmpOffSet is:%x\n",JmpOffSet);
    RtlCopyMemory ( JmpCode+1, &JmpOffSet, 4 );

    _asm
    {
        CLI
        MOV EAX, CR0
        AND EAX, NOT 10000H
        MOV CR0, EAX
    }
    oldIrql = KeRaiseIrqlToDpcLevel();
    RtlCopyMemory ( PspTerminateProcess, JmpCode, 5 );
    DbgPrint("PspTerminateProcess is hook now \n");
    KeLowerIrql(oldIrql);

    _asm
    {
        MOV EAX, CR0
        OR EAX, 10000H
        MOV CR0, EAX
        STI
    }

}

VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
    //  在win2000上是三字节
    //  push ebp
    //  mov ebp, esp
    //        
    //  到了winxp以及后续系统上,则变成了五字节
    //  mov edi, edi
    //  push ebp
    //  mov ebp, esp
    //  函数的序言

    unsigned char Code[5]={0x8b,0xff,0x55,0x8b,0xec};

    _asm
    {
        CLI
        MOV eax, CR0
        AND eax, NOT 10000H
        MOV CR0, eax

        pushad
        mov edi, PspTerminateProcess
        mov eax, dword ptr Code[0]
        mov [edi], eax
        mov al, byte ptr Code[4]
        mov [edi+4], al
        popad

        MOV eax, CR0
        OR eax, 10000H
        MOV CR0, eax
        STI
    }

    DbgPrint("Goodbye driver\n");
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath)
{
    GetPspAddr();
    if(PspTerminateProcess == NULL)
    {
        DbgPrint("PspFunc Not Find!\n");
        return STATUS_UNSUCCESSFUL;
    }

    if(STATUS_SUCCESS != CheckPspTerminateProcessIsHook())
    {
        DbgPrint("PspTerminateProcess Match Failed !");
        return STATUS_UNSUCCESSFUL;
    }

    InlineHookPspTerminateProcess();

    pDriverObject->DriverUnload = DriverUnload;
    return STATUS_SUCCESS;

}

   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 2 不喜欢 | 0
看完这篇文章有何感觉?已经有2人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程