好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 shyoshyo 于 2021-4-18 12:28 编辑
点开发现是个完整的 unity 工程,看资源文件,unity 版本 5.5.0f3,基于 mono 非 il2cpp,Assembly-Csharp 做过处理。smali 没啥干货,lib 是一个魔改过的 unity + mono 和 libsec2021.so。
重新签名后,启动会提示“apk 损坏”,目测是 libsec2021.so 的功能。
IDA 直接调试会报错“检测到调试器”退出,但是将 ida 的 server 文件名换一个随机的,并换一个端口后,就不会再报错了,推测 libsec2021 只是看了看文件名和/或端口
先逆向 libsec2021,字符串被混淆过,很难从字符串推出有效信息
但是其中有一个 sub_1F120 函数很可疑,疑似是字符串索引和解密的函数,有大量的交叉引用,且有一个参数,不同的引用地方数字不一样
上动态调试,发现确实是上述功能,返回值 r0 指向解密后的明文字符串
在这个函数上下断,继续观察,发现失败之前他会解密 “hack detected”,在他解密这个字符串的时候可能正好就是被查到问题的地方
返回到它的上级函数,发现是一个 switch 结构,按错误编号输出文字,并最后 SIGKILL 自己退出程序。因此这个函数就是个报错退出的函数。
他的上级函数是一个简单包装,再上级有五处调用(每次调用先调了个函数获取他的指针)
这五次调用都在 if 判断里面,if 中的条件应该就是判断逻辑,直接把那些 if 对应的跳转条件改掉,劫持指令流就能去除 libsec2021 的保护
$ cmp -l libsec2021.original.so libsec2021.patch.so | gawk '{printf "%08X %02X %02X\n", $1, strtonum(0$2), strtonum(0$3)}'
0001CFA8 0A EA
0001D068 0A EA
00020710 0A EA
0002091C 0A EA
00020934 0A EA
00020A50 0A EA
至此所有的防护都被解除了。
下面分析游戏逻辑。首先是游戏逻辑获取。
通过替换 Assembly-Csharp 的文件内容为随机内容,发现不影响游戏运行,因此推测游戏 apk 中的 Assembly-Csharp 文件只是一个无用的障眼道具,真正的游戏逻辑在其他地方。
之前负责字符串解密和索引的 sub_1F120 函数也解出过 Assembly-Csharp,手工污点分析一下发现后面有个地方在算 Assembly-Csharp 文件的 hash 值,在计算 hash 的函数上停下:
发现在算hash 前,此时 Assembly-Csharp 文件已经解压成功,里面有 unity 资源文件中所需的各脚本名称。使用 IDA-Python dump 该文件
Python>data = idaapi.dbg_read_memory(0x95E20000, 0x2800)
Python>fp = open('/tmp/Assembly-CSharp.dll', 'wb')
Python>fp.write(data)
Python>fp.close()
此时游戏逻辑已经获取成功。
下面开始分析该逻辑。
游戏逻辑只有 2.8K 并不算复杂,点开发现有个 restart button,这个按钮应该是在失败了的时候才显示的,因此失败的判定就在他的引用中
顺着引用很容易就找到相关的判断逻辑
OnTriggerEnter2D 就是碰到硬币和碰到激光的不同判定,直接魔改它去除碰到激光的判定:
至此,使用该游戏逻辑应该就不会失败了。
最后需要把这个游戏逻辑打包回原来的 apk 包。直接的思路是分析 libsec2021 是怎么解压的,然后重新给他加压回去,但这样太费时间。由于unity 的资源文件基本完整,因此直接将 libsec2021 和魔改后的 libunity libmono 换成 unity 官方原版的文件,并重新打包签名。经测试,此时的游戏包是可用的。
比赛文档里没有提及不允许去除 libsec2021 运行环境,因此这理论上是一个符合要求的答案。 |
免费评分
-
查看全部评分
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|