/////
定义全局变量
///////
BYTE *NtOpenProcessAddress=NULL;
BYTE *ObOpenObjectByPointerAddress=NULL;
BYTE *returnAddress=NULL;
BYTE *NtOpenProcess_TP_HOOK=NULL;
ANSI_STRING p_str1,p_str2;
//
保存进程名称
PEPROCESS processEPROCESS = NULL;
//
保存访问者的EPROCESS
//
自定义的NtOpenProcess函数 ZwOpenProcess
extern
"C"
NTSTATUS __declspec(naked) __stdcall MyNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId )
{
processEPROCESS=IoGetCurrentProcess();
RtlInitAnsiString(&p_str1,(PCSZ)((ULONG)processEPROCESS+0x174));
//
将我们要比对的进程名放入str2
RtlInitAnsiString(&p_str2,DNF_EXE);
if
(RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
{
__asm
{
push dword ptr [ebp-38h]
push dword ptr [ebp-24h]
call NtOpenProcess_TP_HOOK
mov edx,returnAddress
jmp edx
}
}
if
(RtlCompareString(&p_str1,&p_str2,TRUE) != 0)
{
_asm
{
push dword ptr [ebp-38h]
push dword ptr [ebp-24h]
call ObOpenObjectByPointerAddress
mov edx,returnAddress
jmp edx
}
}
__asm
{
retn
}
}
//HOOK
函数构建
VOID Hook()
{
BYTE *p = NULL;
//
临时
KdPrint((
"驱动成功被加载中.............................\n"
));
//
获取NtOpenProcess的地址
NtOpenProcessAddress = (BYTE*)MyGetFunAddress(L
"NtOpenProcess"
);
//
获取ObOpenObjectByPointer的地址
ObOpenObjectByPointerAddress = (BYTE*)MyGetFunAddress(L
"ObOpenObjectByPointer"
);
//
将p指向NtOpenProcess函数开始处
p = NtOpenProcessAddress;
//
用一个无限循环来判断给定的特征码来确定被HOOK位置
while
(1)
{
if
((*(p-7) == 0x50) &&
(*(p-0xE) == 0x56) &&
(*(p+0xd) == 0x50) &&
(*(p+0x16) == 0x3b) &&
(*(p+0x17) == 0xce) &&
(*p == 0xE8) &&
(*(p+5) == 0x8b) &&
(*(p+6) == 0xf8))
{
KdPrint((
"%0X \n"
,(ULONG)p));
break
;
}
//
推动指针向前走
p++;
}
///
把RETURN的地址放进变量里
returnAddress=p+5;
NtOpenProcess_TP_HOOK=(BYTE*)(p+5+*(ULONG*)(p+1));
KdPrint((
" p的地址=%x\n"
,p));
KdPrint((
"MYHOOK的地址也就是 p-6的地址=%x\n"
,p-6));
__asm
//
去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h
//and
eax,0FFFEFFFFh
mov cr0,eax
}
ULONG jmpaddr=(ULONG)MyNtOpenProcess-(ULONG)(p-6)-5;
BYTE *pjian6=p-6;
//
in
line hook
__asm
{
mov ebx,pjian6
mov byte ptr ds:[ebx],0xe9
mov eax,jmpaddr
mov DWORD ptr ds:[ebx+1],eax
mov byte ptr ds:[ebx+6],0x90
}
__asm
{
//nt
3
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
return
;
}
///////
变量定义
////////
BYTE *NtOpenThreadAddress=NULL;
BYTE *NtOpenThreadreturn=NULL;
BYTE *NtOpenThread_TP_HOOK=NULL;
//////////////////////////MyNtOpenThread
////////////////////////////////////////////////
extern
"C"
static NTSTATUS __declspec(naked) __stdcall MyNtOpenThread()
{
//
获得调用者的EPROCESS
processEPROCESS = IoGetCurrentProcess();
//
将调用者的进程名保存到str1中
RtlInitAnsiString(&p_str1,(PCSZ)((ULONG)processEPROCESS+0x174));
//
将我们要比对的进程名放入str2
RtlInitAnsiString(&p_str2,DNF_EXE);
if
(RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
{
KdPrint((
"DNF访问了NtOpenThreadHook"
));
__asm
{
push dword ptr [ebp-34h]
push dword ptr [ebp-20h]
call NtOpenThread_TP_HOOK
mov edx,NtOpenThreadreturn
jmp edx
}
}
if
(RtlCompareString(&p_str1,&p_str2,TRUE) != 0)
{
KdPrint((
"NtOpenThreadreturn==%x"
,NtOpenThreadreturn));
KdPrint((
"NtOpenThreadAddress==%x"
,NtOpenThreadAddress));
__asm
{
push dword ptr [ebp-34h]
push dword ptr [ebp-20h]
call NtOpenThreadAddress
mov edx,NtOpenThreadreturn
jmp edx
}
}
__asm
{
retn
}
}
//////NtOpenThread
的 Hook
VOID NtOpenThreadHook()
{
BYTE *p = NULL;
//
临时
KdPrint((
"NtOpenThreadHook被加载中.............................\n"
));
////
获取NtOpenThreadAddress地址
NtOpenThreadAddress=(BYTE*)MyGetFunAddress(L
"NtOpenThread"
);
//
获取ObOpenObjectByPointer的地址
ObOpenObjectByPointerAddress = (BYTE*)MyGetFunAddress(L
"ObOpenObjectByPointer"
);
//
将p指向NtOpenThreadAddress函数开始处
p = NtOpenThreadAddress;
//
用一个无限循环来判断给定的特征码来确定被HOOK位置
while
(1)
{
if
((*(p-1) == 0xE0) &&
(*(p-2) == 0x75) &&
(*(p-3) == 0xFF) &&
(*(p-4) == 0xCC) &&
(*(p-5) == 0x75) &&
(*p == 0xE8) &&
(*(p+5) == 0x8b) &&
(*(p+6) == 0xf8)&&
(*(p+7) == 0x8D))
{
KdPrint((
"%0X \n"
,(ULONG)p));
break
;
}
//
推动指针向前走
p++;
}
///
把RETURN的地址放进变量里
NtOpenThreadreturn=p+5;
NtOpenThread_TP_HOOK= (BYTE*)(p+5+*(ULONG*)(p+1));
KdPrint((
" NtOpenThread_TP_HOOK=%x\n"
,NtOpenThread_TP_HOOK));
KdPrint((
" NtOpenThreadHook的地址=%x\n"
,p));
KdPrint((
"MYHOOK的地址也就是 p-6的地址=%x\n"
,p-6));
__asm
//
去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h
//and
eax,0FFFEFFFFh
mov cr0,eax
}
ULONG jmpaddr=(ULONG)MyNtOpenThread-(ULONG)(p-6)-5;
BYTE *pjian6=p-6;
//
in
line hook
__asm
{
mov ebx,pjian6
mov byte ptr ds:[ebx],0xe9
mov eax,jmpaddr
mov DWORD ptr ds:[ebx+1],eax
mov byte ptr ds:[ebx+6],0x90
}
__asm
{
//nt
3
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
return
;
}
BYTE *KeAttachProcessAddress = NULL;
//KeAttachProcess
函数地址
BYTE *KiAttachProcessAddress=NULL;
BYTE *p;
BYTE MovEaxAddress[5] = {0xB8,0,0,0,0};
//
BYTE JmpEax[2] = {0xff,0xe0};
//
特征码
BYTE Signature1 = 0x56,
//p-1
Signature2 = 0x57,
//p-2
Signature3 = 0x5F,
//p-3
Signature4 = 0x5E,
//p
+5
Signature5 = 0xE8;
//p
第一个字节
BYTE* TP_HOOK_KI;
extern
"C"
NTSTATUS __declspec(naked) __stdcall MyKiAttachProcess()
{
processEPROCESS=IoGetCurrentProcess();
RtlInitAnsiString(&p_str1,(PCSZ)((ULONG)processEPROCESS+0x174));
//
将我们要比对的进程名放入str2
RtlInitAnsiString(&p_str2,DNF_EXE);
/*
if
(RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
{
KdPrint((
"dnf 访问了HOOK_MyKiAttachProcess"
));
__asm
{
mov eax,TP_HOOK_KI
jmp eax
}
}
else
{*/
__asm
{
mov edi,edi
push ebp
mov ebp,esp
push ebx
push esi
mov eax,KiAttachProcessAddress
//
注意这个是全局变量 BYTE*
add eax,7
jmp eax
}
__asm
{
retn
}
//
}
}
BYTE _bp1[]={0x8B,0xFF,0x55,0x8B,0xEC,0x53,0x56};
VOID HOOK_MyKiAttachProcess()
{
//
获得KeAttachProcess地址,然后通过特征码找到
//KiAttachProcess
的地址
KeAttachProcessAddress = (BYTE*)MyGetFunAddress(L
"KeAttachProcess"
);
TP_HOOK_KI=(BYTE*)get_TP_kiprceoss_eaxaddrass();
//
将p指向KeAttachProcess函数开始处
p = KeAttachProcessAddress;
while
(1)
{
if
((*(p-1) == Signature1) &&
(*(p-2) == Signature2) &&
(*(p+5) == Signature3) &&
(*(p+6) == Signature4) &&
(*p == Signature5))
{
//
定位成功后取地址
KiAttachProcessAddress = (BYTE *)*(PULONG)(p+1)+(ULONG)(p+5);
KdPrint((
"KiAttachProcessAddress==%x"
,KiAttachProcessAddress));
break
;
}
//
推动指针
p++;
}
//
BYTE* NtKiAttachProcess_TP_HOOK= (BYTE*)(p+5+*(ULONG*)(p+1));
//
计算中继函数地址
*(ULONG *)(MovEaxAddress+1)=(ULONG)MyKiAttachProcess;
__asm
//
去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h
//and
eax,0FFFEFFFFh
mov cr0,eax
}
//
写入
RtlCopyMemory(KiAttachProcessAddress,MovEaxAddress,5);
RtlCopyMemory(KiAttachProcessAddress+5,JmpEax,2);
//RtlCopyMemory
(KiAttachProcessAddress,_bp1,7);
//
恢复Irql
__asm
{
//nt
3
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
}
//
名称: myGetCurrentAddress
//
功能: 获取SSDT表中指定函数的当前地址
//
参数: index:指定函数在表中的索引号
//
返回: 地址
//////////////////////////////////////////////////////////////////////
ULONG myGetCurrentAddress(IN ULONG index)
{
ULONG SSDT_Cur_Addr;
__asm
{
push ebx
push eax
mov ebx,KeServiceDescriptorTable
mov ebx,[ebx]
mov eax,index
shl eax,2
add ebx,eax
mov ebx,[ebx]
mov SSDT_Cur_Addr,ebx
pop eax
pop ebx
}
return
SSDT_Cur_Addr;
}
BYTE *NtMy_RecoveryHook_NtReadAndWriteMemoryreturn=NULL;
BYTE *NtReadVirtualMemoryAddress = NULL;
//NtReadVirtualMemory
的地址
BYTE *NtWriteVirtualMemoryAddress = NULL;
//NtWriteVirtualMemory
的地址
BYTE *NtMy_RecoveryHook_NtReadAndWrite=NULL;
extern
"C"
NTSTATUS __declspec(naked) __stdcall My_RecoveryHook_NtReadAndWriteMemory()
{
__asm
{
push 0x1c
push 0x804DAEE8
mov edx,NtMy_RecoveryHook_NtReadAndWriteMemoryreturn
jmp edx
}
}
extern
"C"
NTSTATUS __declspec(naked) __stdcall My_RecoveryHook_NtReadAndWrite()
{
processEPROCESS=IoGetCurrentProcess();
RtlInitAnsiString(&p_str1,(PCSZ)((ULONG)processEPROCESS+0x174));
//
将我们要比对的进程名放入str2
RtlInitAnsiString(&p_str2,DNF_EXE);
if
(RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
{
KdPrint((
"dnf 访问了HOOK_My_RecoveryHook_NtReadAndWriteMemory"
));
}
__asm
{
push 0x1c
push 0x804DAEE8
mov edx,NtMy_RecoveryHook_NtReadAndWrite
jmp edx
}
}
VOID HOOK_My_RecoveryHook_NtReadAndWriteMemory()
{
//
从SSDT表中获取NtReadVirtualMemory函数地址
NtReadVirtualMemoryAddress = (BYTE*)myGetCurrentAddress(0xBA);
//
从SSDT表中获取NtWriteVirtualMemory函数地址
NtWriteVirtualMemoryAddress = (BYTE*)myGetCurrentAddress(0x115);
//
写入
ULONG jmpaddr=(ULONG)My_RecoveryHook_NtReadAndWriteMemory-(ULONG)(NtReadVirtualMemoryAddress)-5;
ULONG jmpaddr1=(ULONG)My_RecoveryHook_NtReadAndWrite-(ULONG)(NtWriteVirtualMemoryAddress)-5;
BYTE *pNtReadVirtualMemoryAddress=NtReadVirtualMemoryAddress;
BYTE *pNtWriteVirtualMemoryAddress=NtWriteVirtualMemoryAddress;
__asm
//
去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h
//and
eax,0FFFEFFFFh
mov cr0,eax
}
NtMy_RecoveryHook_NtReadAndWriteMemoryreturn=NtReadVirtualMemoryAddress+7;
//
in
line hook
__asm
{
mov ebx,pNtReadVirtualMemoryAddress
mov byte ptr ds:[ebx],0xe9
mov eax,jmpaddr
mov DWORD ptr ds:[ebx+1],eax
}
NtMy_RecoveryHook_NtReadAndWrite=NtWriteVirtualMemoryAddress+7;
__asm
{
mov ebx,pNtWriteVirtualMemoryAddress
mov byte ptr ds:[ebx],0xe9
mov eax,jmpaddr1
mov DWORD ptr ds:[ebx+1],eax
}
__asm
//
回复保护
{
//nt
3
mov eax, cr0
or eax, 10000h
mov cr0, eax
sti
}
}