首页
社区
课程
招聘
[旧帖] [求助]TP的四个HOOK都过了 OD提示无法附加游戏 0.00雪花
发表于: 2012-4-2 04:12 3780

[旧帖] [求助]TP的四个HOOK都过了 OD提示无法附加游戏 0.00雪花

2012-4-2 04:12
3780
在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直播授课

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 238
活跃值: (55)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
2
楼主头像挺好看
2012-4-2 08:46
0
雪    币: 32
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
同问
我也是过掉了
NtOpenThread    //防止调试器在它体内创建线程
NtOpenProcess   //防止OD等在进程列表看到它
KiAttachProcess   //防止其他软件附加它
NtReadVirtualMemory  //防止别人读取它的内存
NtWriteVirtualMemory  //防止别人在它的内存里面乱写乱画
怎么还是没有附加
2012-5-26 15:00
0
雪    币: 46
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
应该是我们的技术理论和技巧学的不好吧 这样的学习何时才能符合工程师的标准
同求
2013-2-23 13:44
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
各种清零之类的
2013-2-24 21:38
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
6
清零没搞。~~~
2013-2-25 16:01
0
雪    币: 64
活跃值: (60)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
清零没过会附加失败?楼上的写过驱动没?
2013-2-25 16:46
0
雪    币: 64
活跃值: (60)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
明显是DNF4月份更新了,添加了几个新的钩子。
现在这几个钩子又没有了,驱动相对来说容易过了。
Ring3加入了动态代码校验,使得Win7 64位OD附加后网络连接中断。
2013-2-25 16:49
0
雪    币: 64
活跃值: (60)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
明显是DNF4月份更新了,添加了几个新的钩子。
现在这几个钩子又没有了,驱动相对来说容易过了。
Ring3加入了动态代码校验,使得Win7 64位OD附加后网络连接中断。
2013-2-25 16:49
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
这才3月15啊。楼上的都穿越了。
2013-3-13 22:45
0
游客
登录 | 注册 方可回帖
返回
//