美文网首页
压缩壳流程与处理

压缩壳流程与处理

作者: Alanone0x0 | 来源:发表于2020-06-25 22:01 被阅读0次
    • 压缩加壳流程图

      Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled.png
    • 先把 libexec.so 壳文件放到010 Editor 里面,搜索ascii string 如果查看到UPX或者AJM的字段,表示这里是压缩壳,但也有可能是其他字段标识

      Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%201.png
    • 解密压缩流程

      • 在linker中的调用so初始化方法的下一行断下来

        IDA动态调试,在linker调用so方法下一行断下来,如下图蓝色部分,这时候so就是被解密的,dump出来即可

        Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%202.png

        dump出来之后拿到new.so,但是发现里面有一些错误,放到IDA里面,有些部分是红的,这时候需要做如下操作:修改两个段和一个动态链接表的大小和偏移

        • 壳结构,以12字节为分割

          Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%203.png

          l_info 是壳的头

          p_info 是压缩壳的程序头

          b_info 是压缩前和压缩后信息

          下图 .init_proc 是壳的解密程序,上面的 0X1080C 是壳的起始点(l_info起始地址)

          Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%204.png
        • 010 Edith 中操作

          打开 010 Edith 按F5,用ELF.bt文件进行解析,如果出现不了解析结果的话,按ALT+4

          • 打开原so(libexec.so),如图点击goto,到0x1080C的位置

            Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%205.png
          • 这时候以12字节为分割,顺序出现的就是 l_info p_info b_info

            Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%206.png

          重要的是 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
            1. Elf32_Off p_offset_FROM_FILE_BEGIN 指的是当前loader段未加载到内存时相对于文件开始位置的偏移
            2. Elf32_Addr p_vaddr_VIRTUAL_ADDRESS 指的是当前段在内存中相对于文件开始位置的偏移
            3. Elf32_Word p_filesz_SEGMENT_FILE_LENGTH 指的是当前段未加载到内存时的长度
            4. Elf32_Word p_memsz_SEGMENT_RAM_LENGTH 指的是当前段在内存中的长度
            5. 我们看第一个段中的 3和4 是一样的,但是第二个loader段中的 3和4 是不一样的,是因为第二个段中有一些未初始化的数据,加载到内存后会初始化,所以内存中的长度会大于未加载内存时的长度
          • 所以我们现在需要进行修改的就是两个load段和动态链接的大小和偏移

            上面我们拿到的 0x108CC ,在原so里面goto到位置,如下所示,红框部分表示第一个load段的大小 AC 6C 04 00,蓝色框表示load段的内容

            Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%209.png
            • 打开从内存中dump出来的so文件,找到第一个段,把文件大小和在内存中的大小全改成AC 6C 04 00

              Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2010.png Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2011.png

            第一个load段一般是代码,第二个是数据,所以加壳一般只压缩第一个load段,所以只需要改第一个load段的大小

            • 但是第二个load段和动态链接需要改一下,需要把在内存中的地址Elf32_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 这个位置需要改变,跟内存中的偏移一致即可

              Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2012.png Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2013.png
        • 前面拿到的解密so主要用作静态分析,分析加壳流程

        • 拿到解壳后加载到内存中解密后的dex

          先过反调试,过完后,进 libdvm.so ,搜索 _Z12dexFileParsePKhji ,这个位置开始地方下段,即可拿到解密后的dex

          断下来后R0就是起始地址,R1就是大小

          Untitled%20b87c2790bd8e44b1b1300d93e1fa51b7/Untitled%2014.png

          dump出来后如果是如下图,那么就是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

    相关文章

      网友评论

          本文标题:压缩壳流程与处理

          本文链接:https://www.haomeiwen.com/subject/tsyefktx.html