请选择 进入手机版 | 继续访问电脑版
您好,欢迎访问! 登录

QQ登录

只需一步,快速开始

立即注册 切换到窄版
查看: 1155|回复: 2

[转载] Corona SDK的iphone游戏存档校验分析一例

[复制链接]

  离线 

25

主题

51

帖子

159

积分

版主

Rank: 7Rank: 7Rank: 7

积分
159
发表于 2014-6-9 13:06:32 | 显示全部楼层 |阅读模式
标 题: 【原创】Corona SDK的iphone游戏存档校验分析一例
作 者: 曾半仙
时 间: 2012-08-27,19:06:16
链 接: http://bbs.pediy.com/showthread.php?t=155193

近来ios上的游戏, 用非原生的SDK的那是越来越多.
长话短说, 前天就遇到一个, 叫做D.Switches, 塔防游戏, 里面内购主要是解锁我方可使用的人物, 解锁地图.
按照惯例, 打开iFunbox, 把Documents目录里面的文件都拷贝到机器上.
依次打开各种*.sqlite文件, 发现game.sqlite里面的summon表, 应该就是我们需要动手的地方.

地图先不管, 把这里的lock都给去了, 保存, 传到ipad上. 然后进入商店, 喵的一声, 弹出一个对话框, 提示summon信息损坏, 已经重新初始化.
看来这里的hex就应该是校验了, 数了下64字节, 应该是512bits, 512的有啥呢, 我第一时间想到了了sha系列, 搜了下应该是sha512吧?
顿时恶向胆边生, 把整个D.Switches.app拷贝到了电脑上, 用010Editor打开主文件D.Switches, 搜索summon字样, 满以为能找到关键点, 令人惊奇的是, ANSI, Unicode和UCS4格式都搜了, 居然没有.
对整个目录搜索, 不幸在resource.car里面发现了一些summon字样.
打开这个文件, 里面居然有残缺的sql语句, 看起来应该是什么脚本系的东西. 当然这个后缀肯定不会是symbian或者brew这类的, 不管, 经过查看文件头部, 感觉这个可以解.
把每个记录抄在纸上, 发现每条记录分为4部分, 再仔细观察, 文件名部分结尾的0不止是一个, 有时候是两个, 应该是为了对齐.

最后写了个文件模版验证, 证明猜测是对的.

