在3月20号的时候还能 正常附加 游戏更新后 提示无法附加游戏 是不是游戏有新的HOOK? 希望各位大大能说下新加了什么HOOK 我找了几天都找不到 最后才无奈来发帖求助
下面是我的源码
/////定义全局变量///////
BYTE *NtOpenProcessAddress=NULL;
BYTE *ObOpenObjectByPointerAddress=NULL;
BYTE *returnAddress=NULL;
BYTE *NtOpenProcess_TP_HOOK=NULL;
ANSI_STRING p_str1,p_str2; //保存进程名称
#define DNF_EXE "DNF.exe" //要检索的进程名
PEPROCESS processEPROCESS = NULL; //保存访问者的EPROCESS
// 自定义的NtOpenProcess函数 ZwOpenProcess
#pragma PAGECODE
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 函数构建
#pragma PAGECODE
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 ////////////////////////////////////////////////
#pragma PAGECODE
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
}
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课