首页
社区
课程
招聘
怎么过TP驱动
发表于: 2011-2-23 09:29 11793

怎么过TP驱动

2011-2-23 09:29
11793
收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 195
活跃值: (29)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
过NtopenProcess
过Ntopenthread
过KiAttachProcess
过读写二函数

恢复以上2个INLINE HOOK

炸了DEBUGPORT清零二处,一处检测

恢复硬件下段

OK。附上代码

恢复代码如下,其余部分不公布
/************************************************************************
* 文件名称:Driver.h                                                 
* 作    者:桂哥
* 完成日期:2010-2-22
*************************************************************************/
#pragma once

#ifdef __cplusplus
extern "C"
{
#endif
#include <NTDDK.h>
#ifdef __cplusplus
}
#endif 
#include <ntdef.h>
#include <windef.h>
#include <ntstatus.h>
#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#define PAGEDDATA data_seg("PAGE")
#define LOCKEDDATA data_seg()
#define INITDATA data_seg("INIT")

#define arraysize(p) (sizeof(p)/sizeof((p)[0]))
#define FAILED_TO_OBTAIN_FUNCTION_ADDRESSES 0x1;
PEPROCESS processEPROCESS = NULL;//保存访问者的EPROCESS
PEPROCESS processEPROCESS1 = NULL;//保存访问者的EPROCESS
ANSI_STRING p_str1,p_str2,p_str3,p_str4;//保存进程名称
BYTE *ObOpenObjectByPointerAddress=NULL;//ObOpenObjectByPointer的地址
BYTE *ObOpenObjectByPointerAddress1=NULL;
BYTE *p_TpHookAddress=NULL;//Tp的HOOK函数地址
BYTE *p_ReturnAddress=NULL;//返回到的地址
BYTE *p_MyHookAddress=NULL;//自己的HOOK函数地址
BYTE *p_MyHookAddress1=NULL;//OpenThread自己的HOOK函数地址
BYTE *p_TpHookAddress1=NULL;//Tp的HOOK函数地址
BYTE *p_TpHookAddress3=NULL;//KiAttachProcess的地址
BYTE *p_ReturnAddress1=NULL;
#define DNF_EXE "DNF.exe" //DNF进程名 
#pragma pack(1)
typedef struct _TOP5CODE       //前5字节自定义数据类型
{
	UCHAR  instruction;  //指令
	ULONG  address;    //地址
}TOP5CODE,*PTOP5CODE;
#pragma pack()
BYTE OldPOpen[6]={0,0,0,0,0,0};

VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject);
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp);
typedef struct _ServiceDescriptorTable {
	PVOID ServiceTableBase; //System Service Dispatch Table 的基地址  
	PVOID ServiceCounterTable;//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
	unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
	PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
}*PServiceDescriptorTable;  
//由SSDT索引号获取当前函数地址  
//NtOpenProcess  [[KeServiceDescriptorTable]+0x7A*4]  
extern "C" PServiceDescriptorTable KeServiceDescriptorTable; 

PVOID MyGetFunAddress(IN PCWSTR FunctionName)
{
	UNICODE_STRING Old_NtAddr;
	RtlInitUnicodeString(&Old_NtAddr,FunctionName);
	return MmGetSystemRoutineAddress(&Old_NtAddr);
}

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;
}
VOID WPOFF()
{
	__asm //去掉页面保护
	{
		cli
			mov eax,cr0
			and eax,not 10000h //and eax,0FFFEFFFFh
			mov cr0,eax

	}
}

VOID WPON()
{
	__asm
	{
		mov eax,cr0
			or eax,10000h //or eax,not 0FFFEFFFFh
			mov cr0,eax
			sti
	}
}