接下来就是找了个以前做的类似结构的解包程序, 改了下代码, 把文件都给解出来了. 当然这个解包程序还有打包功能, 打包部分懒得一并修改了, 回头再说吧.
解出来的一堆.lu文件, 看起来很像是lua的东西啊, 搜了一堆lua的反编译工具都不认, 然后去看了bytecode的格式, 发现这玩意是Corona包过的, 头部加了三个字段, 删掉这三个字段, 保存为db_m.lu后, luadec提示版本是5.1的, 遂去找了luadec51, 运行居然要msvcr100d.dll我的天, debug运行库得vc安装包才有, 懒得解了, 拿vc2008编译了一个, 再反编译, 还是失败, 不过倒是有bgm_m.lu和info_m.lu可能是比较简单吧, 反出来几行. 既然反编译不行, 那就用-dis选项来反汇编吧.
反汇编出来的虚拟机汇编代码类似ARM的.
顺利找到了令人关心的位置:
代码:
  1. ; Function #19:
  2. ;
  3. ; Name:            
  4. ; Defined at line: 313
  5. ; #Upvalues:       2
  6. ; #Parameters:     2
  7. ; Is_vararg:       0
  8. ; Max Stack Size:  11

  9.   1 [-]: EQ        0 R1 K0      ; if R1 ~= nil then PC := 9
  10.   2 [-]: JMP       9            ; PC := 9
  11.   3 [-]: GETGLOBAL R2 K1        ; R2 := tostring
  12.   4 [-]: GETGLOBAL R3 K2        ; R3 := os
  13.   5 [-]: GETTABLE  R3 R3 K3     ; R3 := R3["time"]
  14.   6 [-]: CALL      R3 1 0       ; R3,... := R3()
  15.   7 [-]: CALL      R2 0 2       ; R2 := R2(R3,...) ; R2 = tostring(os["time"])
  16.   8 [-]: MOVE      R1 R2        ; R1 := R2
  17.   9 [-]: MOVE      R2 R1        ; R2 := R1
  18. 10 [-]: GETGLOBAL R3 K4        ; R3 := pairs
  19. 11 [-]: MOVE      R4 R0        ; R4 := R0
  20. 12 [-]: CALL      R3 2 4       ; R3,R4,R5 := R3(R4) ; R3,R4,R5 = pairs(arg1)
  21. 13 [-]: JMP       19           ; PC := 19
  22. 14 [-]: MOVE      R8 R2        ; R8 := R2
  23. 15 [-]: GETGLOBAL R9 K1        ; R9 := tostring
  24. 16 [-]: MOVE      R10 R7       ; R10 := R7
  25. 17 [-]: CALL      R9 2 2       ; R9 := R9(R10) R9 = tostring(R7)
  26. 18 [-]: CONCAT    R2 R8 R9     ; R2 := R8 .. R9
  27. 19 [-]: TFORLOOP  R3 2         ; R6,R7 :=  R3(R4,R5); if R6 ~= nil then begin PC = 14; R5 := R6 end
  28. 20 [-]: JMP       14           ; PC := 14
  29. 21 [-]: MOVE      R3 R2        ; R3 := R2
  30. 22 [-]: LOADK     R4 K5        ; R4 := "feel-.-dead-.-beef"
  31. 23 [-]: CONCAT    R2 R3 R4     ; R2 := R3 .. R4
  32. 24 [-]: GETUPVAL  R3 U0        ; R3 := U0
  33. 25 [-]: GETTABLE  R3 R3 K6     ; R3 := R3["hmac"]
  34. 26 [-]: GETUPVAL  R4 U0        ; R4 := U0
  35. 27 [-]: GETTABLE  R4 R4 K7     ; R4 := R4["sha512"]
  36. 28 [-]: MOVE      R5 R2        ; R5 := R2
  37. 29 [-]: GETUPVAL  R6 U1        ; R6 := U1
  38. 30 [-]: CALL      R3 4 2       ; R3 := R3(R4,R5,R6) r3 = hmac("sha512", R2+fell-.dead-.-beef)
  39. 31 [-]: MOVE      R4 R1        ; R4 := R1
  40. 32 [-]: RETURN    R3 3         ; return R3,R4
  41. 33 [-]: RETURN    R0 1         ; return
复制代码

我在函数调用的地方写了一些c伪代码, 那些用=而不是:=的就是. 话说刚才写Delphi的代码时候也不自觉的写错等号了... 然后把整个流程整理了一下
代码:
  1. if (arg2 == nil) {
  2.     // fill arg1 to current time?
  3.     arg2 = tostring(os["time"]);
  4. }
  5. R2 = arg2;
  6. R3, R4, R5 = paris(arg1);
  7. foreach(data in pairs) {
  8.   R2 += tostring(data);
  9. }
  10. hex = hmac("sha512", R2+"fell-.dead-.-beef");
  11. return hex
  12. return timestring
复制代码

然后我尝试了各种组合比如时间+181000,18truefalsefalsefalse都不能拼出正确的hash来, 这时候回想起一开始貌似还IDA分析过, 打开导入表果然看到一个CC_SHA512, 这里先卖个关子, 当时我不知道上面的lua代码还有玄机, 于是想尽办法想在ipad上调试这个应用.
XCode直接附加, 等一会儿程序就退出了, 不行. 启动/Developer/usr/bin下面的debugserver, 提示failed to get the task for process xxx, 也是不行, 不过这个好办, 创建个xml文件, 重新对debugserver签名, 加入get-task-allow和task_for_pid-allow就可以了, 不过这里签名后的就不可以复制回去/Developer/usr/bin目录了, 因为这里是只读的, 而且每次XCode都会验证这个文件. 那么我把它放进去根目录, 启动后, 狠可惜, XCode不认我手动监听的服务.

遂用IDA Pro连上, 结果暂停后就不能继续了, 我很不解啊, 然后用gdb客户端连了一把, 发现输什么命令都报包格式错误, 想着可能是debugserver并不严丝合缝的兼容gnu的东西, 于是在cydia上面下了一个gdb… 尼玛居然不是server好吧我ssh上去跳, 尼玛居然无法启动应用, 看说明对应用有编译选项要求, 一看就是3g的那个6410的armv6核心型号, 嚎吧卸载掉, 这次我灵机一动, 窝搜了XCode.app的Developer目录, 叫我找到了一个gdb. 连上去一看, continue, print都好用, 于是想着对应用下个硬件读写断点, 在他读lazy_symbol对应的地址时候尝试断下来看值, 结果…

