某试用版so保护压缩壳分析
压缩壳并不一定会使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
中对压缩的代码和数据进行了解压还原。
最后梳理一下他的压缩壳实现思路
- 将所有的代码和数据进行压缩,对于导出函数其会生成嵌入代码并跳转到解压后真实的函数地址。
- 文件中原始代码和数据的位置都是置空的,对应的是一段
.bss
内存段,只有执行了.init.proc
函数后其才会将压缩的代码和数据解压到内存中这块.bss
内存段中。 - 因为内存中解压后的代码(包含.plt表)和数据与第二个
PT_LOAD
段中的.got
表的相对偏移并没有变化,所以并不影响linker的重定位操作(不需要自己额外做重定位操作)。当然因为嵌入了代码,原始代码和数据的内存偏移发生了变化,因此加壳的时候相应的got
表和重定位表(.rel.dyn,.rel.dyn
)中的数据需要做一下修改。
(某盾的是将原始so和壳so的got表和重定位表分开,linker程序在重定位时只会对壳so需要重定位的部分重定位,而原始so的重定位工作是由某盾自己在.init.array中完成的)
脱壳思路#
脱壳的话也很简单,因为执行了.init.proc
函数之后所有的代码和数据都被解压缩还原了。直接从内存中dump下来,最后利用ida去patch 加壳后的文件。patch之后发现plt
表被还原并且可以正常解析了。
字符串数据也被还原了
最后看一下B4038
地址处的get_module_base
函数也是可以正常解析的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】