多媒体编程、网络编程、系统编程、网络安全编程、驱动编程

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程

针对 NtOpenProcess服务函数HOOK SSDT示例代码,保护记事本进程

#include <ntddk.h>
//////////////////////////////////////////////////////////////////////////
//函数声明
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath);
VOID Unload(PDRIVER_OBJECT pDriverObject);
NTSTATUS        MyNtOpenProcess(OUT PHANDLE ProcessHandle,
                                                        IN ACCESS_MASK AccessMask,
                                                        IN POBJECT_ATTRIBUTES pObjatt,
                                                        IN PCLIENT_ID Client);
NTSTATUS PsLookupProcessByProcessId(IN HANDLE ProcessId,
                                                                        OUT PEPROCESS *Process);
PUCHAR        PsGetProcessImageFileName(IN PEPROCESS process);
//////////////////////////////////////////////////////////////////////////
//结构体声明
typedef struct _SystemServiceDescriptorTable 
{
        PULONG        ServiceTableBase;
        PULONG        ServiceCounterTableBase;
        ULONG        NumberOfService;
        PULONG        ParamTableBase;
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
extern PSystemServiceDescriptorTable KeServiceDescriptorTable;

typedef NTSTATUS (*NTOPENPROCESS)(OUT PHANDLE ProcessHandle,
                                                                                        IN ACCESS_MASK AccessMask,
                                                                                        IN POBJECT_ATTRIBUTES pObjatt,
                                                                                        IN PCLIENT_ID Client);
NTOPENPROCESS RealOpenProcess;
//////////////////////////////////////////////////////////////////////////
#pragma code_seg("INIT")
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
{
        NTSTATUS status = STATUS_SUCCESS;
        //**********************************************************
        //Hook        SSDT
        //**********************************************************
        PULONG        Address;
        PULONG  HookPoint;
        _asm
        {
                pushad
                mov        ebx,KeServiceDescriptorTable ;这里获取到SSDT服务的首地址
                mov        ebx,[ebx] ;将SSDT首地址值放入EBX寄存器中
                mov        eax,0x7a ;我们知道在XP系统中122号SSDT索引号为NtOpenProcess函数地址
                shl        eax,2 ;左移两位表示EAX值乘以4
                add        ebx,eax ;在SSDT基址的基础上加上偏移值就是NtOpenProcess的地址值勤
                mov        HookPoint,ebx ;将获取到的地址值赋值给HookPoint指针变量
                mov        edx,[ebx] ;将NOpenProcess函数地址值放入EDX寄存器
                mov        Address,edx ;将NOpenProcess函数地址值赋值给Address指针变量
                popad
        }
         RealOpenProcess = (NTOPENPROCESS)(Address); //这里将真实的NOpenProcess函数地址值备份保存下来
         DbgPrint("Address of Real NtOpenProcess:0x%08x\n",(Address));
         DbgPrint("Address of Fake NtOpenProcess:0x%08x\n",MyNtOpenProcess);

        //关中断,并关闭页保护属性

_asm

        {
                cli
                mov        eax,cr0
                and        eax,not 10000h
                mov        cr0,eax
        }
        *HookPoint = (ULONG)MyNtOpenProcess; //将真实的NtOpenProcess地址值替换成我们自定义函数的地址值,实现HOOK

       //打开中断,并恢复页保据属性

 _asm

        {
                mov        eax,cr0
                or        eax,10000h
                mov        cr0,eax
                sti
        }
        pDriverObject->DriverUnload = Unload; //卸载例程
        return status;
}

#pragma code_seg("PAGE")
VOID Unload(PDRIVER_OBJECT pDriverObject)

{

//没什么好说的,功能就是卸载时将SSDT中的NtOpenProcess地址值恢复回去,与上面的一样*HookPoint = (ULONG)RealOpenProcess;只不过 //这句是将真实的SSDT中的NtOpenProcess地址恢复回去

        PULONG HookPoint;
        _asm
        {
                pushad
                mov        ebx,KeServiceDescriptorTable
                mov        ebx,[ebx]
                mov        eax,0x7a
                shl        eax,2
                add        ebx,eax
                mov        HookPoint,ebx
                popad
        }
        _asm
        {
                cli
                mov        eax,cr0
                and        eax,not 10000h
                mov        cr0,eax
        }
        *HookPoint = (ULONG)RealOpenProcess;
        _asm
        {
                mov        eax,cr0
                or        eax,10000h
                mov        cr0,eax
                sti
        }
        return;
}

NTSTATUS MyNtOpenProcess(OUT PHANDLE ProcessHandle, 
                                                 IN ACCESS_MASK AccessMask, 
                                                 IN POBJECT_ATTRIBUTES pObjatt, 
                                                 IN PCLIENT_ID Client)

{

//HOOK到以后就可以做我们自己想做的事情了

        NTSTATUS status = STATUS_SUCCESS;
        PEPROCESS lpPEPROCESS;
        PUCHAR ProcessName;
        status = PsLookupProcessByProcessId(Client->UniqueProcess,&lpPEPROCESS);
        if (NT_SUCCESS(status))
        {
                ProcessName = _strupr((PCHAR)PsGetProcessImageFileName(lpPEPROCESS));
                if (strcmp(ProcessName,"NOTEPAD.EXE") == 0)
                {
                        return STATUS_ACCESS_DENIED;
                }

        }
        status = RealOpenProcess(ProcessHandle,AccessMask,pObjatt,Client);
        return status;
}
阅读更多
个人分类: 驱动开发学习
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