吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 7002|回复: 16
收起左侧

[Android 原创] 关于某游戏的混淆符号解析

[复制链接]
wmsuper 发表于 2017-8-20 14:50
0x01 前言
函数符号对于逆向分析来说是十分重要,如果符号被混淆将会加大分析的难度,这次遇到的是一个cocos2dx的游戏,关键的函数名被混淆。
1.png

0x02 分析
  本来不打算解密混淆的函数名,但是在分析过程中发现一个解密关键字符串的函数。
4.png

它用的是循环异或来解密加密后的字符串,会不会混淆的函数名也使用了这种加密方式?可能性非常大。
3.png
但是用这个函数的秘钥去解密函数名解出来的是乱码,秘钥可能是不同的,那么如何获取密码呢?网上的方式是基于文本字符统计的方式去猜所使用的循环异或秘钥,
但是有没有比较好的方法呢?

0x03 猜秘钥
在浏览函数名我发现一个比较有意思的类,它有一个Encode的函数,那会不会有一个Decode函数呢?
看下图那个框起来的函数,刚好6字节,参数也对得上,或许就是我们要找的函数,因为是循环异或,所以可以通过明文和密文直接算出秘钥
秘钥:0702050003,通过该秘钥去解密其他字符串,都能解密成功,所以猜测是正确的。{:1_912:}
2.png

0x04 批量重命名
可以方便的通过IDAPython去重命名类似“_ZN26BAGA516B7669616B675765607312BAGA6B676374Ev”的c++修饰的函数名。
主要思路是获取所有导出函数名,再通过相应的解析规则去替换函数名称,代码如下:
[Python] 纯文本查看 复制代码
import idaapi
import idautils
import idc
import binascii
import string
#解密字符串
def dec_name(str):
        str
        key=binascii.a2b_hex('0702050003')
        keylen=len(key)
        str=binascii.a2b_hex(str)
        strlen=len(str)
        de_str=''
        for i in range(0,strlen):
                de_str+=chr((ord(key[i%keylen])^ord(str[i]))&0xff)
        return de_str
#获取长度前缀
def getint(str):
        pos=0
        for i in range(0,len(str)):
                if(str[0:i+1].isdigit()):
                        pos=i+1
                else:
                        if pos>0:
                                return pos
        return 0
#获取改名后的符号
def getsysm(str):
        rep_str=[]
        if(str[0:3]=='_ZN'):
                i=3
                while i<len(str):
                        pos=getint(str[i:])
                        if pos<=0:
                                break;
                        pre_len=str[i:i+pos]
                        int_len=string.atoi(pre_len)
                        ba_str=str[i+pos:i+pos+int_len]
                        if(ba_str[0:4]=='BAGA'):
                                dec_str=dec_name(ba_str[4:])
                        else:
                                i+=int_len+len(pre_len)
                                continue
                        
                        rep_str+=[[pre_len+ba_str,"%d%s"%(len(dec_str),dec_str)]]
                        i+=int_len+len(pre_len)
                for i in rep_str:
                        str=str.replace(i[0],i[1])   #替换相应的字符串
                return str
                        
        else:
                return None
funlist=list(idautils.Entries())   #获取导出函数
for i in funlist:
        str=getsysm(i[3])
        if str:
                idc.MakeNameEx(i[2],str,idc.SN_NOWARN)

跑完脚本后,基本上重命名完成了,发送和接受,加密和解密的地方都可以看出来,一般不用分析加解密函数,直接call发包函数就能发包,因为用于连接服务器的对象的this指针一般是不变的(单例模式),
如何获取上述指针能?简单的打个hook就能获取了。
5.png

0x05 结束
如果碰上那种符号被混淆的很厉害或者根本没符号的那应该怎么办?发送函数最终还是调用send(tcp ),可以从send入手,一直往上,但是很可能跟不到发送的地方。
因为一般封装的用于处理发送和接受的消息的类,都不是直接发的,而是插入一个队列或者类似队列的地方,由update函数进行发送,这种异步的发送方式可以从队列下手
就能发现sendMsg的函数了。

免费评分

参与人数 9威望 +2 吾爱币 +20 热心值 +8 收起 理由
Intro + 1 我很赞同!
qtfreet00 + 2 + 12 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
飘荡的心 + 1 + 1 谢谢@Thanks!
秋水 + 1 + 1 干货
Rody + 1 我很赞同!
gunxsword + 1 + 1 谢谢@Thanks!
xiaofengzi + 1 + 1 用心讨论,共获提升!
小飞虫 + 2 + 1 鼓励转贴优秀软件安全工具和文档!
caddy + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

caddy 发表于 2017-8-20 15:15
脚本很赞。
煦涵 发表于 2017-8-20 15:19
tomemouse 发表于 2017-8-20 16:37
mayl8822 发表于 2017-8-20 16:57
感谢分享
可坏 发表于 2017-8-20 17:27
脚本超级赞
xiaofengzi 发表于 2017-8-20 18:36
其实混淆的研究还是会较多的,记得以前在看雪上看到12种以上的混淆情况
艾莉希雅 发表于 2017-8-20 19:28
混淆强于加壳233333
wentwent 发表于 2017-8-20 20:50
围观 学习
l145191039l 发表于 2017-8-21 21:41
这是啥游戏. 小白白哦是俺不懂
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 13:28

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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