隨筆 - 1  文章 - 37  trackbacks - 0
          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          留言簿(16)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          test

          搜索

          •  

          最新評論

          在上一篇的跟蹤中,調試后發現二次加密的密匙其實就是一個常量008B480C,分析一下整個二次加密的過程,以下代碼均在VC6.0中運行通過,加密后數據與客戶端實際發送數據一致。

          函數1 - _declspec(naked) void _stdcall getEncryptMsg(long *nIdentity, char * dest)
          nIdentity - 008B480C
          dest - 二次加密明文
          該函數負責生成二次加密后的明文,代碼如下
          注意:第13行是原來的代碼,14行是自己加的,原因如下
          在實際的客戶端中,mov     al, byte ptr [eax]  取的是地址為008B480C的低8位,調試的時候該值為0,有可能二次解密后的解密掩碼會存放在這里,目前還未可知;而在該代碼中008B480C的地址是不可讀的,因此這里需要將AL置0

          static long nIdentity = 0x008B480C;

           1_declspec(naked) void _stdcall getEncryptMsg(long *nIdentity, char * dest){
           2    _asm{
           3          sub     esp, 8
           4  push    ebx
           5  push    ebp
           6  push    esi
           7  push    edi
           8  mov     edi, dword ptr [esp+0x20]  
           9  inc     edi                        
          10  mov     dword ptr [esp+0x14], 4    
          11L008:
          12  mov     eax, dword ptr [esp+0x1C]  
          13  ;mov     al, byte ptr [eax]         
          14  xor     al, al
          15  xor     al, 0x87                   
          16  push    0x31    
          17  push    0
          18  mov     byte ptr [esp+0x1B], al    
          19  call    ll401A60                   
          20  add     al, 0x0A                   
          21  push    0x13
          22  push    0
          23  mov     byte ptr [esp+0x30], al    
          24  call    ll401A60                   
          25
          26  mov     cl, byte ptr [esp+0x30]    
          27
          28  mov     ebx, eax                   
          29  add     bl, 0x0A                   
          30  movzx   eax, bl                    
          31  add     esp, 0x10                  
          32  mov     byte ptr [edi-1], cl       
          33  mov     byte ptr [edi+8], bl       
          34  xor     esi, esi
          35  lea     ebp, dword ptr [eax-1]     
          36L029:
          37  movzx   eax, byte ptr [esp+0x13]   
          38  mov     edx, 0x80                  
          39  mov     ecx, esi                   
          40  sar     edx, cl                    
          41  push    ebp
          42  push    0
          43  test    eax, edx                   
          44  jnz L039
          45  call    ll401A60
          46  jmp L041
          47L039:
          48  call    ll401A60                   
          49  add     al, bl                     
          50L041:
          51  add     al, byte ptr [esp+0x28]    
          52  add     esp, 8
          53  mov     byte ptr [edi+esi], al     
          54  inc     esi                        
          55  cmp     esi, 8                     
          56  jl L029
          57  mov     edx, dword ptr [esp+0x1C]  
          58  mov     eax, dword ptr [esp+0x14]  
          59  inc     edx                        
          60  add     edi, 0x0A                  
          61  dec     eax
          62  mov     dword ptr [esp+0x1C], edx
          63  mov     dword ptr [esp+0x14], eax
          64  jnz L008
          65  pop     edi
          66  pop     esi
          67  pop     ebp
          68  pop     ebx
          69  add     esp, 8
          70  retn    8
          71
          72    }

          73}

          ---------------------------------------------------------------------------------------------------------
          函數2 - _declspec(naked) int _cdecl _ll401A60(int a1, int a2)
          該函數負責生成一個偽隨機數

          _declspec(naked) int _cdecl _ll401A60(int a1, int a2)
          {

              _asm
          {
                      push    esi
                      push    edi
                      call    ll4bb903
                      mov     esi, eax
                      call    ll4bb903
                      sub     esi, eax
                      jns L008
                      neg     esi
          L008:
                      mov     ecx, dword ptr [esp
          +0xC]  
                      mov     edi, dword ptr [esp
          +0x10
                      mov     eax, esi                  
                      sub     edi, ecx                  
                      cdq                               
                      inc     edi                       
                      idiv    edi
                      pop     edi
                      pop     esi
                      mov     eax, edx
                      add     eax, ecx
                      retn
              }

          }

          ---------------------------------------------------------------------------------------------------------
          函數3 - _declspec(naked) int _cdecl ll4bb903()
          該函數根據客戶端啟動時生成的當前時間來進行隨機數生成(這個步驟調試2個小時才出來)

          long int_4D4F78 = 0x484953AE//客戶端啟動時的當前時間

          _declspec(naked) 
          int _cdecl ll4bb903()
          {
              _asm
          {
                  mov     eax, dword ptr [int_4D4F78]
                  imul    eax, eax, 
          0x343FD
                  add     eax, 
          0x269EC3
                  mov     dword ptr [int_4D4F78], eax
                  xor     eax, eax
                  mov     ax, word ptr [int_4D4F78
          +2]
                  and     eax, 
          0x7FFF
                  retn
              }

          }


          運行的Main函數如下,客戶端在啟動時執行了5次ll4bb903,因此這里也執行5次,不過服務器端也不可能知道客戶端到底什么時候啟動的,所以未必一定要執行5次,這點還沒試
          void encodeTest(){

              
          //執行5次ll4bb903()
              ll4bb903();
              ll4bb903();
              ll4bb903();
              ll4bb903();
              ll4bb903();

              
          long * ll = (long*)0x008b480c;
              ll 
          = 0;

              
          char dest[40];
              
              getEncryptMsg(
          &nIdentity, dest);
              printf(
          "%s\n", dest);

              
          char idest[54];
              fnEncode6BitBuf(dest, idest, 
          4054);
              printf(
          "%s\n", idest);
          }

          以上代碼轉成JAVA代碼如下:
          public class DecodeMask {

              
          private static int int_4D4F78 = 0x484953AE// 系統當前時間,不包含毫秒
              private static long nIdentity = 0x008B480C// 常量

              
          private static int ll4bb903() {
                  int_4D4F78 
          = int_4D4F78 * 0x343FD + 0x269EC3;
                  
          int r = (int_4D4F78 >> 16& 0x7FFF;  //這里取高16位
                  
          return r;
              }


              
          private static int ll401A60(int nFrom, int nTo) {
                  
          int nRandNum = 0;
                  
          int nRand = (ll4bb903() - ll4bb903());
                  
          if (nRand < 0)
                      nRand 
          = -nRand;
                  nRandNum 
          = nRand % (nTo - nFrom + 1+ nFrom;
                  
          return nRandNum;
              }


              
          private static byte[] getEncryptMsg() {
                  
          byte[] dest = new byte[40];
                  
          int pos = 1;
                  
          for (int i = 0; i < 4; i++{

                      
          byte bMax = (byte) (ll401A60(00x31+ 0x0A);
                      
          byte bMin = (byte) (ll401A60(00x13+ 0x0A);

                      dest[pos 
          - 1= bMax;
                      dest[pos 
          + 8= bMin;

                      
          for (int j = 0; j < 8; j++{
                          
          int bT = 0x80 >> j;
                          
          byte _b = (byte) ll401A60(0, bMin - 1);
                          
          if ((bT & 0x87!= 0{
                              _b 
          += bMin;
                          }

                          dest[pos 
          + j] = (byte) (_b + bMax);
                      }

                      nIdentity
          ++;
                      pos 
          += 0x0a;
                  }


                  
          return dest;
              }


              
          /**
               * 調試: 客戶端啟動時的當前時間為 0x484953AE 
               * 選擇角色進入游戲時,客戶端向服務器端實際發送數據為 
               * #3<<<<<Jx?<<<<<<<<E`\cFo<mO@Q?A=ToC]\YE_DnGMDfQ_Q@IPIOMqLW?oPS?mD_E>dtAL!
               * 該方法運行后的正確輸出應為: 
               * E`\cFo<mO@Q?A=ToC]\YE_DnGMDfQ_Q@IPIOMqLW?oPS?mD_E>dtAL
               
          */

              
          public static void doTest() {
                  
          // 執行5次ll4bb903()
                  ll4bb903();
                  ll4bb903();
                  ll4bb903();
                  ll4bb903();
                  ll4bb903();
                  
          byte[] b = getEncryptMsg();
                  System.out.println(
          "二次加密明文 - [" + new String(b) + "]");
                  String s 
          = PacketEncode.fnEncode6BitBuf(b);
                  System.out.println(
          "二次加密密文 - [" + s + "]");
              }


              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  doTest();
              }


          }
          posted on 2008-06-07 10:20 Phrancol Yang 閱讀(709) 評論(3)  編輯  收藏 所屬分類: 反匯編

          FeedBack:
          # re: [原]MIR3G二次加解密反匯編分析(四)——還原 2011-10-31 15:54 Mir3
          ll4bb903 這其實是srand 函數  回復  更多評論
            
          # re: [原]MIR3G二次加解密反匯編分析(四)——還原 2011-10-31 15:54 Mir3
          int_4D4F78 是隨即數種子  回復  更多評論
            
          # re: [原]MIR3G二次加解密反匯編分析(四)——還原 2011-10-31 19:22 phrancol
          @Mir3
          好久沒有研究這個...  回復  更多評論
            
          主站蜘蛛池模板: 吐鲁番市| 旅游| 永福县| 盐源县| 台湾省| 崇仁县| 沙雅县| 沈阳市| 依安县| 商都县| 库尔勒市| 阿尔山市| 房产| 林芝县| 凤台县| 伊金霍洛旗| 昌江| 确山县| 安康市| 曲阳县| 长垣县| 会泽县| 梅河口市| 沅陵县| 沐川县| 芷江| 河北省| 额济纳旗| 浠水县| 靖西县| 九龙坡区| 南木林县| 泾阳县| 华阴市| 浠水县| 桐城市| 昌吉市| 吴忠市| 德州市| 榆树市| 大兴区|