clarexxg 发表于 2011-8-5 12:35:51

加解密算法定位、还原、密钥寻找

以封神榜为例,(适合金山绝大部分游戏,原理相同)

先脱壳(由于脱很简单,不介绍了)

用IDA看下这游戏从 ws2_32导入了哪些函数..网络游戏通迅一般用到的是send,recv,WSASend,WSARecv这四个API函数.发现用到了 recv,WSASend,WSARecv,游戏中时发现并未用recv,所以有可能登陆用到了,初步分析是游戏过程中用WSASend和WSARecv 通讯,recv用来登陆收包.

进游戏后下断bp WSASend,游戏中按V(坐下),游戏被断下,看堆栈区:

0012F1B80056616A/CALL 到 WSASend 来自 GAME1_.00566164
0012F1BC00000318|Socket = 318
0012F1C003E9B07C|pBuffers = 03E9B07C   
0012F1C400000001|nBuffers = 1
0012F1C80012F1E8|pBytesSent = 0012F1E8
0012F1CC00000000|Flags = 0
0012F1D000000000|pOverlapped = NULL
0012F1D400000000\Callback = NULL

WSASend的第二个参数buffer指向加密后的包结构,

03E9B07C04 00 00 00 E8 0B 2E 01 DC C3 E9 03 01 00 00 00...?.苊?...
03E9B08C00 04 00 00 00 00 00 00 E8 0B 2E 01 51 00 00 00.......?.Q...

观察发现 03E9B080的地址不变,dd 012E0BE8查看发现此地址存放着好像包的内容..

012E0BE8E7FF0004

一般游戏函数调用流程是这样的:

功能函数(打坐)->明文发包函数(明文包)->加密函数(密文包)->通讯函数(send等通讯函数发送密文包..)

通讯函数(recv等通讯函数收到密文包..)->解密函数(密文包)->解密明文包(解密后的明文包)..

所以012E0BE8地址存放的是密文包.再次下断bp WSASend,按V断下,连续两次CRTL+F9,加密过程要往回找(解密过程往下找);

005605B0    A1 A4F25C00    mov    eax, dword ptr //F2下断单步调试,看012E0BE8何时生成
005605B5    53            push    ebx
005605B6    83F8 02      cmp    eax, 2
005605B9    55            push    ebp
005605BA    0F84 CE000000je      0056068E
005605C0    83F8 03      cmp    eax, 3
005605C3    0F84 C5000000je      0056068E
005605C9    83F8 04      cmp    eax, 4
005605CC    0F84 BC000000je      0056068E
005605D2    83F8 05      cmp    eax, 5
005605D5    0F84 B3000000je      0056068E
005605DB    83F8 06      cmp    eax, 6
005605DE    0F84 AA000000je      0056068E
005605E4    83F8 07      cmp    eax, 7
005605E7    0F84 A1000000je      0056068E
005605ED    83F8 08      cmp    eax, 8
005605F0    0F84 98000000je      0056068E
005605F6    8B6C24 10      mov    ebp, dword ptr
005605FA    85ED            test    ebp, ebp
005605FC    0F84 93000000je      00560695
00560602    8B5C24 14      mov    ebx, dword ptr
00560606    833B 00      cmp    dword ptr , 0
00560609    0F84 86000000je      00560695
0056060F    56            push    esi
00560610    57            push    edi
00560611    8B7C24 14      mov    edi, dword ptr
00560615    8D4F 0C      lea    ecx, dword ptr
00560618    E8 83640000    call    00566AA0
0056061D    8BF0            mov    esi, eax
0056061F    8B03            mov    eax, dword ptr
00560621    8D4C24 18      lea    ecx, dword ptr
00560625    6A 02          push    2
00560627    83C0 02      add    eax, 2
0056062A    51            push    ecx
0056062B    8BCE            mov    ecx, esi
0056062D    894424 20      mov    dword ptr , eax
00560631    E8 3A610000    call    00566770
00560636    8B13            mov    edx, dword ptr
00560638    8BCE            mov    ecx, esi
0056063A    52            push    edx
0056063B    55            push    ebp
0056063C    E8 2F610000    call    00566770
00560641    8B8F D4020000mov    ecx, dword ptr
00560647    85C9            test    ecx, ecx
00560649    75 1B          jnz    short 00560666
0056064B    8B4E 44      mov    ecx, dword ptr
0056064E    8B13            mov    edx, dword ptr
00560650    8D87 D8010000lea    eax, dword ptr
00560656    83C1 02      add    ecx, 2
00560659    50            push    eax
0056065A    51            push    ecx
0056065B    52            push    edx
0056065C    E8 AF700000    call    00567710    //发现经过这个CALL后,12E0BE8中的包生成,所以这有可能是加密函数..重新在此处下断,去掉原先断点,F7跟进.
00560661    83C4 0C      add    esp, 0C
00560664    EB 16          jmp    short 0056067C
00560666    8D97 D8010000lea    edx, dword ptr
0056066C    8B01            mov    eax, dword ptr
0056066E    52            push    edx
0056066F    8B56 44      mov    edx, dword ptr
00560672    83C2 02      add    edx, 2
00560675    52            push    edx
00560676    8B13            mov    edx, dword ptr
00560678    52            push    edx
00560679    FF50 08      call    dword ptr
0056067C    56            push    esi
0056067D    8D4F 04      lea    ecx, dword ptr
00560680    E8 4B5A0000    call    005660D0
00560685    8BCE            mov    ecx, esi
00560687    E8 24620000    call    005668B0
0056068C    5F            pop    edi
0056068D    5E            pop    esi
0056068E    5D            pop    ebp
0056068F    33C0            xor    eax, eax
00560691    5B            pop    ebx
00560692    C2 0C00      retn    0C



