360加固Dump

360主体逻辑部分采用的VMP虚拟机的模式,在case:29和case:33是其函数调用点,在其调用点下断点,监视其函数调用过程。


0x1.反调试

  • 1. 时间反调试
    逻辑流程: 通过time()获取时间计算时间差值
    反反调试: 两次置函数返回值为0
  • 2. rtld_db_dlactivity
    原理分析:
    如果程序在被调试的状态下, /system/bin/linker中会注册此函数
    逻辑流程:

    1. 读取/proc/self/maps 获取 /system/bin/linker基址。
    2. 读取/system/bin/linker中e_phnum和e_phoff值。
    3. 遍历ProgramHeader ,读取 PT_ DYNAMIC中的p_ vaddr,定位到dynamic_ LinkTable。
    4. 遍历Table,读取DT_STRTAB和DT_SYMTAB。(目的为遍历DT_STRTAB)
    5. 符号表找到函数rtld_db_dlactivity 对应的模块中的地址

    反反调试:
    置查找出函数的地址为0

  • 3.TracerPid
    逻辑流程
    读取/proc/self/status,查看TracerPid是否不为0
    反反调试:
    置strtol返回值为0
  • 4.检测Android_server端口
    逻辑流程
    读取/proc/net/tcp,遍历查找是否有23946端口
    反反调试
    修改匹配字符串为23947
  • 5.反某些APP

0x2.加载解密Dex的SO

逻辑流程:
- 通过dlsys获取到uncompress基址,解压缩后手动填充soInfo手动加载SO

int uncompress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen);

  • 获取加载SO的makeKey和JNI_ONLOAD地址
  • 调用 JNI_ONLOAD函数

DumpSO:
- 执行完uncompress后,通过dest和destLen用 idc dump后修复

0x3.解密Dex并加载

逻辑流程:

  • 解密Dex数据
    • 判断VM版本
    • 通过/proc/self/maps获取Dex基址,并判断Dex头

  • 通过dataoff + datasize定位到Dex尾部, 对齐区块,判断头部,确定大小
  • 解密头,每一个段头部都是pk ,后面两个DWORD是后面两个字符串的长度,例如:APPKEY=f9810dd4e677d8bc,activityName = get1t.crackme.MainAcitvity

  • Check刚刚获取的值,fileCheck,sigCheck,report,reason

  • 解密真正的Dex,其中参数1是加密的Dex,参数2是长度,参数3是解密的Dex,在这里Dump就是完整的Dex。(OnCreate被Native)

    v5 = sub_EC48((int *)(v29 + 4 + v7), v30, (int *)&v98);

  • 设置appName,appEntry,activityName,mEntryActivity。

  • 根据不同的系统,注册Native函数
  • 调用OnCreate函数

0xN.分析OnCreate方法

comments powered by Disqus