塞翁364 发表于 2024-2-29 12:54:24

简单分析某游戏debugport清零

简单分析,小弟能力有限如果有什么错误的话,欢迎各位牛牛指正,共同进步嘛

第一处清零代码
[*]
[*]mov   edi, edi
[*]push    ebp
[*]mov   ebp, esp
[*]push    ecx
[*]push    esi
[*]mov   , 0
[*]call    ds:KeGetCurrentIrql
[*]cmp   al, 2 //判断中断级
[*]mov   esi, offset SpinLock
[*]mov   ecx, esi
[*]jb      short loc_1002660
[*]call    ds:KefAcquireSpinLockAtDpcLevel
[*]mov   , 1
[*]jmp   short loc_1002669

复制代码
loc_1002660:
[*]
[*]call    ds:KfAcquireSpinLock
[*]mov   , al

复制代码
loc_1002669:
[*]
[*]mov   ecx, dword_100D1C0//这里比较关键啦。 dword_100D1C0 这个全局变量很重要
[*]mov   edx, offset dword_100D1C0
[*]cmp   ecx, edx
[*]jz      short loc_10026BA// 这个是个关键比较啦
[*]push    ebx
[*]push    edi

复制代码
loc_100267A:
[*]
[*]mov   edi, dword_100CEDC//这里存放着EPROCESS的下标
[*]mov   edi,       //CEDC+4的位置正是BC
[*]add   edi,    //的位置存放着EPROCESS结构的地址
[*]xor   eax, eax
[*]xchg    eax,       //清零
[*]mov   eax, dword_100CEDC
[*]mov   ebx, //存放着EPROCESS+70位置的内容
[*]mov   eax, //CEDC+18位置存放70下标
[*]mov   edi, //EPROCESS结构的地址
[*]mov   , ebx//写回去防止修改位置
[*]mov   ebx, //74的内容
[*]mov   , ebx//写回去
[*]mov   edi, dword_100CEDC
[*]mov   edi, //取78位置
[*]add   edi,
[*]xor   eax, eax       //写回去
[*]stosd
[*]stosd
[*]

复制代码
上面这一段把EPROCESS+70,74,78的位置全部封杀了
防止把BC的位置修改为70,74,78,所以曾经某种方法改位置变得无效了               
      
第2段清零位代码,这里有个检测
[*]
[*]                               mov   edi, edi
[*]                               push    ebp
[*]                               mov   ebp, esp
[*]                               push    ecx
[*]                               push    ecx
[*]                               push    ebx
[*]                               xor   ebx, ebx
[*]                               push    esi
[*]                               mov   ecx, offset SpinLock
[*]                               mov   byte ptr , 1
[*]                               mov   , ebx
[*]                               call    ds:KfAcquireSpinLock
[*]                               mov   esi, dword_100D1C0 //这里同1的注释这个变量很重要
[*]                               cmp   esi, offset dword_100D1C0//这里同1的注释一样
[*]                               mov   , al
[*]                               jz      loc_1004FE9 //关键跳
[*]                               mov   , bl
[*]                               push    edi

复制代码
loc_1004F62:
[*]
[*]                               mov   eax, dword_100CEDC //这里存放着EPROCESS的下标
[*]                               mov   eax,       //CEDC+4的位置正是BC
[*]                               lea   edi, //的位置存放着EPROCESS结构的地址 注意这里是取地址
[*]                               add   eax,    //指到BC处
[*]                               xor   ebx, ebx
[*]                               xchg    ebx, //清零
[*]                               xor   eax, eax
[*]                               cmp   , eax
[*]                               jnz   short loc_1004F83
[*]                               cmp   ebx, eax
[*]                               jz      short loc_1004F83
[*]                               mov   ecx,
[*]                               mov   , ecx

复制代码
loc_1004F83:
[*]
[*]                               mov   ecx, 1505h
[*]                               movsx   edx, byte ptr //这段算法主要是检测有没有被修改如果有的话就重启机器
[*]                               imul    ecx, 21h   //edi存放着EPROCESS的地址,有兴趣的朋友可以逆下
[*]                               add   ecx, edx
[*]                              inc   eax
[*]                              cmp   eax, 18h
[*]                              jb      short loc_1004F88
[*]                              cmp   ecx, //1CH处存放着检验值 1CH+4位置存放着进程名
[*]                              jz      short loc_1004FA1
[*]                               call    sub_100163C //重启机器

复制代码
其实这里注意dword_100D1C0 变量这里很重要。                                          

这2个都好搞定,关键是有个监控
[*]                     mov   edi, edi
[*]                               push    ebp
[*]                               mov   ebp, esp
[*]                               sub   esp, 10h
[*]                              mov   eax, dword_100CA6C //CA6C=CF;
[*]                              push    ebx
[*]                              push    esi
[*]                              push    edi
[*]                              mov   edi, offset unk_100CA68
[*]                              sub   edi, 0CA68h//EDI=模块载入地址
[*]                              lea   ecx, //EAX=CF;
[*]                              shl   ecx, 2         //这步计算我估计应该是得出了100B268总大小
[*]                              push    0
[*]                           mov   , edi
[*]                           mov   , ecx
[*]                           pop   edx
[*]                           jz      short loc_100422B

