UPX为APK加壳中.init段相关问题

感谢UPX的维护者们.最近在读UPX源码,目的是为.so文件加壳玩.
在此之前阅读了大部分我能搜到的中文相关内容.很多语焉不详,所以综合了一下,编译出了Linux下的版本.
本文简单说明了以下内容:

  • 为什么一些.so在新版编译的UPX中压缩无法通过.
  • .init段的一些简单探索

编译UPX

你可以参考这里,step by step.Android NDK UPX加固作者:fallrain

无法编译的一点情况

UPX最新版d9e7cb4b5485用VS编译会报错-无法识别的导出符号.另外还有一些问题,动态结构体数组不能直接声明.需要动态申请.这都是小问题,根据报错信息很容易解决.真正的关键在于对于加壳.so动态链接库会提示无法识别的文件格式.当前我还没有在windows平台编译成功最新版.

编译的小科普

源代码如果跨平台,通过不同的编译选项可以编译成不同平台的程序.
功能不变.

无法加壳

我编译成功UPX的Linux版后,发现加壳Android上的.so动态链接库文件会报“未知文件格式”.在使用一定数量的不同类型.so后.认为要么UPX压缩.so的传言为虚,要么我们的.so文件统统有问题..init多篇网文反复提到UPX只能压缩具有该”区段”的内容.

UPX区分格式的方法

压缩可执行程序肯定不能像压缩软件那样直接一套通用算法就能搞定,得针对不同格式做出相应安排,UPX是如何区分文件格式的呢?
它是确定大致可执行文件类型,然后挨个格式试验canPack,一旦发现格式不对,不符合此种格式的标准就抛异常.
最后一个canPack也不符合就告诉大家这个文件”未知文件格式”.

听说必须要有.init段才能运行时解压缩,手头的.so文件都没有.init段.那是不是随便找个段添加进去就可以了呢?还是找个段改个名字?我们调试一下,它是在什么时候pass我们的.

问题锁定

UPX支持的格式果然很多,然后各种不好找.最终找到.so文件判断过程的过程在p_lx_elf.cpp

if (/*jni_onload_sym ||*/ elf_find_dynamic(Elf32_Dyn::DT_INIT)) {
......

DT_INIT不存在就会跳过.DT_INIT是什么东东?查看ELF格式的解析,好像是北大软件学院做的.里面有一句说:dynamic区段中标志为0xC的内容为init,即后面的值指向初始化地址.

经过验证:如果你的.so文件有_init段,区段dynamic中就会有一个标志等于0xC,其地址指向初始化区段文件偏移地址.
另外_init并非区段,只是一个导出函数.NDK会生成对应的区段并融合在某个大区段中,所以你从区段表看不到它.至于它的作用如何网文介绍很多,不再赘述.

结语

最终我完成了它的Linux版编译和.so加壳.

书写2016年1月28日 21:59:07
修订2016年2月4日 23:39:40

你可能感兴趣的:(UPX为APK加壳中.init段相关问题)