VOID _declspec(naked) MyNtOpenProcess()
{

	processEPROCESS=IoGetCurrentProcess();//获得调用者的EPROCESS
	RtlInitAnsiString(&p_str1,(PCSZ)processEPROCESS+0x174);//将调用者的进程名保存到str1里
	RtlInitAnsiString(&p_str2,DNF_EXE);//将DNF进程名保存到str2里
	if(RtlCompareString(&p_str1,&p_str2,true)==0)
	{
		__asm
		{			
			push dword ptr [ebp-38h]
			push dword ptr [ebp-24h]
			push p_ReturnAddress
				mov  eax,p_TpHookAddress
				jmp  eax

		}
	}
	else
	{
		__asm
		{

			push dword ptr [ebp-38h]
			push dword ptr [ebp-24h]
			push p_ReturnAddress
				mov  eax,ObOpenObjectByPointerAddress
				jmp  eax


		}
	}

}
NTSTATUS My_RecoverHook_NtOpenProcess()
{

	BYTE *NtOpenProcessAddress=NULL;//NtOpenProcess地址
	BYTE JmpAddress[6]={0xE9,0,0,0,0,0x90};
	BYTE *p=NULL;
	TOP5CODE  *top5code = NULL;
	KIRQL Irql;

	NtOpenProcessAddress=(BYTE*)MyGetFunAddress(L"NtOpenProcess");	
	if (NtOpenProcessAddress==NULL)
	{
		KdPrint(("NtOpenProcess获取失败!\n"));
		return 0;
	}

	ObOpenObjectByPointerAddress=(BYTE*)MyGetFunAddress(L"ObOpenObjectByPointer");
	if (ObOpenObjectByPointerAddress==NULL)
	{
		KdPrint(("ObOpenObjectByPointer获取失败!\n"));
		return 0;
	}

	p = NtOpenProcessAddress;
	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(("P指针指向的地址%0X \n",(ULONG)p));
			break;
		}
		p++;
	}
	top5code = (TOP5CODE*)p;
	//被TX HOOK的地址,也就是call 后面的地址
	p_TpHookAddress = (BYTE*)((ULONG)p+5+top5code->address);
	p_MyHookAddress = p-6;
	p_ReturnAddress = p+5;
	*(ULONG *)(JmpAddress+1)=(ULONG)MyNtOpenProcess-((ULONG)p_MyHookAddress+5);
    
	KdPrint(("Myhook地址=%0X \n",p_MyHookAddress));
	KdPrint(("TPhook地址=%0X \n",p_TpHookAddress));
	KdPrint(("返回地址=%0X \n",p_ReturnAddress));


	WPOFF();
	Irql=KeRaiseIrqlToDpcLevel();
	RtlCopyMemory((BYTE*)OldPOpen,(BYTE*)p_MyHookAddress,6);
    RtlCopyMemory(p_MyHookAddress,JmpAddress,6);
	KeLowerIrql(Irql);
	WPON();



	return STATUS_SUCCESS;
}

VOID recodeOpenProcess()
{
	KIRQL    Irql;
	WPOFF();  //清除CR0
	//提升IRQL中断级
	Irql=KeRaiseIrqlToDpcLevel();
	//写入
	if(OldPOpen[0]!=0)
	{
		RtlCopyMemory(p_MyHookAddress,OldPOpen,6);
	}
	//恢复Irql
	KeLowerIrql(Irql);
	WPON();    //恢复CR0
}

