zoukankan      html  css  js  c++  java
  • Delphi实现SSDT Hook

    关于SSDT Hook的理论知识就不多说了。
    简单的说一下Delphi开发KMD的一些需要注意的地方...

    这里使用DDDK---有点自己修改过的痕迹不过区别不大...自己可以看代码
    1.KeServiceDescriptorTable是一个很特殊的函数...如果直接使用implib来进行创建库的话
    你会发现这个函数是被忽略的...因为偏移为0所以这个函数基本上只能起到标志作用没有任何实用价值....一些代码中出现了

    代码:
    function SystemService(AFunc:Pointer):PLONG;
    begin
    Result:=PLONG(Cardinal(KeServiceDescriptorTable^.ServiceTableBase)+SizeOf(ULONG)*PULONG(ULONG(AFunc)+1)^);
    end;
    很容易让人误认为是运行后的返回值(PS:Delphi的函数调用可以不需要写xxx())
    上面说过因为这个函数几乎是没用的...所以不可能是执行他后返回地址
    还有一点需要注意的...难道这个地址是说函数的地址??
    导入表中的确是可以创建这个函数...但是这个函数几乎是没用的...而且系统的SYS Loader也不可能为他填写正确的函数地址...
    这里取得地址就是他的本身地址...因为他的虚拟偏移为0
    所以你直接使用

    代码:
    PPointer(@KeServiceDescriptorTable)^;
    得到这个地址就可以了

    2.fastcall的问题
    这个问题很头痛.这个函数和delphi的调用方式完全不一样
    很容易让人误认为是相同的Delphi的寄存器调用方式是
    eax,edx,ecx,push...,etc
    vc的fastcall大部分是edx,ecx,etc....
    所以为了解决这个问题需要自己重写某些代码部分...

    3.基本上没什么需要注意了自己做好链接库您当然可以使用
    mickeylan牛为我们制作的rmcoff...

    4.调试部分WinDbg什么的我就不说了...因为无法进行源码调试
    个人觉得SysDebuger就不错其实asm也就那么回事。不是吗?呵呵

    下面写一个完整的SSDT Hook

    代码:
    {
       NtOpenProcess[SSDT Hook] By Anskya
       Email: Anskya[at]Gmail.com
    }
    unit Driver;

    interface

    uses
       ntddk;   // ---->DDDK.pas

    function _DriverEntry(DriverObject: PDriverObject; RegistryPath: PUnicodeString): NTSTATUS; stdcall;

    implementation

    type
       TZwOpenProcess = function(ProcessHandle:PHandle; DesiredAccess:TAccessMask; ObjectAttributes:PObjectAttributes; ClientId:PClientId): NTSTATUS; stdcall;

    var
       HookActive: Boolean;
       ZwOpenProcessNextHook: TZwOpenProcess;

    //   从导入表中获取一个函数的地址
    function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
    begin
       Result := PPointer(PPointer(Cardinal(lpImportAddr) + 2)^)^;
    end;

    //   KeServiceDescriptorTable+函数名计算SSDT函数偏移
    function SystemServiceName(AFunc: Pointer): PLONG; stdcall;
    var
       lpKeServiceDescriptorTable: PServiceDescriptorEntry;
    begin
       lpKeServiceDescriptorTable := PPointer(@KeServiceDescriptorTable)^;
       Result := PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * PULONG(ULONG(AFunc) + 1)^));
    end;

    //   KeServiceDescriptorTable+序号名计算SSDT函数偏移
    function SystemServiceOrd(iOrd: ULONG): PLONG; stdcall;
    var
       lpKeServiceDescriptorTable: PServiceDescriptorEntry;
    begin
       lpKeServiceDescriptorTable := PPointer(@KeServiceDescriptorTable)^;
       Result := PLONG(PLONG(Cardinal(lpKeServiceDescriptorTable^.ServiceTableBase) + (SizeOf(ULONG) * iOrd)));
    end;

    //   钩子过程
    function ZwOpenProcessHookProc(ProcessHandle:PHandle; DesiredAccess:TAccessMask; ObjectAttributes:PObjectAttributes; ClientId:PClientId): NTSTATUS; stdcall;
    begin
       DbgPrint('ZwOpenProcess HookProc: NewZwOpenProcess(ProcessHandle:0x%.8X,DesiredAccess:0x%.8X,ObjectAttributes:0x%.8X,ClientId:0x%.8X)',
             ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);

       Result := ZwOpenProcessNextHook(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
       DbgPrint('ZwOpenProcess HookProc: NewZwOpenProcess(-):0x%.8X', Result);
    end;

    //   驱动卸载过程
    procedure DriverUnload(DriverObject:PDriverObject); stdcall;
    begin
       if (HookActive) then
       begin
         asm
           cli                                               //disable WP bit
           push   eax
           mov   eax, cr0                                     //move CR0 register into EAX
           and   eax, not 000010000h                         //disable WP bit
           mov   cr0, eax                                     //write register back
           pop   eax
         end;

         ZwOpenProcessNextHook := TZwOpenProcess(xInterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)), LONG(@ZwOpenProcessNextHook)));

         asm
           push   eax                                           //enable WP bit
           mov   eax, cr0                                       //move CR0 register into EAX
           or     eax, 000010000h                               //enable WP bit
           mov   cr0, eax                                       //write register back
           pop   eax
           sti
         end;

         DbgPrint('ZwOpenProcess New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);
         DbgPrint('ZwOpenProcess Old Address: 0x%.8X', DWORD(@ZwOpenProcessNextHook));

         HookActive := False;
       end;
       DbgPrint('DriverUnload(-)');
    end;

    //   驱动入口点
    function _DriverEntry(DriverObject:PDriverObject;RegistryPath:PUnicodeString): NTSTATUS; stdcall;
    begin
       DriverObject^.DriverUnload := @DriverUnload;
       Result := STATUS_SUCCESS;
       DbgPrint('DriverEntry(-):0x%.8X', Result);

       HookActive := False;

       DbgPrint('ZwOpenProcess Import Address: 0x%.8X', GetImportFunAddr(@ZwOpenProcess));
       DbgPrint('KeServiceDescriptorTable() Address 1: 0x%.8X', @KeServiceDescriptorTable);
       DbgPrint('KeServiceDescriptorTable() Address 2: 0x%.8X', PPointer(@KeServiceDescriptorTable)^);

       DbgPrint('ZwOpenProcess ord Address: 0x%.8X', SystemServiceOrd($7A)^);     //   XP ord!
       DbgPrint('ZwOpenProcess Name Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);
       DbgPrint('ZwOpenProcess HookProc Address: 0x%.8X', @ZwOpenProcessHookProc);

       if (Not HookActive) then
       begin
         //   SSDT Hook
         asm                                             //disable WP bit
           cli
           push   eax
           mov   eax, cr0                                   //move CR0 register into EAX
           and   eax, not 000010000h                         //disable WP bit
           mov   cr0, eax                                   //write register back
           pop   eax
         end;

         //lpNew^ := LONG(lpOld);
         ZwOpenProcessNextHook := TZwOpenProcess(xInterlockedExchange(SystemServiceName(GetImportFunAddr(@ZwOpenProcess)), LONG(@ZwOpenProcessHookProc)));

         asm
           push   eax                                       //enable WP bit
           mov   eax, cr0                                   //move CR0 register into EAX
           or     eax, 000010000h                           //enable WP bit
           mov   cr0, eax                                   //write register back
           pop   eax
           sti
         end;

         DbgPrint('ZwOpenProcess New Address: 0x%.8X', SystemServiceName(GetImportFunAddr(@ZwOpenProcess))^);
         DbgPrint('ZwOpenProcess Old Address: 0x%.8X', DWORD(@ZwOpenProcessNextHook));

         HookActive := True;
       end else
       begin
         DbgPrint('ZwOpenProcess Hooked!!! By Anskya');
       end;

    end;

    end.
    关于function GetImportFunAddr(lpImportAddr: Pointer): Pointer; stdcall;
    这个函数稍微说一下...
    如果你使用的连接库是x86模式的你就不能这样了。。。
    这个是标准格式...
    call [xxxx]---->jmp [xxxxxx]---->函数地址
    x86模式的lib是直接
    call [xxxx]---->函数地址
    这里需要注意一下
    这个函数你可以本地获取一下Ring3下的函数地址吧...这个我就不多说了...
    相信大家import hook玩的都比我熟

  • 相关阅读:
    Python中的类(上)
    Django REST Framework API Guide 07
    Django REST Framework API Guide 06
    Django REST Framework API Guide 05
    Django REST Framework API Guide 04
    Django REST Framework API Guide 03
    Django REST Framework API Guide 02
    Django REST Framework API Guide 01
    Django 详解 信号Signal
    Django 详解 中间件Middleware
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/2178877.html
Copyright © 2011-2022 走看看