euteamo 发表于 2015-9-16 17:56

OD下断 解密 石器时代8.0 客户端与服务器 通信封包,写给像我一样的新手[持续更新]

本帖最后由 euteamo 于 2015-9-23 15:51 编辑

我解密的是石器时代,一个历史非常悠久的网络游戏。准备的工具:
客户端:有1.0个g,不过据说版主建议附加被解密软件,我就不上传了,有需要的可以自行到www.shiqi.in下载(我可不是为了打广告而发布的)
计算机:windows自带的即可,用于2进制,10进制,16进制的数值对应,我是用易语言的(10进制),机器本身的汇编语言(16进制),加密操作位或,位与,位异或用2进制查看比较清晰,
其他工具:WPE,OD,论坛原创区和网盘都有,一本汇编的基础或者指令大全,要不然一大段一大段的汇编代码看上去会头晕的

目的:
破解玩玩,玩游戏的更高境界,玩破解大家都知道,完全破解一款游戏的封包以后能做什么,,我这里就不细说了哈

新手可以按照顺序看下去,大牛们如果要看,可以直接红色点击推荐楼层
第一章:从发送聊天封包入手
1.1 分析,寻找代码段

[*]03楼:分析封包,寻找程序内生成封包的程序段
[*]10楼:跟踪封包栈001872b8,查找修改代码段
[*]12楼:锁定001632e4栈 查找修改代码段 step1 step2
[*]24楼:锁定001632e4栈 查找修改代码段 step3 step4
[*]32楼:call 0049528d:修改001832b8栈的代码段

1.2 构建封包组成框架紅色部分为需要反汇编的加密部分

[*]
1.3 加密算法分析

[*]13楼:栈 001632e4: 前6位 加密算法
[*]28楼:字符串加密 call sa_8001s.0048CD60汇编分析
[*]29楼:字符串加密 call使用易语言反汇编   步骤1-3
[*]29楼:字符串加密 call使用易语言反汇编   步骤4
[*]31楼:call 0048d110: 001832b8 通过 key0加密方式 到 001732c0
[*]33楼:call 0048f7c0 : 生成封包一级加密算法

[*]34楼:聊天字符串 加密源代码                                                                      <<<推荐

1.4 加解密过程

[*]36楼:封包头:6位字节,存储封包自身偏移数据,加密 以及 解密             <<<推荐------         对应的13楼 栈001632e4 的加密
[*]37楼:封包加密段:偏移,排序封包段加密 解密                                        <<<推荐 ------         对应的31楼 call0048d110,001832b8,通过 key0加密方式 到001732c0
[*]38楼:封包正文:一级加密 聊天数据 加密 解密                                          <<<推荐

1.5 完整封包解密

[*]39楼:聊天发送封包 完整解密 源代码


[*]46楼:番外:小工具简易封包分析器
第二章:其他封包
[*]40楼:走路及转向
[*]43楼:账密登录 - 角色选择界面 的通信加解密

持续更新中








euteamo 发表于 2015-9-18 02:41

本帖最后由 euteamo 于 2015-9-18 16:36 编辑

0048D322|.E8 39FAFFFF   call sa_8001s.0048CD60 分析                  


0048CD65|.33DB          xor ebx,ebx
0048CD85|.8B6C24 20   mov ebp,dword ptr ss:            ;把钥匙指针传递

0048CDBB|>8B4424 24   /mov eax,dword ptr ss:         ;载入循环数,循环首
0048CDBF|.B9 03000000   |mov ecx,0x3                                    ;循环常量3
0048CDC4|.99            |cdq
0048CDC5|.F7F9          |idiv ecx                                                 ;eax求余3
0048CDC7|.8B4424 18   |mov eax,dword ptr ss:         ;载入的指针
0048CDCB|.8B4C24 24   |mov ecx,dword ptr ss:         ;载入循环数
0048CDCF|.8A0401      |mov al,byte ptr ds:                   ;取中数据
0048CDD2|.25 FF000000   |and eax,0xFF                                        ;留下8位
0048CDD7|.8D0C12      |lea ecx,dword ptr ds:                ;
0048CDDA|.D3E0          |shl eax,cl                                             ;左移 余数双倍
0048CDDC|.8A0C2F      |mov cl,byte ptr ds:                  ;取钥匙         ID+网址
0048CDDF|.0BF0          |or esi,eax                                                 ;或一下
0048CDE1|.8BC6          |mov eax,esi                                          ;用或结果来做参数
0048CDE3|.2BC1          |sub eax,ecx                                          ;参数加上钥匙顺位
0048CDE5|.8B4C24 20   |mov ecx,dword ptr ss:             ;传递加密ascii指针
0048CDE9|.83E0 3F       |and eax,0x3F                                       ;保留6位
0048CDEC|.43            |inc ebx                                                    ;写入位序数
0048CDED|.47            |inc edi                                                    ;钥匙序数
0048CDEE|.8A0C08      |mov cl,byte ptr ds:                  ;偏移 加密ascii
0048CDF1|.8B4424 14   |mov eax,dword ptr ss:            ;传递写入位置指针
0048CDF5|.884C03 FF   |mov byte ptr ds:,cl             ;写入

