gengyiwei 发表于 2020-8-13 22:23:59

游戏保护方面的资料

weilisheng 发表于 2021-3-13 16:16:02

#include <ntddk.h>
#include <windef.h>


#define INITCODE code_seg("INIT") /*运行一次就释放内存*/
#define PAGECODE code_seg("PAGE") /*分页内存*/


VOID CloseMemoryProtect(); //关闭写保护
VOID OpenMemoryProtect(); //开启写保护
VOID MyDriver_Unload(PDRIVER_OBJECT pDriverObject); //卸载函数


#pragma pack(1) //一字节对齐
typedef struct JmpCode {
      BYTE bytecode; //0xBA , mov edx,MyFunctionAddress,自定义HOOK类型
      ULONG Address; //MyFunctionAddress
      USHORT JmpEdx; //D2FF ,jmp edx
} JmpCode, *PJmpCode;
#pragma pack()


typedef struct ServiceDescriptorEntry {
    unsigned int *ServiceTableBase;
    unsigned int *ServiceCounterTableBase;
    unsigned int NumberOfServices;
    unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
extern PServiceDescriptorTableEntry KeServiceDescriptorTable; //SSDT表,声明指针用extern


ULONG Readdizhi,Writedizhi,OldRead,OldWrite; //读,写
JmpCode CopyCode,CopyCodeT; //保存进程,线程被HOOK的代码,以便卸载时恢复
PJmpCode OldAddress,OldAddressT; //要HOOK的进程和线程地址
PEPROCESS processEPROCESS = NULL,TprocessEPROCESS = NULL; //保存访问者的EPROCESS
ANSI_STRING p_str1,p_str2,p_str3; //保存进程名称


//用SSDTHOOK对抗TP保护的INLINEHOOK
//读内存
static __declspec(naked) NTSTATUS __stdcall MyNtReadVirtualMemory(HANDLE ProcessHandle,
                                                         PVOID BaseAddress,
                                                         PVOID Buffer,
                                                         ULONG NumberOfBytesToRead,
                                                         PULONG NumberOfBytesReaded)
{
    //跳过去
    __asm
    {
      push    0x1C
      push    0x804DAEE8
      mov   edx,0x805B5291
      jmp   edx
    }
}


//写内存
static __declspec(naked) NTSTATUS __stdcall MyNtWriteVirtualMemory(HANDLE ProcessHandle,
                                                            PVOID BaseAddress,
                                                            PVOID Buffer,
                                                            ULONG NumberOfBytesToWrite,
                                                            PULONG NumberOfBytesReaded)
{
    //跳过去
    __asm
    {
      push    0x1C
      push    0x804DAF00
      mov   edx,0x805B539B
      jmp   edx
    }
}


static __declspec(naked) VOID MyFunction() //NtOpenProcess调用ObOpenObjectByPointer的处理
{
__asm
{
    push eax
    push dword ptr
    push dword ptr
}


//获得访问者的EPROCESS
processEPROCESS = IoGetCurrentProcess();


//将调用者的进程名保存到p_str2中
RtlInitAnsiString(&p_str2,(PCSZ)((ULONG)processEPROCESS+0x174));


if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)
{
    //说明是DNF进程访问了这里,让其调用TP模块的函数跟Ring3通信,不被报非法模块
    __asm
    {
      push 0x805CC625
      movedx,0x805CC621
      movedx,dword ptr
      addedx,0x805CC625
      jmpedx//TP模块的函数,DNF程序不从这里过,就报非法模块
    }
}
else
{
    //说明是其他进程访问了这里,直接调用ObOpenObjectByPointer,CE就可以附加了
    __asm
    {
      push 0x805CC625
      movedx,0x805BCC6C//ObOpenObjectByPointer
      jmpedx
    }
}
}


static __declspec(naked) VOID MyFunctionT() //NtOpenThread调用ObOpenObjectByPointer的处理
{
__asm
{
    push eax
    push dword ptr
    push dword ptr
}
   
//获得访问者的EPROCESS
TprocessEPROCESS = IoGetCurrentProcess();
   
//将调用者的进程名保存到p_str3中
RtlInitAnsiString(&p_str3,(PCSZ)((ULONG)TprocessEPROCESS+0x174));


if (RtlCompareString(&p_str1,&p_str3,TRUE) == 0)
{
    //说明是DNF进程访问了这里,让其调用TP模块的函数跟Ring3通信,不被报非法模块
    __asm
    {
      push 0x805CC8A7
      movedx,0x805CC8A3
      movedx,dword ptr
      addedx,0x805CC8A7
      jmpedx//TP模块的函数,DNF程序不从这里过,就报非法模块
    }
}
else
{
    //说明是其他进程访问了这里,直接调用ObOpenObjectByPointer,但是OD附加就蓝屏
    __asm
    {
      push 0x805CC8A7
      movedx,0x805BCC6C //ObOpenObjectByPointer
      jmpedx
    }
}
}


