能力值:
( 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
}
|
能力值:
( LV6,RANK:90 )
|
-
-
4 楼
2楼的强悍阿~!
早点发到论坛 说不定能拿个精 哈
|