0048CE02|>C1EE 06       |shr esi,0x6                                           ;右移6位
0048CE05|.83FA 02       |cmp edx,0x2                                          ;第0次及每个第1,3次循环跳转
0048CE08|.75 20         |jnz short sa_8001s.0048CE2A

0048CE0A|.8A142F      |mov dl,byte ptr ds:                  ;取钥匙位
0048CE0D|.8B4C24 20   |mov ecx,dword ptr ss:            ;传递加密ascii指针
0048CE11|.2BF2          |sub esi,edx                                             ;加上余数
0048CE13|.83E6 3F       |and esi,0x3F                                          ;保留6位
0048CE16|.43            |inc ebx                                                   ;写入位序数
0048CE17|.47            |inc edi                                                    ;钥匙位序数
0048CE18|.8A140E      |mov dl,byte ptr ds:                  ;偏移 加密ascii
0048CE1B|.885403 FF   |mov byte ptr ds:,dl            ;写入
0048CE1F|.8A042F      |mov al,byte ptr ds:
0048CE26|.33FF          |xor edi,edi
0048CE28|>33F6          |xor esi,esi

每个第1,3次循环跳转位
0048CE2A|>8B4424 24   |mov eax,dword ptr ss:          ;取循环数
0048CE2E|.8B4C24 1C   |mov ecx,dword ptr ss:         ;取总循环数
0048CE32|.40            |inc eax                                 ;
0048CE33|.3BC1          |cmp eax,ecx                           ;
0048CE35|.894424 24   |mov dword ptr ss:,eax            ;记录循环数
0048CE39|.^ 7C 80         \jl short sa_8001s.0048CDBB                  ;循环尾

0048CE3B|.85F6          test esi,esi
0048CE3D|.74 18         je short sa_8001s.0048CE57                     ;这里好像是判定是不是满足4位
0048CE3F|.8A042F      mov al,byte ptr ds:                      ;
0048CE42|.8B4C24 20   mov ecx,dword ptr ss:               ;
0048CE46|.2BF0          sub esi,eax                                                 ;
0048CE48|.8B4424 14   mov eax,dword ptr ss:                ;
0048CE4C|.83E6 3F       and esi,0x3F                                             ;
0048CE4F|.43            inc ebx                                                       ;
0048CE50|.8A140E      mov dl,byte ptr ds:                        ;
0048CE53|.885403 FF   mov byte ptr ds:,dl                  ;

满足4位跳转
0048CE57|>8B4C24 14   mov ecx,dword ptr ss:            ;   传递写入位置指针

0048CE5D|.8BC3          mov eax,ebx
0048CE5F|.C6040B 00   mov byte ptr ds:,0x0               ;末尾写0

运行前关键栈内容:
0018F84C|00327C50

0017B300   00000000

运行后关键栈内容:
0018F84C|00327C50
0017B300   5A63475A
0017B304   00000000

钥匙
maqianhe1

ascii 加密码 长度 0x3f(所以总是 与0x3f)
004D70E430 31 32 33 34 35 36 37 38 39 41 42 43 44 45 460123456789ABCDEF
004D70F447 48 49 4A 4B 4C 4D 4E 4F 50 51 52 53 54 55 56GHIJKLMNOPQRSTUV
004D710457 58 59 5A 61 62 63 64 65 66 67 68 69 6A 6B 6CWXYZabcdefghijkl
004D71146D 6E 6F 70 71 72 73 74 75 76 77 78 79 7A 7B 7Dmnopqrstuvwxyz{}

