当前位置: 首页 > news >正文

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;

}

转载于:https://blog.51cto.com/haidragon/2307170

相关文章:

  • 人工智能会改变世界?那这项技能你必须要掌握了。
  • 如何洞悉城市人群移动规律?DataV海量轨迹可视化实践解析
  • webpack4 正确的配置方式
  • 5s管理推进的三个阶段及三大实施原则
  • 小程序生命周期流程
  • 前端缓存-IndexedDB
  • 生产LVS负载均衡与keepalive的高可用实践
  • SQL数据库字段数据类型详细说明
  • *Algs4-1.5.25随机网格的倍率测试-(未读懂题)
  • Mysql密码重置
  • hadoop之旅6-windows本地MapReducer离线单词统计
  • 获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录
  • 【火炉炼AI】机器学习053-数据降维绝招-PCA和核PCA
  • 兄弟连区块链教程Fabric1.0源代码分析Ledger(账本)一
  • 简单远程遥控程序【网络程序设计 - 简单远程遥控程序,C实现】
  • 分享的文章《人生如棋》
  • 2017-09-12 前端日报
  • es6--symbol
  • js
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • mongo索引构建
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • PHP的Ev教程三(Periodic watcher)
  • rabbitmq延迟消息示例
  • Spring Boot MyBatis配置多种数据库
  • Transformer-XL: Unleashing the Potential of Attention Models
  • vagrant 添加本地 box 安装 laravel homestead
  • Webpack 4 学习01(基础配置)
  • 初识 webpack
  • 解决iview多表头动态更改列元素发生的错误
  • 我的面试准备过程--容器(更新中)
  • ​520就是要宠粉,你的心头书我买单
  • # 安徽锐锋科技IDMS系统简介
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • #android不同版本废弃api,新api。
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • (1)(1.9) MSP (version 4.2)
  • (4)Elastix图像配准:3D图像
  • (C#)Windows Shell 外壳编程系列4 - 上下文菜单(iContextMenu)(二)嵌入菜单和执行命令...
  • (C语言)字符分类函数
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第5章第5节(delphi中的指针)
  • (HAL库版)freeRTOS移植STMF103
  • (Redis使用系列) Springboot 实现Redis消息的订阅与分布 四
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (三)Honghu Cloud云架构一定时调度平台
  • (一)RocketMQ初步认识
  • (原創) 物件導向與老子思想 (OO)
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • (转)视频码率,帧率和分辨率的联系与区别
  • **PHP分步表单提交思路(分页表单提交)
  • .NET Core WebAPI中封装Swagger配置
  • .NET DataGridView数据绑定说明
  • .net framework4与其client profile版本的区别