zoukankan      html  css  js  c++  java
  • 一个不错的过TP思路,转载CSDN

    也许大家也是研究腾讯游戏的爱好者,对腾讯的游戏都有过这样的体会  例如OD与CE无法进行如以下操作: 
    无法附加进程, 
    无法打开进程, 
    游戏进程被隐藏无法在工具中查看到,
    内存无法读取代码  
    内存修改后游戏掉线   
    无法双机进行调试  
    出现SX非法模块提示 `
    其实以上说的这么多限制 都是因为TP保护造成的.其实这些东西研究了很久后,发现其实就是黑色老大常说的APIHOOK这方面. 7%32E1F)%  
    例如DNF的TP保护就是HOOK了以下几个API函数来禁止上面刚才说的那些:  
    NtOpenThread    //这是TP防止调试器在它体内创建线程   
    NtOpenProcess   //这是TP防止OD等在进程列表看到游戏进程 
    KiAttachProcess   //这是TP防止其他软件附加它  
    NtReadVirtualMemory  //这是TP防止别人读取它的内存  
    NtWriteVirtualMemory  //这是TP防止别人在它的内存里面乱写乱画 
    KDCOM.dll:KdReceivePacket  //这是TP这两个是COM串口的接受和发送数据 
    KDCOM.dll:KdSendPacket      //这是TP主要用来方式别人双机调试,TP使用了KdDisableDebugger来禁用双机调试.  
    TP通过将以上这几个API进行HOOK后 来保护游戏, 看过独立团第四版本易语言辅助教程的人 应该知道 以上的那几个API函数 开头是 Nt 的吧 
    Nt开头的是ntdll.dll库中的函数,也正是黑色衬衣老大在第四版本易语言辅助教程中有一篇课程是讲 SSDTHOOK与恢复这方面的.  
    那么TP保护它比较变态,并对debugport进行了疯狂的清零操作甚至还包括EPROCESS+70+74+78等几处位置处理的手段通常都是向64端口写入FE导致计算机被重启。 
    下面我简单看说下以上关键的几个APIHOOK:
    1.KiAttachProcess 函数   
    2.NtReadVirtualMemory 内存函数 
    3.NtWriteVirtualMemory 内存函数
    4.NtOpenThread 线程函数   
    5.NtOpenProcess 进程函数   
    那么前3个函数是可以直接SSDT恢复的 第四版本易语言辅助教程老大讲了如何恢复的 不明白的可以自己去看教程。 
    第4个函数是有监视,如果直接恢复的话电脑会即刻重启.(TP蛮变态)  
    第5个函数和ring3有驱动通信,直接恢复这个函数的话  游戏会在1分钟内弹出SX非法模块提示. 
      
    既然我们现在知道了TP保护的保护特点和这几个API分析后的结果.   
    接下来就是要做出相应的解除TP保护(也就是这些APIHOOK) 
    下面我在梳理一下头绪给出相应的解决方案   
    1.首先直接恢复 第1、2、3处的SSDT表中的HOOK  
    2.绕过4、5处的HOOK 不采用直接恢复   
    3.将TP保护程序中的debugport清零的内核线程干掉 停止该线程继续运行.  
    4.恢复硬件断点  
    但是要有一个先后的逻辑顺序   
    因为内核有一个线程负责监视几个地方,必须要先干掉它。 
    但是这个内容我写在了处理debugport清零的一起,也就是第3步。所以大家在照搬源码的时候注意代码执行次序。
    下面我们就开始写解除TP保护的代码,因为本人喜欢C++ 所以是c++编写,如果是使用易语言的话 就自己翻译过来吧
    先从简单的工作讲起,恢复1、2、3处的HOOK 
    KiAttachProcess函数的处理的代码:

      1.  
        //////////////////////////////////////////////////////////////////////
      2.  
        // 名称: Nakd_KiAttachProcess
      3.  
        // 功能: My_RecoveryHook_KiAttachProcess的中继函数
      4.  
        // 参数:
      5.  
        // 返回:
      6.  
        //////////////////////////////////////////////////////////////////////
      7.  
        static NAKED VOID Nakd_KiAttachProcess()
      8.  
        {
      9.  
        __asm
      10.  
        {
      11.  
        mov edi,edi
      12.  
        push ebp
      13.  
        mov ebp,esp
      14.  
        push ebx
      15.  
        push esi
      16.  
        mov eax,KiAttachProcessAddress //注意这个是全局变量 BYTE*
      17.  
        add eax,7
      18.  
        jmp eax
      19.  
        }
      20.  
        }
      21.  
        //////////////////////////////////////////////////////////////////////
      22.  
        // 名称: RecoveryHook_KiAttachProcess
      23.  
        // 功能: 解除游戏保护对_KiAttachProcess函数的HOOK(DNF)
      24.  
        // 参数:
      25.  
        // 返回: 状态
      26.  
        //////////////////////////////////////////////////////////////////////
      27.  
        NTSTATUS My_RecoveryHook_KiAttachProcess()
      28.  
        {
      29.  
        BYTE *KeAttachProcessAddress = NULL; //KeAttachProcess函数地址
      30.  
        BYTE *p;
      31.  
        BYTE MovEaxAddress[5] = {0xB8,0,0,0,0}; //
      32.  
        BYTE JmpEax[2] = {0xff,0xe0};
      33.  
        KIRQL Irql;
      34.  
        //特征码
      35.  
        BYTE Signature1 = 0x56, //p-1
      36.  
        Signature2 = 0x57, //p-2
      37.  
        Signature3 = 0x5F, //p-3
      38.  
        Signature4 = 0x5E, //p+5
      39.  
        Signature5 = 0xE8; //p第一个字节
      40.  
        //获得KeAttachProcess地址,然后通过特征码找到
      41.  
        //KiAttachProcess的地址
      42.  
        KeAttachProcessAddress = (BYTE*)MyGetFunAddress(L"KeAttachProcess");
      43.  
        if (KeAttachProcessAddress == NULL)
      44.  
        {
      45.  
        KdPrint(("KeAttachProcess地址获取失败 "));
      46.  
        return FAILED_TO_OBTAIN_FUNCTION_ADDRESSES;
      47.  
        }
      48.  
        //将p指向KeAttachProcess函数开始处
      49.  
        p = KeAttachProcessAddress;
      50.  
        while (1)
      51.  
        {
      52.  
        if ((*(p-1) == Signature1) &&
      53.  
        (*(p-2) == Signature2) &&
      54.  
        (*(p+5) == Signature3) &&
      55.  
        (*(p+6) == Signature4) &&
      56.  
        (*p == Signature5))
      57.  
        {
      58.  
        //定位成功后取地址
      59.  
        KiAttachProcessAddress = *(PULONG)(p+1)+(ULONG)(p+5);
      60.  
        break;
      61.  
        }
      62.  
        //推动指针
      63.  
        p++;
      64.  
        }
      65.  
        //计算中继函数地址
      66.  
        *(ULONG *)(MovEaxAddress+1)=(ULONG)Nakd_KiAttachProcess;
      67.  
        WPOFF(); //清除CR0
      68.  
        //提升IRQL中断级
      69.  
        Irql=KeRaiseIrqlToDpcLevel();
      70.  
        //写入
      71.  
        RtlCopyMemory(KiAttachProcessAddress,MovEaxAddress,5);
      72.  
        RtlCopyMemory(KiAttachProcessAddress+5,JmpEax,2);
      73.  
        //恢复Irql
      74.  
        KeLowerIrql(Irql);
      75.  
        WPON(); //恢复CR0
      76.  
        return STATUS_SUCCESS;
      77.  
  • 相关阅读:
    数论小结转载
    hdu 3792 二分
    求N的所有因子(约数)
    整数划分 --- 一个老生长谈的问题 动态规划
    hdu 1541 Stars poj 1195 Mobile phones(二维) poj 2155 Matrix(二维) hdu 3584 Cube(三维) 树状数组
    zoj 3175 Number of Containers
    asp.netMVC中权限控制论
    asp.net下使用Cookie保存登录信息
    asp.netMVC中实现分页方法
    asp.net异步上传
  • 原文地址:https://www.cnblogs.com/csnd/p/11587498.html
Copyright © 2011-2022 走看看