NTSTATUS My_RecoveryHook_ReadandWrite()
{
	BYTE  *NtReadVirtualMemoryAddress    = NULL;
	BYTE  *NtWriteVirtualMemoryAddress  = NULL;
	KIRQL  Irql;
	BYTE Read_data1[2]={0x6A,0x1C};						//机器硬编码
	BYTE Read_data2[5]={0x68,0xF0,0xAE,0x4D,0x80};		//机器硬编码
	BYTE Read_data3[5]={0x68,0x08,0xAF,0x4D,0x80};		//机器硬编码 
	//从SSDT表中获取NtReadVirtualMemory函数地址
	NtReadVirtualMemoryAddress = (BYTE*)MyGetCurrentAddress(0xBA);
	if (NtReadVirtualMemoryAddress == NULL)
	{
		KdPrint(("NtReadVirtualMemory函数地址获取失败! \n"));
		return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
	}
	//从SSDT表中获取NtWriteVirtualMemory函数地址
	NtWriteVirtualMemoryAddress = (BYTE*)MyGetCurrentAddress(0x115);
	if (NtWriteVirtualMemoryAddress == NULL)
	{
		KdPrint(("NtWriteVirtualMemory函数地址获取失败! \n"));
		return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
	}
	WPOFF();  //清除CR0
	//提升IRQL中断级
	Irql=KeRaiseIrqlToDpcLevel();
	//写入
	RtlCopyMemory(NtReadVirtualMemoryAddress,Read_data1,2);
	RtlCopyMemory(NtReadVirtualMemoryAddress+2,Read_data2,5);
	RtlCopyMemory(NtWriteVirtualMemoryAddress,Read_data1,2);
	RtlCopyMemory(NtWriteVirtualMemoryAddress+2,Read_data3,5);
	//恢复Irql
	KeLowerIrql(Irql);
	WPON();    //恢复CR0
	return  STATUS_SUCCESS;
}

