某试用版so保护压缩壳分析

发布时间 2023-08-30 23:12:12作者: 怎么可以吃突突

压缩壳并不一定会使so的体积变小,这一点和pc的压缩壳是相同的。

压缩壳实现思路

so被压缩后和之前分析的情况基本类似,这里主要看第一个PT_LOAD段的内存大小是远大于文件大小的。

对应的内存大小比文件大小多出来的这部分就是.bss了,就是第一个PT_LOAD段中最后的那段内存了。

这段内存保存了原始so文件所有的代码(包含.plt表)和数据,查看get_module_base函数,此函数是嵌入的代码构造的并不是原始的get_module_base函数,最后会跳转到B4038

查看B4038地址发现在bss段中,并且此地址到got表的偏移和原始get_module_base函数到got表的偏移一样。

调试so,在执行完.init.proc函数后发现B4038地址处对应的就是原始的get_module_base函数。其应该是在.init.proc中对压缩的代码和数据进行了解压还原。

最后梳理一下他的压缩壳实现思路

  1. 将所有的代码和数据进行压缩,对于导出函数其会生成嵌入代码并跳转到解压后真实的函数地址。
  2. 文件中原始代码和数据的位置都是置空的,对应的是一段.bss内存段,只有执行了.init.proc函数后其才会将压缩的代码和数据解压到内存中这块.bss内存段中。
  3. 因为内存中解压后的代码(包含.plt表)和数据与第二个PT_LOAD段中的.got表的相对偏移并没有变化,所以并不影响linker的重定位操作(不需要自己额外做重定位操作)。当然因为嵌入了代码,原始代码和数据的内存偏移发生了变化,因此加壳的时候相应的got表和重定位表(.rel.dyn,.rel.dyn)中的数据需要做一下修改。

脱壳思路

脱壳的话也很简单,因为执行了.init.proc函数之后所有的代码和数据都被解压缩还原了。直接从内存中dump下来,最后利用ida去patch 加壳后的文件。patch之后发现plt表被还原并且可以正常解析了。

字符串数据也被还原了

最后看一下B4038地址处的get_module_base函数也是可以正常解析的