360加固保ELF脱壳总结

Intro

360加固保可以针对ELF和DEX进行保护,360某些产品的ELF文件基本都使用了自家产品进行加壳,而这些正是我们感兴趣的东西。由于文件比较多,为了能够快速的拿到Payload,最近稍微总结了一些较为通用的方法。

大体流程

壳整个流程的目的是解密核心ELF文件到内存中,关键解密的地方有3处,均使用RC4。

  • INIT_ARRAY:壳填充了结构,Linker在so加载完毕后会调用这个回调。这个函数被重命名为__gnu_armfini_26。其功能是进行一些反调试,并且解密JNI_Onload的代码。
  • JNI_Onload:JNI_OnLoad负责解密核心ELF并加载。此时解密的ELF文件的入口代码没有解密。
  • __gnu_Unwind_0:最后的步骤,解密核心ELF的入口代码。在不同的版本中解密入口代码的地方有所不同,一般的产品中在壳调用原始JNI_OnLoad之前会进行解密,360的某些产品则会通过Hook库函数的方式,在调用库函数之前再进行解密。

关键函数

外壳大部分函数名被修改成了伪库函数的名字,如图:

通过调试得到了一些关键函数的功能,对这些函数下断点可以快速的脱壳:

__gnu_arm_message rc4_decode
__arm_aeabi_6 rc4_init
__gnu_Unwind_0  解密入口

脱壳流程

  1. 找到__gnu_armfini_26函数。修改入口代码为FE FF FF EA,即死循环;
  2. 加载so并使用调试器附加,将原始代码修改回去,一般是PatchDword(GetRegValue(“PC”), 0xe92d0001)
  3. __gnu_arm_message进行下断,然后开始跑;
  4. 第一次是JNI_Onload的解密,第二次是ELF文件的解密,记录下解密数据保存的地址和大小,RC4解密完之后还会有些处理,此时可以先不Dump;
  5. 第三次略有不同,如果是解密一个8字节的数据,则需要手工设置PC为__gnu_Unwind_0。如果大于8字节,则是在解密入口代码。解密完成后Dump出Step 4中的数据以及入口代码。
  6. 把入口代码写回ELF中。ELF头部magic可能被修改为lfx,这种情况把lfx替换为ELF即可。

360加固保ELF脱壳总结》有5个想法

  1. Pingback引用通告: 360安卓壳反调试 | corner

  2. Pingback引用通告: 加固保动态脱壳学习

  3. Pingback引用通告: 360安卓壳反调试 - lbchs-团队

  4. Pingback引用通告: 动态脱壳学习 - lbchs-团队

  5. Pingback引用通告: 一周信息安全干货分享(第19期) – Guge's blog

发表评论