//////////////////////////////////////////////////////////////////////
//  名称:  RecoveryHook_KiAttachProcess
//  功能:  解除游戏保护对_KiAttachProcess函数的HOOK(DNF)
//  参数:  
//  返回:  状态
//////////////////////////////////////////////////////////////////////
NTSTATUS My_RecoveryHook_KiAttachProcess()
{
	BYTE	data[7]={0x8B,0xFF,0x55,0x8B,0xEC,0x53,0x56};
	BYTE    *KeAttachProcessAddress = NULL;  //KeAttachProcess函数地址
	BYTE    *p;
	KIRQL    Irql;
	TOP5CODE  *top5code = NULL;  //保存5字节内容

	//获得KeAttachProcess地址,然后通过特征码找到
	//KiAttachProcess的地址
	KeAttachProcessAddress = (BYTE*)MyGetFunAddress(L"KeAttachProcess");
	if (KeAttachProcessAddress == NULL)
	{
		KdPrint(("KeAttachProcess地址获取失败\n"));
		return  FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
	}
	//将p指向KeAttachProcess函数开始处
	p = KeAttachProcessAddress;
	while (1)
	{
		if ((*(p-1) == 0x56) &&
			(*(p-2) == 0x57) &&
			(*(p+5) == 0x5F) &&
			(*(p+6) == 0x5E) &&
			(*p     == 0xE8))
		{
			//定位成功后取地址
			//KiAttachProcessAddress = (BYTE*)((PULONG)(p+1))+((ULONG)(p+5));
			break;
		}

		//推动指针
		p++;
	}
	top5code = (TOP5CODE*)p;
	p_TpHookAddress3 = (BYTE*)((ULONG)p+5+top5code->address);
	KdPrint(("%0X \n",p_TpHookAddress3));
	WPOFF();  //清除CR0
	//提升IRQL中断级
	Irql=KeRaiseIrqlToDpcLevel();
	//写入
	RtlCopyMemory(p_TpHookAddress3,data,7);
	//恢复Irql
	KeLowerIrql(Irql);
	WPON();    //恢复CR0

	return  STATUS_SUCCESS;
}
VOID _declspec(naked) MyNtOpenThread()
{



	/*processEPROCESS1=IoGetCurrentProcess();//获得调用者的EPROCESS
	RtlInitAnsiString(&p_str3,(PCSZ)processEPROCESS+0x174);//将调用者的进程名保存到str1里
	RtlInitAnsiString(&p_str4,DNF_EXE);//将DNF进程名保存到str2里
	if(RtlCompareString(&p_str3,&p_str4,true)==0)
	{
		
		__asm
		{			
			push dword ptr [ebp-34h]
			push dword ptr [ebp-20h]
			push p_ReturnAddress1
				mov  eax,p_TpHookAddress1
				jmp  eax

		}
	}
	else
	{*/
		__asm
		{

			push dword ptr [ebp-34h]
			push dword ptr [ebp-20h]
			push p_ReturnAddress1
			mov  eax,ObOpenObjectByPointerAddress1
			jmp  eax


		}
	//}

}
BYTE OldPOpen1[6]={0,0,0,0,0,0};
NTSTATUS My_RecoverHook_NtOpenThread()
{

	BYTE *NtOpenThreadAddress=NULL;//NtOpenThread地址
	BYTE JmpAddress[6]={0xE9,0,0,0,0,0x90};
	BYTE *p=NULL;
	TOP5CODE  *top5code = NULL;
	KIRQL Irql;

	NtOpenThreadAddress=(BYTE*)MyGetFunAddress(L"NtOpenThread");	
	if (NtOpenThreadAddress==NULL)
	{
		KdPrint(("NtOpenThread获取失败!\n"));
		return 0;
	}

	ObOpenObjectByPointerAddress1=(BYTE*)MyGetFunAddress(L"ObOpenObjectByPointer");
	if (ObOpenObjectByPointerAddress1==NULL)
	{
		KdPrint(("ObOpenObjectByPointer获取失败!\n"));
		return 0;
	}

	p = NtOpenThreadAddress;
	while (1)
	{
		if ((*(p-7)   == 0x50) && 
			(*(p-0xE)  == 0x56) &&
			(*(p-0xd)  == 0x8d) &&
			(*(p+7) == 0x8d) &&
			(*(p+8) == 0x85) &&
			(*p        == 0xE8) &&
			(*(p+5)    == 0x8b) &&
			(*(p+6)    == 0xf8))
		{
			break;
		}
		p++;
	}
	top5code = (TOP5CODE*)p;
	//被TX HOOK的地址,也就是call 后面的地址
	p_TpHookAddress1 = (BYTE*)((ULONG)p+5+top5code->address);
	p_MyHookAddress1 = p-6;
	p_ReturnAddress1 = p+5;
	*(ULONG *)(JmpAddress+1)=(ULONG)MyNtOpenThread-((ULONG)p_MyHookAddress1+5);

	KdPrint(("Myhook地址=%0X \n",p_MyHookAddress1));
	KdPrint(("TPhook地址=%0X \n",p_TpHookAddress1));
	KdPrint(("返回地址=%0X \n",p_ReturnAddress1));


	WPOFF();
	Irql=KeRaiseIrqlToDpcLevel();
	RtlCopyMemory((BYTE*)OldPOpen1,(BYTE*)p_MyHookAddress1,6);
	RtlCopyMemory(p_MyHookAddress1,JmpAddress,6);
	KeLowerIrql(Irql);
	WPON();



	return STATUS_SUCCESS;
}

VOID recodeOpenThread()
{
	KIRQL    Irql;
	WPOFF();  //清除CR0
	//提升IRQL中断级
	Irql=KeRaiseIrqlToDpcLevel();
	//写入
	if(OldPOpen1[0]!=0)
	{
		RtlCopyMemory(p_MyHookAddress1,OldPOpen1,6);
	}
	//恢复Irql
	KeLowerIrql(Irql);
	WPON();    //恢复CR0
}
2011-2-23 09:34
0
雪    币: 71
活跃值: (1414)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
原码都出来了~收藏
2011-2-23 09:58
0
雪    币: 346
活跃值: (129)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
2楼的强悍阿~!
  早点发到论坛 说不定能拿个精 哈
2011-3-14 10:52
0
雪    币: 66
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不懂,进来学习
2011-3-21 08:06
0
游客
登录 | 注册 方可回帖
返回
//