首先分析il2cpp.so 被加密,在依赖库中存在一个非公有库的so引发了怀疑,
libtprt.so ,可能是用来解密的,既然会解密,那么一定会调用 mprotect 修改内存属性。
![image-20200921120219464](http://pareto.fun/wp-content/uploads/2020/09/image-20200921120219464.png)
再看libtprt.so 的dynamic segment
![image-20200921132154879](http://pareto.fun/wp-content/uploads/2020/09/image-20200921132154879.png)
有个可疑的段.tptext 。
在so中找mprotect函数。找到以下的函数,在对tptext段进行解密。刚好调用该函数过程出现在init_array ,基本确定是在解密。
![image-20200921131843045](http://pareto.fun/wp-content/uploads/2020/09/image-20200921131843045.png)
在IDA使用脚本对so的tptext段进行解密。
import idc
def xor(begin_addr , len):
retInt=0
for i in range(0,0xc78):
curAd = begin_addr + i
curByte = idc.Byte(curAd)
idc.PatchByte(curAd , curByte^0xb8)
il2cpp size太大,为了分析方便换成另一个依赖tprt.so的so“GameCore.so” , 先看
![image-20200921144714606](http://pareto.fun/wp-content/uploads/2020/09/image-20200921144714606.png)
libGameCore.so 的init_proc , 通过偏移定位到待调用函数地址。0x2449B58.
![](http://pareto.fun/wp-content/uploads/2020/09/image-20200918172247086.png)
负责解密text segment。发现使用了g_tprt_pfn_array ,追踪发现这个变量为tprt.so 的导出变量。
![](http://pareto.fun/wp-content/uploads/2020/09/image-20200921152709586.png)
g_tprt_pfn_array 存放了连续函数的函数。
![image-20200921150654663](http://pareto.fun/wp-content/uploads/2020/09/image-20200921150654663.png)
调用decry_so(”.text”,0,3) 来解密,加密方法很简单同样也是异或运算,但是但是代码段可能很大,为了提高效率做了间断加密,每隔4k做一次加密。
比如libil2cpp.so 加密了text section 和rodata section ,针对text section ,首先是获取text段起始地址_start,然后加密的第一个空间大小则为 0x1000 + (0x1000 – _start) ,之后便 每4k做一次加密,直到text结尾。
rodata section则做完全加密。
http://kmanong.top/kmn/qxw/form/article?id=17265&cate=126
0 条评论