00567710    8B4424 0C      mov    eax, dword ptr
00567714    8D5424 0C      lea    edx, dword ptr
00567718    52            push    edx
00567719    8B08            mov    ecx, dword ptr
0056771B    8B4424 0C      mov    eax, dword ptr
0056771F    894C24 10      mov    dword ptr , ecx
00567723    8B4C24 08      mov    ecx, dword ptr
00567727    50            push    eax
00567728    51            push    ecx //包长
00567729    E8 82FFFFFF    call    005676B0//继续F7跟进

005676B0    53            push    ebx
005676B1    8B4424 0C      mov    eax, dword ptr //明文包地址
005676B5    56            push    esi
005676B6    8B7424 0C      mov    esi, dword ptr //包长度
005676BA    57            push    edi
005676BB    8B7C24 18      mov    edi, dword ptr //加密密钥
005676BF    8BD6            mov    edx, esi
005676C1    8B0F            mov    ecx, dword ptr
005676C3    83E2 03      and    edx, 3
005676C6    C1EE 02      shr    esi, 2
005676C9    74 0D          je      short 005676D8
005676CB    8B18            mov    ebx, dword ptr
005676CD    83C0 04      add    eax, 4
005676D0    33D9            xor    ebx, ecx
005676D2    4E            dec    esi
005676D3    8958 FC      mov    dword ptr , ebx
005676D6^ 75 F3          jnz    short 005676CB
005676D8    85D2            test    edx, edx
005676DA    76 0D          jbe    short 005676E9
005676DC    8A18            mov    bl, byte ptr
005676DE    32D9            xor    bl, cl
005676E0    8818            mov    byte ptr , bl
005676E2    40            inc    eax
005676E3    C1E9 08      shr    ecx, 8
005676E6    4A            dec    edx
005676E7^ 75 F3          jnz    short 005676DC
005676E9    8B07            mov    eax, dword ptr
005676EB    8BC8            mov    ecx, eax
005676ED    C1E1 05      shl    ecx, 5
005676F0    2BC8            sub    ecx, eax
005676F2    B8 01000000    mov    eax, 1
005676F7    81C1 05840808add    ecx, 8088405
005676FD    890F            mov    dword ptr , ecx
005676FF    5F            pop    edi
00567700    5E            pop    esi
00567701    5B            pop    ebx
00567702    C3            retn

在单步调试的时候发现数据段中的数据是4字节4字节在变的..走完这段,密文包也就出来了..又因为这段没调用别的什么模块..所以断定这是加密函数.. (希望大家学的是方法,加密往前跟,解密往后跟,,你会发现这游戏调用的加解密是同一个函数,只是密钥不同,所以解密过程就不分析了.)

CString EncAndDec(CString datestr,CString key,int len) //加解密函数
{
int j,nprev,nkey,nxor;
CString strxor,nxor1;
j=0;
strxor=NULL;
for(int i=0;i<len,i++)
{
    if (i<2)
    {
    strxor=strxor+copy(datastr,i*2+1,2);
    continue;
    }
    nprev=(long int)((int)("0x"+copy(datastr,i*2+1,2)));
    nkey=(long int)((int)("0x"+copy(key,i*2+1,2)));
    j++;
    if (j>3)
    {
    j=0;
    }
    nxor=nprev ^ nkey;
    strxor=strxor+nxor1.Format("%x",nxor);
}
return strxor;
}

密钥的查找:

退出游戏,在选择服务器前下断:bp recv;选择服务器后断下:

0012F92800566447/CALL 到 recv 来自 GAME1_.00566445
0012F92C00000360|Socket = 360
0012F93004C5983C|Buffer = 04C5983C
0012F93400000022|BufSize = 22 (34.)
0012F93800000000\Flags = 0

dd 04C5983C,ALT+F9看收到的数据:

04C5983C22 00 20 00 D4 47 EE F9 D8 3B 99 89 F0 01 6E AC". .訥铢?檳?n
04C5984C62 7B 1A 75 64 97 FE C9 68 8B 22 5D AC BF 86 31b{ud楟蒱?]

kafeikuku 发表于 2020-3-25 09:45:19

支持楼主,支持看流星社区,以后我会经常来!

kkoo815 发表于 2020-4-19 19:46:39

https://www.yxkfw.com/data/attachment/forum/202004/19/094200agqgvi1cebgifcfe.png
页: [1]
查看完整版本: 加解密算法定位、还原、密钥寻找