#pragma PAGECODE
VOID CloseMemoryProtect() //去掉页面保护
{
__asm
{
    cli
    mov eax,cr0
    and eax,not 10000h
    mov cr0,eax
}
}


#pragma PAGECODE
VOID OpenMemoryProtect() //恢复页面保护
{
__asm
{
    mov eax,cr0
    oreax,10000h
    mov cr0,eax
    sti
}
}


#pragma INITCODE
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING pRegistryPath)
{
ULONG jizhi;


//初始化驱动卸载函数
pDriverObject->DriverUnload = MyDriver_Unload;


jizhi = (ULONG)KeServiceDescriptorTable->ServiceTableBase; //获取SSDT表基址

Readdizhi = jizhi+186*4; //获取NtReadVirtualMemory
OldRead = *(PULONG)Readdizhi; //保存NtReadVirtualMemory原始地址
KdPrint(("Readdizhi地址为 %x",Readdizhi));

Writedizhi = jizhi+277*4; //获取NtWriteVirtualMemory
OldWrite = *(PULONG)Writedizhi; //保存NtWriteVirtualMemory原始地址
KdPrint(("Writedizhi地址为 %x",Writedizhi));


//保存原始代码,NtOpenProcess调用ObOpenObjectByPointer之前的7个字节
OldAddress = (PJmpCode)0x805CC619;
CopyCode.bytecode = OldAddress->bytecode;
CopyCode.Address = OldAddress->Address;
CopyCode.JmpEdx = OldAddress->JmpEdx;


//保存原始代码,NtOpenThread调用ObOpenObjectByPointer之前的7个字节
OldAddressT = (PJmpCode)0x805CC89B;
CopyCodeT.bytecode = OldAddressT->bytecode;
CopyCodeT.Address = OldAddressT->Address;
CopyCodeT.JmpEdx = OldAddressT->JmpEdx;


//将DNF.exe进程名放入p_str1中,以便判断
RtlInitAnsiString(&p_str1,"DNF.exe");


CloseMemoryProtect(); //去掉页面保护


//HOOK绕过TP保护读内存,写内存
*(PULONG)Readdizhi = (ULONG)MyNtReadVirtualMemory;
*(PULONG)Writedizhi = (ULONG)MyNtWriteVirtualMemory;


//HOOK绕过NtOpenProcess调用ObOpenObjectByPointer
OldAddress->bytecode = 0xBA;
OldAddress->Address = (ULONG)MyFunction;
OldAddress->JmpEdx = 0xE2FF;


//HOOK绕过NtOpenThread调用ObOpenObjectByPointer
OldAddressT->bytecode = 0xBA;
OldAddressT->Address = (ULONG)MyFunctionT;
OldAddressT->JmpEdx = 0xE2FF;


OpenMemoryProtect(); //恢复页面保护


KdPrint(("MyFunction地址为 %x",(ULONG)MyFunction));
KdPrint(("MyFunctionT地址为 %x",(ULONG)MyFunctionT));


KdPrint(("驱动加载成功..."));


return STATUS_SUCCESS;
}


#pragma PAGECODE
VOID MyDriver_Unload(PDRIVER_OBJECT pDriverObject)
{
CloseMemoryProtect(); //去掉页面保护


//代码恢复,读内存,写内存
*(PULONG)Readdizhi = OldRead;
*(PULONG)Writedizhi = OldWrite;


//代码恢复
OldAddress->bytecode = CopyCode.bytecode;
OldAddress->Address = CopyCode.Address;
OldAddress->JmpEdx = CopyCode.JmpEdx;
//代码恢复
OldAddressT->bytecode = CopyCodeT.bytecode;
OldAddressT->Address = CopyCodeT.Address;
OldAddressT->JmpEdx = CopyCodeT.JmpEdx;


OpenMemoryProtect(); //恢复页面保护


KdPrint(("驱动已被卸载..."));
}

hukai 发表于 2021-5-29 15:38:53

666666666666666

fengjiangli 发表于 2021-8-1 14:38:00

有视频教材吗?
页: 1 2 3 4 5 6 7 8 [9]
查看完整版本: 游戏保护方面的资料