A、选取HOOK地址
B、分析等HOOK函数参数
C、构建HOOK 代码
D、实现HOOK
E、测试效果
课时:26
32 ssdt hook
eb ba52c07e 90
u nt!NtOpenProcess
u nt!NtOpenProcess l 100
jmp //0xE9
//jmp my_NtOpenProcess
// NtOpenProcess=jmp my_NtOpenProcess // my_NtOpenProcess-RealNtOpenProcess-5;
// 定义一下NtOpenProcess的原型
extern "C" typedef NTSTATUS __stdcall NTOPENPROCESS
(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
);
NTOPENPROCESS * RealNtOpenProcess;
PEPROCESS EP;
// 自定义的NtOpenProcess函数 ZwOpenProcess
#pragma PAGECODE
NTSTATUS __declspec(naked) __stdcall MyNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId )
{
NTSTATUS rc;
HANDLE PID;
KdPrint(("++++++++++++Entry MyNtOpenProcess int ++++++++++++++\n"));
//rc = (NTSTATUS)RealNtOpenProcess( ProcessHandle, DesiredAccess, ObjectAttributes, ClientId );
if( (ClientId != NULL) )
{
PID = ClientId->UniqueProcess;
KdPrint(( "------------------------- PID=%d--------------\n",(int*)PID ));
// 如果是被保护的PID,则拒绝访问,并将句柄设置为空
if(PID == MyPID)
{
KdPrint(("被保护进程 MyPID=%d \n",(int)MyPID));
//调试输出 类似C语言的 Printf
ProcessHandle = NULL; //这个是关键
rc = STATUS_ACCESS_DENIED; //这个返回值
//PsLookupProcessByProcessId((ULONG)PID,&EP);
EP=PsGetCurrentProcess();
KdPrint((" ACESS Process Name --:%s-- \n",(PTSTR)((ULONG)EP+0x174)));
__asm
{ // int 3
// add esp,10 //弹出4个参数
retn 0x10
}
}
}
__asm
{ // int 3
// add esp,10 //弹出4个参数
push 0x0C4
mov eax,RealNtOpenProcess
add eax,5
jmp eax
}
// return rc;
}
SSDT_Adr=(PLONG)*SSDT_Adr;// 0xE9 HOOK跳
ULONG jmpaddr= (ULONG)MyNtOpenProcess- (ULONG)RealNtOpenProcess-5; //SSDT HOOK
__asm
{ mov ebx,SSDT_Adr
mov eax,jmpaddr
mov BYTE ptr ds:[ebx],0xe9
mov DWORD ptr ds:[ebx+1],eax
int 3
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
========================================================
笔记:
以32课为例今天写一个内联HOOK,打开虚拟机,在WINDBG里看一下u nt!NtOpenProcess函数,因为JMP需要5字节,看一下函数的前三句都适合,所以取第一句最省事.用SSDT找到找到OP函数的地址,804e5a88,再看一下地址里的内容,就是NtOP函数的地址8058270a
找到地址之后先写入5个字节跳到我们自己的地址,然后判断是否被保护的进程,如果是的话就返回空,如果不是则跳回原有函数+5的地址,也就是原有函数的第二句,当然还要写好原有的第一句push 0c4h
在虚拟机里进行测试,输入被保护的PID后就被INT 3断点断下来了,原有函数已经被HOOK了,看一下我们自己的函数u f775b000 1 30 前30行代码,将之前的INT 3断点去掉eb f775b074 90
但是这样虚拟机太卡了,再编译成FREE版,再次保护一下记事本的PID,然后用CE打开一下提示错误,这样就在驱动层保护了我们的进程. |