看流星社区

 找回密码
 注册账号
楼主: aja93

游戏保护方面的资料

[复制链接]
  • TA的每日心情
    开心
    2020-8-13 22:12
  • 发表于 2020-8-13 22:23:59 | 显示全部楼层
    游戏保护方面的资料

    该用户从未签到

    发表于 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; //保存进程名称


    //用SSDT  HOOK对抗TP保护的INLINE  HOOK
    //读内存
    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 [ebp-38h]
        push dword ptr [ebp-24h]
      }


      //获得访问者的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
          mov  edx,0x805CC621
          mov  edx,dword ptr [edx]
          add  edx,0x805CC625
          jmp  edx  //TP模块的函数,DNF程序不从这里过,就报非法模块
        }
      }
      else
      {
        //说明是其他进程访问了这里,直接调用ObOpenObjectByPointer,CE就可以附加了
        __asm
        {
          push 0x805CC625
          mov  edx,0x805BCC6C  //ObOpenObjectByPointer
          jmp  edx
        }
      }
    }


    static __declspec(naked) VOID MyFunctionT() //NtOpenThread调用ObOpenObjectByPointer的处理
    {
      __asm
      {
        push eax
        push dword ptr [ebp-34h]
        push dword ptr [ebp-20h]
      }
       
      //获得访问者的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
          mov  edx,0x805CC8A3
          mov  edx,dword ptr [edx]
          add  edx,0x805CC8A7
          jmp  edx  //TP模块的函数,DNF程序不从这里过,就报非法模块
        }
      }
      else
      {
        //说明是其他进程访问了这里,直接调用ObOpenObjectByPointer,但是OD附加就蓝屏
        __asm
        {
          push 0x805CC8A7
          mov  edx,0x805BCC6C //ObOpenObjectByPointer
          jmp  edx
        }
      }
    }


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


    #pragma PAGECODE
    VOID OpenMemoryProtect() //恢复页面保护
    {
      __asm
      {
        mov eax,cr0
        or  eax,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(("驱动已被卸载..."));
    }
  • TA的每日心情
    擦汗
    2021-8-20 11:42
  • 发表于 2021-5-29 15:38:53 | 显示全部楼层
    666666666666666

    该用户从未签到

    发表于 2021-8-1 14:38:00 | 显示全部楼层
    有视频教材吗?
    点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
    您需要登录后才可以回帖 登录 | 注册账号

    本版积分规则

    小黑屋|手机版|Archiver|看流星社区 |网站地图

    GMT+8, 2024-4-26 06:20

    Powered by Kanliuxing X3.4

    © 2010-2019 kanliuxing.com

    快速回复 返回顶部 返回列表