全部的素材在这里了。
红色地方是没有经过分析的,可能是输入的字符串不足4个的时候强制再加一个,

目前已知的情况
字符串只用到钥匙加密,钥匙又是本身id+一个网址,所以真是很囧。

钥匙长度 0x19,当字符串超过钥匙长度的时候未知情况。



关系步骤我已经全部列明,而且分析出来了,有兴趣的童鞋可以琢磨一下这么加密的。
明天我的工作就是把他怎么加密的算法给用其他语言写出来,
PS:我其他的语言只会易语言
要睡觉了,晚安哈。

as36601987 发表于 2015-9-16 18:13

我发现发的是一些废得不能再废的废话!

awfiqr 发表于 2015-9-16 18:27

这就没了?
主要部分一句没有。

euteamo 发表于 2015-9-16 18:33

本帖最后由 euteamo 于 2015-9-19 13:32 编辑

分析封包,寻找程序内生成封包的程序段
step 1 截取封包,简单分析
首先用WPE封包在游戏里说话,第一次就简单点,说,1,2
经过多次尝试
82 A5 85 82 82 CC A8 92 87 A8 91 C4 DC C4 D9 C4 CB C7 C4 96 A8 CF B8 A8 91 C4 96 A8 CF B2 A8 91 C4 A5 B8 9C A5 C4 96 A8 92 9A A8 91 C4 96 A8 CF 9A A8 91 C4 96 0A
82 BD 86 82 82 CC A8 92 87 A8 91 C4 DC C4 D9 C4 CB C7 C4 96 A8 CF B8 A8 91 C4 96 A8 CF B2 A8 91 C4 A5 B8 C9 9E C4 96 A8 92 9A A8 91 C4 96 A8 CF 9A A8 91 C4 96 0A
82 B1 88 82 82 CC 91 C4 DC C4 D9 C4 CB C7 C4 96 A8 CF B8 A8 91 C4 96 A8 CF B2 A8 91 C4 A5 B8 9C A5 C4 96 A8 92 9A A8 91 C4 96 A8 CF 9A A8 91 C4 96 A8 92 87 A8 0A
82 C8 85 82 82 CC C4 D9 C4 CB C7 C4 96 A8 CF B8 A8 91 C4 96 A8 CF B2 A8 91 C4 A5 B8 9C A5 C4 96 A8 92 9A A8 91 C4 96 A8 CF 9A A8 91 C4 96 A8 92 87 A8 91 C4 DC 0A

发一个单字节字符串的时候
封包长度是0x36个字节
第4-6和最后一个字节是一样的。
输入相同的字符串:前3个字节不同后面7-53字节也会不同,但是仅仅是排序不同,相当于ABCD,BCDA,DABC这样的不同排序。
输入不同的字符串:除了其他不同的,封包其中一个字节会有所更改。


简单分析完毕以后
下面就用OD下send断点
我是在win7 64上操作的,可能其他系统不同



step 2 od下断
建议要稍微有一些汇编基础,如果没有的话,就要度娘到一个汇编指令大全,然后对照分析

附加完程序后,找到模块,ws2_32

ctrl n搜索找到send,直接F2下断



然后在游戏里说话,断点成功,执行到返回(ctrl+F9),直到回到主模块(sa_8001s),因为是查询如何加密,所以往回走



这里怎么看回到程序模块,就看od的标题,里面是不是我们附加的程序




step 3 寻找相关 跟踪信息
在这里,封包是已经准备好了,等待发送了,所以应该会有一些关于封包的信息,
仔细查看下每个寄存器的值,再看下栈里的内容
发现,栈里面有发送封包的封包一些基本的信息。
我们跟踪一条封包长度0x36



往回看,栈里的值是push eax进去的,
寻找相关eax赋值的语句,找到这条从内存读取。

再在内存里下这个位置的写入断点




断在了
0045ED62    893D 00B46104   mov dword ptr ds:,edi



继续往上找,和edi相关的语句
0045ED53    03F8            add edi,eax
0045ED14    8B4424 14       mov eax,dword ptr ss:


删除内存断点,重新下断点,进游戏说话,取esp的值
得知eax的值36存放在栈0018328C赋值过去的



重新来一步,在主模块处,给eax赋值前 多个push 前下断点 ,开始找到在18328C存入值的指令




0043E155    51            push ecx//找到


