-
-
[原创]SSDT InlineHook学习笔记
-
发表于:
2015-5-9 00:59
10660
-
最近学习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;
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)