-
压缩加壳流程图
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled.png -
先把
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%201.pnglibexec.so
壳文件放到010 Editor 里面,搜索ascii string 如果查看到UPX或者AJM的字段,表示这里是压缩壳,但也有可能是其他字段标识 -
解密压缩流程
-
在linker中的调用so初始化方法的下一行断下来
IDA动态调试,在linker调用so方法下一行断下来,如下图蓝色部分,这时候so就是被解密的,dump出来即可
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%202.pngdump出来之后拿到new.so,但是发现里面有一些错误,放到IDA里面,有些部分是红的,这时候需要做如下操作:修改两个段和一个动态链接表的大小和偏移
-
壳结构,以12字节为分割
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%203.pngl_info
是壳的头p_info
是压缩壳的程序头b_info
是压缩前和压缩后信息下图
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%204.png.init_proc
是壳的解密程序,上面的0X1080C
是壳的起始点(l_info起始地址
) -
在
010 Edith
中操作打开
010 Edith
按F5,用ELF.bt文件进行解析,如果出现不了解析结果的话,按ALT+4-
打开原so(
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%205.pnglibexec.so
),如图点击goto,到0x1080C的位置 -
这时候以12字节为分割,顺序出现的就是
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%206.pngl_info
p_info
b_info
重要的是
b_info
,上图红色部分,34 01 00 00
也就是压缩前长度为 134,9C 00 00 00
是压缩后的长度 9C,因为是原so,所以用0x1080C + 9C = 0x108CC
-
下图中,程序头表中上面两个是loader段,第三个是动态链接库,这三个是需要修改的地方
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%207.png -
下图中解释如下
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%208.png-
Elf32_Off p_offset_FROM_FILE_BEGIN
指的是当前loader段未加载到内存时相对于文件开始位置的偏移 -
Elf32_Addr p_vaddr_VIRTUAL_ADDRESS
指的是当前段在内存中相对于文件开始位置的偏移 -
Elf32_Word p_filesz_SEGMENT_FILE_LENGTH
指的是当前段未加载到内存时的长度 -
Elf32_Word p_memsz_SEGMENT_RAM_LENGTH
指的是当前段在内存中的长度 - 我们看第一个段中的 3和4 是一样的,但是第二个loader段中的 3和4 是不一样的,是因为第二个段中有一些未初始化的数据,加载到内存后会初始化,所以内存中的长度会大于未加载内存时的长度
-
-
所以我们现在需要进行修改的就是两个load段和动态链接的大小和偏移
上面我们拿到的
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%209.png0x108CC
,在原so里面goto到位置,如下所示,红框部分表示第一个load段的大小AC 6C 04 00
,蓝色框表示load段的内容-
打开从内存中dump出来的so文件,找到第一个段,把文件大小和在内存中的大小全改成
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2010.png Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2011.pngAC 6C 04 00
第一个load段一般是代码,第二个是数据,所以加壳一般只压缩第一个load段,所以只需要改第一个load段的大小
-
但是第二个load段和动态链接需要改一下,需要把在内存中的地址
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2012.png Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2013.pngElf32_Addr p_vaddr_VIRTUAL_ADDRESS
给到 当前段相对于文件起始位置的偏移:Elf32_Off p_offset_FROM_FILE_BEGIN
,因为dump出来的so是一个新的so,基本只包含load段,所以跟原so的结构是不一样的,所以当它自己作为一个单独的so存在的时候,当前段相对于文件起始位置的偏移:Elf32_Off p_offset_FROM_FILE_BEGIN
这个位置需要改变,跟内存中的偏移一致即可
-
-
-
前面拿到的解密so主要用作静态分析,分析加壳流程
-
拿到解壳后加载到内存中解密后的dex
先过反调试,过完后,进
libdvm.so
,搜索 _Z12dexFileParsePKhji ,这个位置开始地方下段,即可拿到解密后的dex断下来后R0就是起始地址,R1就是大小
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2014.pngdump出来后如果是如下图,那么就是dexopt文件,这时候需要打开GDA工具,放进去跟原dex对比,如果差不多,那么就是dump失败,如果不一样,那么是有可能是成功
为什么说有可能,因为如果整体加载,那么就是成功,但是也有可能只有一部分数据,那么就是需要分析so,看里面的加密逻辑
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2015.png然后Odex2Dex转成dex导出,完成
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2016.png但是需要注意:在 _Z12dexFileParsePKhji 进行dump的时候,有可能系统的一些代码也会走这里,所以需要注意,如果是个apk的dex,基本在10万字节(
0x186A0
)以上,太小可能就是系统的dump的时候,需要等这个结束,如果几M那就,是需要些时间的,要不然会出现文件不完整,出错的情况
Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2017.png
-
-
网友评论