复制代码
loc_100420C:
[*]                      movzx   esi, byte_100B268/*
[*]                           100B268这个变量指向一个结构 这个结构类似 struct{ULONG PY(偏移),INT LEN,ULONG HASH}
[*]                            CRC检验,估计是黑白名单之类的,我的猜测,如果有错那位朋友知道的话帮我纠正一下
[*]                         */
[*]                        mov   ebx,
[*]                           shr   ebx, 1Bh
[*]                           xor   esi, ebx
[*]                            mov   ebx,
[*]                           shl   ebx, 5
[*]                            xor   esi, ebx
[*]                           inc   edx
[*]                        cmp   edx, ecx
[*]                         mov   , esi
[*]                        jb      short loc_100420C

复制代码
loc_100422B:
[*]                      cmp   , 17606A55h //上面一系列的计算和(17606A55计算后的总大小)比较,如果被修改了就重启
[*]                      jz      short loc_100423E
[*]                      call    sub_100163C//重启
[*]                      mov   eax, dword_100CA6C

复制代码
loc_100423E:
[*]                     and   , 0
[*]                     test    eax, eax
[*]                     jbe   short loc_100429F //这个跳可以修改
[*]                     mov   esi, offset unk_100B26C

复制代码
loc_100424B:
[*]                  mov   ecx, //ECX==STRUCT结构的PY偏移
[*]             mov   edx,
[*]                  and   , 0
[*]                  add   ecx, edi   //加上模块载入地址址
[*]            test    edx, edx
[*]                  mov   , edx
[*]                  jbe   short loc_1004282

复制代码
loc_100425D:
[*]                   mov   edi,
[*]                   movzx   edi, byte ptr //取出PY下面的值来计算HASH
[*]                   mov   ebx,
[*]                   shr   ebx, 1Bh
[*]                   xor   edi, ebx
[*]                   mov   ebx,
[*]                   shl   ebx, 5
[*]                   xor   edi, ebx
[*]                   inc   
[*]                   cmp   , edx//edx == STRUCT结构中的LEN
[*]                   mov   , edi
[*]                   jb      short loc_100425D
[*]                   mov   edi,
[*]                   mov   ecx,
[*]                   cmp   ecx,    //经过一系列运算比较是不是STRUCT中的HASH
[*]                   jz      short loc_1004294 //相同就跳
[*]            call    sub_100163C //不同就重启
[*]            mov   eax, dword_100CA6C

复制代码
loc_1004294:
[*]                  inc   
[*]                  add   esi, 0Ch
[*]                  cmp   , eax
[*]                  jb      short loc_100424B
[*]                  pop   edi
[*]                  pop   esi
[*]                  pop   ebx
[*]                  leave
[*]               retn

复制代码
重启代码
[*]          in      al, 64h
[*]               mov   bl, al
[*]               test    bl, 1
[*]               jz      short loc_1001660
[*]               in      al, 60h
[*]               test    bl, 2
[*]               jnz   short loc_1001655
[*]               mov   al, 0FEh
[*]               out   64h, al
[*]               popa
[*]               retn

复制代码
解决方法很多,我说几种

第一种是我以前用的一种比较挫的,其实最重要的是解决监控哪里,
   分2步 1。在监控哪里 跳走或者直接返回         
         2.注意我标的清零的2段代码
         mov   ecx, dword_100D1C0//这里比较关键啦。                  
         mov   edx, offset dword_100D1C0
                cmp   ecx, edx
               jz      short loc_10026BA// 这个是个关键比较啦
         在函数开头钩钩一下跳到我们的函数
         处理一下先查找到模块加载地址(Modulebase)。
          伪代码
         ULONG D1C0=Modulebase+0XD1C0;
            _asm{
                mov edi,edi
                push ebp
                mov ebp,esp
                mov eax,D1C0
                mov ,eax
                mov eax,Ret(返回地址)
          add eax,5
          jmp eax
   }                  
      jz      short loc_10026BA相等就跳啦

第二种方法 前天看到的,好像更加简便 查看
感谢这位朋友的共享精神;
第三种没尝试
直接修改
       jz      short loc_10026BA   
         jz      loc_1004FE9
         jbe   short loc_100429F

第三种没实践过只是大概估计,有兴趣的朋友可以尝试一下。多实践总不会错
至于那些SSDT HOOK呀inline-hook要我相信大部分人都能解决的。
本人能力有限。此文章如果有什么不正确的地方,希望大家指正一下,共同学习,共同进步嘛。
页: [1]
查看完整版本: 简单分析某游戏debugport清零