首页
社区
课程
招聘
[原创]SSDT InlineHook学习笔记
发表于: 2015-5-9 00:59 10647

[原创]SSDT InlineHook学习笔记

2015-5-9 00:59
10647

最近学习SSDT InlineHook,看了很多论坛前辈的文章,收获很多,代码很长,也很完善,但觉得有点难理解,太完善的代码会禁锢人的思维,发现问题通过努力自己解决,岂不理解得更加深刻?纸上得来终觉浅,绝知此事要躬行。下面说说我对InlineHook的理解,以NtOpenProcess为例。先看下正常的NtOpenProcess的执行流程,如图1:



我们应该怎么Hook这个函数呢,最简单的方法只需要把函数头的push 0C4h改为jmp xxxxxxx就可以了,当调用NtOpenProcess的时候,就会跳到我们的Hook函数上,就可以为所欲为了。这就是InlineHook,改变函数内部执行流程的Hook就是InlineHook。Hook后的函数,如图2:



我们看到原函数的push 04Ch已经变为jmp f7c15600,这个跳转的地址就是HookedNtOpenProcess的地址。那么问题来了,我们如何把原函数头部的push指令改为jmp指令,使其跳转到我们的Hooked函数上呢。我们必须要取得两个函数的地址,由于SSDT表是导出的,所以取得NtOpenProcess非常简单.

typedef struct _SERVICE_DESCRIPTOR_TABLE
{
  PVOID    ServiceTableBase;
  PULONG   ServiceCounterTableBase;
  ULONG    NumberOfService;
  ULONG    ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; 

Extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;       //KeServiceDescriptorTable为导出函数

Address=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0x7A*4;
//存放NtOpenProcess的数组下标为7A,

OldServiceAddress=*(ULONG*)Address;  
//取得Address中的内容,为NtOpenProcess地址。
ULONG OldServiceAddress;                                         //原来NtOpenProcess的服务地址

VOID Hook(int *PID)
{  //HANDLE pid;
     ULONG temp;
  ULONG Address;
  ULONG jmpaddr;
  Address=(ULONG)KeServiceDescriptorTable->ServiceTableBase+0x7A*4;    //0x7A为NtOpenProcess服务ID
  DbgPrint("Address:0x%08X\n",Address);
  MyPID=(HANDLE)*PID;
  OldServiceAddress=*(ULONG*)Address;                                  //保存原来NtOpenProcess的地址
  RealNtOpenProcess=(NTOPENPROCESS)OldServiceAddress;
  DbgPrint("RealNtOpenProcess:0x%08X\n",RealNtOpenProcess);

  DbgPrint("MyNtOpenProcess:0x%08X\n",MyNtOpenProcess);

  __asm                                                                //去掉关内存保护
  {
        cli
      mov    eax,cr0
      and    eax,not 10000h
      mov    cr0,eax
  }


     temp=*((ULONG*)Address);
     DbgPrint("temp:%08X\n",temp);
     jmpaddr=(ULONG)MyNtOpenProcess-(ULONG)RealNtOpenProcess-5;
         __asm
         {
           mov ebx,temp
           mov eax,jmpaddr
           mov byte ptr ds:[ebx],0xE9           //在原来函数头加jmp 
           mov DWORD ptr ds:[ebx+1],eax
         }

  __asm                                                               //恢复开内存保护 
  {
        mov    eax,cr0
      or     eax,10000h
      mov    cr0,eax
      sti
  }
  DbgPrint("hook\n");
}
NTSTATUS __declspec(naked)(__stdcall MyNtOpenProcess)(
                                              PHANDLE ProcessHandle,
                        ACCESS_MASK DesiredAccess,
                        POBJECT_ATTRIBUTES ObjectAttributes,
                        PCLIENT_ID ClientId) 
{
  __asm
  {
  
          retn 0x10   //执行保护后的返回
  }
typedef struct _CLIENT_ID {
    HANDLE UniqueProcess;
    HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 3
支持
分享
最新回复 (15)
雪    币: 764
活跃值: (147)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不错,赞一个!
2015-5-9 01:24
0
雪    币: 5147
活跃值: (3367)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
挺好~~~~~~
2015-5-9 04:07
0
雪    币: 1392
活跃值: (5107)
能力值: ( LV13,RANK:240 )
在线值:
发帖
回帖
粉丝
4
inline hook还是要考虑多核蓝屏问题。最好HOOK四个字节或者8字节 用原子锁这样的
2015-5-9 09:12
0
雪    币: 60
活跃值: (439)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
5
谢大神指点。我还有许多细节需要学习~
2015-5-9 09:42
0
雪    币: 2822
活跃值: (154)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
学习一下,请教下r0那个要怎么编译出来
2015-5-9 11:17
0
雪    币: 60
活跃值: (439)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
7
你不是没装WDK把,在wdk命令行下,指定目录,build就可以了~
2015-5-9 11:27
0
雪    币: 2822
活跃值: (154)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
谢谢,楼主能否分享下学习的资料,对驱动有点无从下手
2015-5-14 01:11
0
雪    币: 60
活跃值: (439)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
9
驱动的书比较少,一般都是看张帆的windows驱动开发技术详解。
2015-5-14 08:39
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
很详细的讲解
2015-5-14 08:39
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
122是在xp下的地址,在win7下不同,但是我在win7下测试,hook成功,但是会立马蓝屏呢?
2015-5-14 14:39
0
雪    币: 60
活跃值: (439)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
12
这个函数在WIN7的索引已经变了,而且头部也不是push 04c,肯定会蓝屏的
2015-5-14 16:09
0
雪    币: 16
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
哦,索引我改了,那就是头部的问题了
2015-5-14 17:06
0
雪    币: 29
活跃值: (184)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
感谢分享,在win7中的函数头部就是mov  edi,edi  push  ebp  mov  ebp,esp,和普通的hook头五个字节一样
2017-7-15 10:47
0
雪    币: 29
活跃值: (184)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
建议再hook前保存好原函数的前五个字节,方便对hook的恢复
2017-7-15 11:53
0
雪    币: 1319
活跃值: (1330)
能力值: ( LV8,RANK:140 )
在线值:
发帖
回帖
粉丝
16
仁兄,我也做过一个类似的,只不过hook了ntterminateprocess,效果就是任务管理器无法关闭程序了,你这个思路好像更好点
2017-7-15 12:07
0
游客
登录 | 注册 方可回帖
返回
//