结果continue以后, 提示硬件断点超过数量, 看起来不认. 然后我break CC_SHA512当然也不认, 加载了XCode下的LibSystem.B.dylib也不行, 提示载入了符号表, 再break还是提示符号表是空的.
顿时火了, 打开自己的app, xcode里面运行起来, 然后暂停, 查看内存, 输入了_CC_SHA512, 不认, 输入CC_SHA512, 得到地址0x3298F288, 于是转战gdb, 顺利断下来, 然后printf “%s”, $r0一看, 啧启动时候下载服务器的新闻信息啊. 顺利点开商店, 顺利弹出summon信息损坏提示… 哦等等不对啊, 不应该顺利, 应该断点断到才对, 好吧反复试了几次, 开始怀疑是不是两段sha256组合起来的? 回过头看看导入表, 除了SHA256和SHA384这类, 这时候发现还有一个CCHmac, 于是就如法炮制, 得到这些函数的值. 顺便还记下了_strcat_chk和__strncat_chk的值, 打算直接查看字符串相加的过程. 不过这时候还是感觉先看看CCHmac, 查看原型如下
CCHmac(kcchmac512, key, keylen, src, srclen, dest)
分别是r0<4>, r1, r2, r3, stack, stack
运行还没进商店就断下了, info register查看r0果然是4, 查看r1的key, 是防衛魔女の宴, 不知所谓啊, 应该是关卡检查? continue掉, 然后点商店, 果然断了.

查看r3, 哦哟,
13445069228100feel-.-dead-.-beef
看来summon表的加密是这样的, time, uid, sid, lock, four, tail
再看看key, 还是这个, 原来这个key是固定的, 就是hmac步骤的key. r2存储的长度是18, 应该是utf8
用x/18xb $r1打印出来
0xee7e530:  0xe9  0x98  0xb2  0xe8  0xa1  0x9b  0xe9  0xad
0xee7e538:  0x94  0xe5  0xa5  0xb3  0xe3  0x81  0xae  0xe5
0xee7e540:  0xae  0xb4

然后在HashCalc里面按照这个格式, 验算结果和未修改的game.sql的summon表的hex字段符合.

这个接下来就没什么悬念, 解锁了123456789 11,12,13这几个位置的魔女, 因为10和14~20的官方还没推出.
把补丁过的game.sql丢进游戏, 居然认了, 解锁成功, 人在头在!
回过头查看了启动时候的断点作用, 发现是检查user表.这个表是每条记录hash一次存放在hexmap表的.
同样也拦下了map表的计算方式.
134450690280001111111feel-.-dead-.-beef
time, uid, lock[10], tail
这里也是只能解锁到第七个地图因为后面三个还没做出来.

后记: 都是lua的错么, 如果他全部都是自行实现不调ios的函数, 那么可能还轻松些, 当然如果有方便的反编译工具, 直接把游戏改造的面目全非再打包回去也不是不可能的事情.
Corona SDK的游戏应该挺多的, 先把俺的解包工具和解析模版放上来, 回头有空说不定再做些lua解析工具.
话说这个fee1dead和deadbeef好像很眼熟啊, 十六进制的…
DWitchesKanxue.rar (592.11 KB, 下载次数: 6)
我不会告诉你,在游源签到是一种执着!
回复

使用道具 举报

  离线 

2

主题

19

帖子

29

积分

版主

Rank: 7Rank: 7Rank: 7

积分
29
发表于 2014-7-18 23:35:29 | 显示全部楼层
看不懂
回复

使用道具 举报

  离线 

0

主题

10

帖子

26

积分

游源小侠

Rank: 2Rank: 2

积分
26
发表于 2016-11-18 09:49:27 | 显示全部楼层
我来看看!谢谢












回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点统计|Archiver|手机版|小黑屋|游源网 ( 冀ICP备14006073号-1

Copyright 2013 最新最精彩-社区论坛 版权所有 discuz 模板All Rights Reserved.

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表