zoukankan      html  css  js  c++  java
  • 百度脱壳的一点尝试--人肉修复

    前言

    近期把研究dex的脱壳,顺便又是再次熟悉了一下dex的标准格式以及dex被解析后在内存中所存在的格式。自己上官网加了一个壳子,发现跑不起来。于是求助几个基友,最后样本是海总给的apk,非常全面,带有Activity、Application、BroadcastReceiver、ContentProvider、以及Service。

    0x1 加壳前后对照

    这里写图片描写叙述

    加固后的文件列表变化:
    新增一个so文件以及一个jar包:
    libbaiduprotect.so
    baiduprotect.jar
    改动:
    META-INF目录
    AndroidManifest.xml
    Classes.dex

    0x2 IDA尝试

    用IDA来远程调试,直接跑挂了。看来有反调试。
    从壳入口Java层找到例如以下语句:

     static {
            if(!Debug.isDebuggerConnected()) {
                String v0 = Build.CPU_ABI;
                if(v0 != null && (v0.startsWith("x86"))) {
                    StubApplication.loadX86Library();
                    return;
                }
    
                System.loadLibrary("baiduprotect");
            }
    }

    把第一个if删掉之后,程序顺利的载入了baiduprotect.so。顺利的进入了壳的领空。只是不知道是程序在so里面做了完整性校验还是再次检測了debuggerconnected,每次跑都是进入了一个死循环后,然后程序就跑挂了。跑了非常多次都是难以逃出那个trap。这个时候就比較纠结了。既然反调试过不去,想起360的壳子用DD也能够脱的非常完美。那就换个方式试试。

    0x3 DD大法

    dd if=/proc/PID/mem of=XX skip=0 ibs=1 count=LENGTH 
    skip改成偏移地址
    偏移地址 
    cat /proc/pid/maps

    1.这里首先要感谢下wbyang博士猛男,这个DD大法也是上次挑战赛之后向他学来的。程序跑起来,把内存都dump出来,大概是100多mb的东西。找几个字符串,然后向上翻。找到dex文件的头。发现是被抹掉的。如图:
    这里写图片描写叙述
    前面红色框的8字节是odex的magic头。后面的0x70字节是dex的头。除了一些size和编码标志没有被抹掉。其它的已经是面目全非,修复后例如以下:
    这里写图片描写叙述
    这下把dex文件抠出来了。
    2.把dex反编译成smali文件
    出现例如以下错误:

    这里写图片描写叙述

    重复检查后发现了例如以下是CodeItems以下的offset错误:
    这里写图片描写叙述
    Dex的文件大小才0xA30DC。而offset指向了外面的东西。

    当然是无法解析的。这里我是有一个问题的,第三个偏移,这个0x0220E8E8,指向的是前面的内存。这是怎样做到的?我个人觉得是百度是在载入完毕之后有益改成这个数字的。若有错误。还望前辈不吝指正。


    把这三个offset 都改成0就能够达到反编译成功,当然是在缺三个DataItem的前提下编译成功的。找到被抹掉的DataItem地址:
    这里写图片描写叙述

    以上三处为0的区域就是加固前的dex代码所存放的位置。


    因此,如果我们能从dex的结构逆推出该三处的数据而且用应该的数据填充这块。静态就能把这个壳子搞定了。


    3.怎样修复

    360壳子要修复的数据为DataclassDef中的offset就可以。而百度的更为麻烦一些,不仅它的偏移须要修复一下,更为麻烦的是DataItem的数据也要修复。这个难度就更大了。


    总的修复原则是导出函数表,然后按顺序来修复dex中被抹掉的数据,例如以下:
    这里写图片描写叙述

    逆计算出函数的uleb128的索引值、常见函数的一些accessflags、以及指向函数内容的offset。
    修复后例如以下:
    这里写图片描写叙述

    修复的过程比較繁琐。有时候还须要自己尝试几次才知道size是多少。所以叫它人肉修复好了。
    修复好了反编译如图
    这里写图片描写叙述

    发现onCreate函数没有代码,检查了一下,又有新发现!


    这里写图片描写叙述

    原来是oncreate中的insns[]也被抹掉了。

    这个算是最主要的单位了。功力太弱。无法逆推。

    最后总结下。百度的壳子须要修复dex头中的magic、签名值、校验值以及各个offset。还须要修复Dataclassoffset,以及Dataclass和opcodes。前两者是能够静态修复的,最后的仅仅能动态调试寻找了。百度壳子新增了一个oncreate001的函数,调用的壳中的d方法以及e方法,推測是d方法填充了insns[]解密数据,然后e方法为清洁工,抹去正确的数据或者是改成一些非法数据。此时就泪奔了。。

    (心里暗想:百度好猥琐啊。。

    。)

    因为过去几天了,再次写文章又又一次做了一遍,把各种东西找好。写完花了将近三个小时,累觉不爱了。

    。。

    T T

    因为水平有限,难免有错误。还望各位看官不吝指正。


    2015.3.24 By Ericky

  • 相关阅读:
    java web 学习 --第七天(Java三级考试)
    java web 学习 --第六天(Java三级考试)
    java web 学习 --第五天(Java三级考试)
    java web 学习 --第四天(Java三级考试)
    java web 学习 --第三天(Java三级考试)
    java web 学习 --第二天(Java三级考试)
    java web 学习 --第一天(Java三级考试)
    shell 监控局域网的主机是否up
    How to call getClass() from a static method in Java?
    不知道数据库中表的列类型的前提下,使用JDBC正确的取出数据
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/7069973.html
Copyright © 2011-2022 走看看