您的位置:首页 > 移动开发 > Android开发

UPX对Android上ELF加壳使用过程中的若干问题总结

2016-07-12 16:08 1631 查看
1. UPX中使用的压缩算法有三种,最早是UCL,然后加入了NRV,3.91版本又加入了LZMA。按照UPX源码中的文档来说,UCL压缩效率是相对较低的,但是好处是OpenSource的,NRV效率较高,但是不开源,而LZMA算是这三种中压缩效率最高的了,在7Zip中就是使用的这种压缩算法。但是从UCL的官网来看,UCL是对NRV中的一些算法的重实现,这样来说的话应该压缩效率更高才对。这里不纠结这个了,具体信息见相关链接:http://www.redhat.com/archives/blinux-list/2003-September/msg00030.html

2. Packed programs will be byte-identical to the original after uncompression. UPX是安全的、没有数据损失的压缩工具。

3. UPX对ELF文件加壳要求ELF文件必须有_init导出函数,否则会报"UnknownExecutableFormatException"错误,问题定位到UPX源码的p_lx_elf.cpp文件的canPack()函数中:

[cpp] view
plain copy

 





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

......  

也就是说Dynamic段中必须有类型为DT_INIT的字段,它指向ELF文件初始化函数在文件中的偏移。一般的so都不会有这个函数,要加上很简单,只要在你的代码中加入下面代码:

[cpp] view
plain copy

 





#ifdef __cplusplus  

extern "C" {  

#endif  

  

void _init(void){}  

  

#ifdef __cplusplus  

}  

#endif  

下面内容部分摘录自:http://www.cnblogs.com/fishou/p/4202061.html

5、相关问题总结

5.1、编译UPX出现“cannot find -lz”错误。
         分析:原因是链接器LD没有找到编译出来的zlib库libz.so或libz.a。
         解决方法:将libz.so或libz.a拷贝到系统默认的动态链接库路径下,比如/usr/lib,/usr/lib64      等。
5.2、编译UPX出现“CantPackException: DT_TEXTREL found; re-compile with -fPIC”错误。
         分析:这是早期NDK版本的BUG。
         解决方案:使用NDK9或以上的版本
5.3、编译UPX出现“NotCompressibleException”错误。
         分析:UPX对被加壳的二进制文件有最小限制,太小的文件将无法被加壳。
         解决方案:在native代码中定义足够大的数据变量,使得编译出来的二进制文件容易达          到UPX的要求(参考《加固步骤》之《修改native代码》章节)。
5.4、编译UPX出现“UnknownExecutableFormatException”错误。
         分析:被加壳的二进制文件必须存在init段,否则UPX将无法脱壳还原原始代码。
         解决方案:在native代码中定义_init()方法,需要注意C和C++的区别(参考《加固步    骤》之《修改native代码》章节)。
         备注:查看二进制文件是否存在init段的命令:readelf –dynamic xxx.so,如下图:
         


5.5、使用UPX加壳的SO,在eclipse中启动Android程序时出现”Fatal signal…”错误,如图:
         


         分析:此错误是因为UPX解析某些特殊字符处理不当导致的,该BUG已经有人提交UPX        官方解决,但是当前官方正式发布的正式版本(V3.91)并没有fix该问题,而是在未正      式发布的V3.92才解决了该问题,因此本文档使用源代码版本为V3.92而非V3.91。
         解决方案:下载使用V3.92源码,下载入口请参考《创建加固环境》章节。
5.6、为何删除UPX源码中的软件信息,以及如何定位查找这些信息。
         分析:UPX对文件进行加壳时会把这些信息写入壳内,通过静态反汇编可查看到这些壳信息,进而寻找对应的脱壳机进行脱壳,使得攻击难度降低。
         解决方案:在UPX源码中删除这些信息,并重新编译,步骤如下:
         5.6.1、使用原始版本对文件进行加壳。
         5.5.2、使用IDA反汇编加壳文件,在反汇编文件的上下文中查找UPX壳特征字符串,    如下图所示:
         


         5.5.3、在UPX源码中查找这些特征字符串(建议使用Search and Replace),并一一删除,      如下图:
         


         5.5.4、重新编译UPX(参考“创建加固环境”章节)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android UPX ELF加壳