在往上看,ecx的值是检测栈里长度得来的,同时找到所检测的栈



指向的头位置为 0x001872B8,长度为0x36

001872B8|8282A982
001872BC|A8B8CC82
001872C0|A896C491
001872C4|91A8B2CF
001872C8|9CB8A5C4
001872CC|A896C4A5
001872D0|91A89A92
001872D4|CFA896C4
001872D8|C491A89A
001872DC|8792A896
001872E0|DCC491A8
001872E4|CBC4D9C4
001872E8|A896C4C7
001872EC|00000ACF

4-7位为 82 82 CC 末尾为 0A ,长度为0x36 ,和封包很相似。
应该就是程序等待发送的封包了,运行到返回。



找到了这一段代码,在开头和结尾处下断点,重新在游戏里发送信息,这次可以更改下发送内容
断前无修改,断后栈内容修改,应该就是加密段了..

至此寻找到某一处加密封包的段。要在retn前返回。











euteamo 发表于 2015-9-16 18:34

亲们,这个是个直播贴...我刚才还在码字呢..

Ps出来的小赵 发表于 2015-9-16 19:06

哈哈 直播,前排出售瓜子,矿泉水,方便面……

yt753302 发表于 2015-9-16 19:13

楼主给力 强大 不已 膜拜

一片枫叶落地无 发表于 2015-9-16 19:14

花生瓜子 啤酒 饮料    配上图- - 不然 还是不知道你在说什么

z234465027 发表于 2015-9-16 19:25

顶,楼主给力

euteamo 发表于 2015-9-16 19:31

本帖最后由 euteamo 于 2015-9-19 13:44 编辑

跟踪封包栈001872b8,查找修改代码段
step 1 跟踪封包栈
在每一个call上下断点,并观察 001872b8 z栈里的数据


发现经过这个call的时候数据变更了。进入call继续这一步



把所有的call上都加断点,并在retn下断。找到程序经过这个call以后,数据变更,进入call查看。

进入call后,发现有2个循环,在每个循环首-1,尾+1的位置断点,看后观察数据经过哪个循环以后更改。



发现是第二个。其实第一个是数了一下另外一个栈多少数据,然而并没有上面卵用,后面又被重置了,,,,



step 2 分析代码段
0048D02B    53            push ebx
0048D02C    8BDD            mov ebx,ebp                                       //ebp是指向001632e4
0048D02E    2BDA            sub ebx,edx                                           //这个是一条循环
0048D030    8A0413          mov al,byte ptr ds:            //从另外一个地址读取byte数据
0048D033    46            inc esi                                                      //序数加1
0048D034    F6D0            not al                                                    //二级加密就是这个,这叫啥,或运算把~
0048D036    8802            mov byte ptr ds:,al                     //然后写入
0048D038    8BFD            mov edi,ebp                                       //重置搜索条件
0048D03A    83C9 FF         or ecx,-0x1                                       //重置循环数
0048D03D    33C0            xor eax,eax                                          //重置存储器
0048D03F    42            inc edx                                                   //读取位置+1
0048D040    F2:AE         repne scas byte ptr es:                  //搜索剩余转换
0048D042    F7D1            not ecx                                                 //
0048D044    49            dec ecx                                                    //
0048D045    3BF1            cmp esi,ecx                                           //循环尾
0048D047^ 72 E7         jb short 0048D030

新手最好像我一样,备注好每一条指令。

经过分析得出,ebp指向另外一个栈001632e4的位置,这段循环是读取另外一个栈里的数据然后进行或运算,然后写入001872b8。

暂时不称之为一级加密了,总之是另外一层加密哈,那么回到上面那一步,在每个call上面下断,看看是哪位修改了这个栈

001632E4   7D78527D
001632E8   656D337D
001632EC   693B6E57
001632F0   57653057
001632F4   57693B6E
001632F8   6E57786D
001632FC   263B233B
00163300   3B38343B
00163304   46575769
00163308   693B6E57
0016330C   574D5757
00163310   475A3B6E
00163314   693B5A63
00163318   00000057

setp 3 总结
封包栈001872b8经过 call 0048d010 修改
由001632e4 每位位或运算获得




页: [1] 2 3 4 5 6 7 8
查看完整版本: OD下断 解密 石器时代8.0 客户端与服务器 通信封包,写给像我一样的新手[持续更新]