• 网站刚刚上线,难免有不足的地方,敬请谅解!欢迎提出宝贵意见!

  •    3年前 (2015-06-14)  Android应用开发 安卓应用 |   抢沙发  118 
    文章评分 0 次,平均分 0.0

    上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客。接下来我们将介绍另一种防止apk反编译的技术-运行时修改字节码。这种方法是在工作中在实现app wrapping时,看到国外的一篇关于android 安全的介绍实现的并且独创。下面我们来介绍一下这种方法。

     

    我们知道apk生成后所有的java生成的class文件都被dx命令整合成了一个classes.dex文件,当apk运行时dalvik虚拟机加载classes.dex文件并且用dexopt命令进行进一步的优化成odex文件。我们的方法就是在这个过程中修改dalvik指令来达到我们的目的。

     

    一、dex文件格式

    dex的文件格式通常有7个主要部分和数据區组成,格式如下:

    android apk 防止反编译技术第二篇-运行时修改Dalvik指令

     

    header部分记录了主要的信息其他的部分只是索引,索引的内容存在data区域

     

    Header部分结构如下:

     

    字段名称 偏移值 长度 描述
    magic 0x0 8 'Magic'值,即魔数字段,格式如”dex/n035/0”,其中的035表示结构的版本。
    checksum 0x8 4 校验码。
    signature 0xC 20 SHA-1签名。
    file_size 0x20 4 Dex文件的总长度。
    header_size 0x24 4 文件头长度,009版本=0x5C,035版本=0x70
    endian_tag 0x28 4 标识字节顺序的常量,根据这个常量可以判断文件是否交换了字节顺序,缺省情况下=0x78563412
    link_size 0x2C 4 连接段的大小,如果为0就表示是静态连接。
    link_off 0x30 4 连接段的开始位置,从本文件头开始算起。如果连接段的大小为0,这里也是0
    map_off 0x34 4 map数据基地址。
    string_ids_size 0x38 4 字符串列表的字符串个数。
    string_ids_off 0x3C 4 字符串列表表基地址。
    type_ids_size 0x40 4 类型列表里类型个数。
    type_ids_off 0x44 4 类型列表基地址。
    proto_ids_size 0x48 4 原型列表里原型个数。
    proto_ids_off 0x4C 4 原型列表基地址。
    field_ids_size 0x50 4 字段列表里字段个数。
    field_ids_off 0x54 4 字段列表基地址。
    method_ids_size 0x58 4 方法列表里方法个数。
    method_ids_off 0x5C 4 方法列表基地址。
    class_defs_size 0x60 4 类定义类表中类的个数。
    class_defs_off 0x64 4 类定义列表基地址。
    data_size 0x68 4 数据段的大小,必须以4字节对齐。
    data_off 0x6C 4 数据段基地址

     

    dexclass文件相比的一个优势,就是将所有的常量字符串集统一管理起来了,这样就可以减少冗余,最终的dex文件size也能变小一些。详细的dex文件介绍就不说了,有兴趣的可以查看android 源码dalvik/docs目录下的dex-format.html文件有详细介绍。不过我记得在android4.0版本后就没有了这个文件。

    根据上面的dex文件的格式结构,dalvik虚拟机运行dex文件执行的字节码就存在method_ids区域里面。我们查看dalvik虚拟机源码会有一个

    struct DexCode {

    u2  registersSize;

    u2  insSize;

    u2  outsSize;

    u2  triesSize;

    u4  debugInfoOff;       /* file offset to debug info stream */

    u4  insnsSize;          /* size of the insns array, in u2 units */

    u2  insns[1];

    /* followed by optional u2 padding */

    /* followed by try_item[triesSize] */

    /* followed by uleb128 handlersSize */

    /* followed by catch_handler_item[handlersSize] */

    };

    这样一个结构,这里的insns数组存放的就是dalvik的字节码。我们只要定位到相关类方法的DexCode数据段,即可通过修改insns数组,从而实现我们的目的。

     

    二、odex文件格式

     

    apk安装或启动时,会通过dexopt来将dex生成优化的odex文件。过程是将apk中的classes.dex解压后,用dexopt处理并保存为/data/dalvik-cache/data@app@<package-name>-X.apk@classes.dex文件。

    odex文件结构如下:

    android apk 防止反编译技术第二篇-运行时修改Dalvik指令

    从上图中我们发现dex文件作为优化后的odex的一部分,我们只需要从odex中找出dex的部分即可以了。

     

    三、方法实现

    要实现修改字节码,就需要先定位到想要修改得代码的位置,这就需要先解析dex文件。dex文件的解析在dalvik源码的dexDump.cpp给出了我们具体的实现,根据它的实现我们可以查找我们需要的类及方法。具体实现步骤如下:

    (1)    找到我们apk生成的odex文件,获得odex文件在内存中的映射地址和大小。实现代码如下:

    (2)    知道dex文件在odex中的偏移,以便解析dex文件。代码如下:

     

    (3)    找到dex偏移以后就可以解析dex文件,从而查找我们要进行替换的方法所在的类,然后在该类中找到该方法并返回该方法对应的DexCode结构体。函数实现如下:

    (4)    找到DexCode后就可以进行指令替换了。实现如下:

    注意:由于是在运行时修改的dalvik指令,这是进程的内存映射为只读的,所以需要调用mprotect函数将只读改为读写才能进行指令的修改。

     

    根据上面的讲述相信大家对运行时修改字节码的技术有了一定的了解,下一篇我们将讲解另一种android apk防止反编译技术,期待大家的捧场。如果对这篇讲的技术有任何疑问及想要获得这篇文章讲的技术的工程源码

    欢迎关注个人微信公众平台:程序员互动联盟(coder_online),扫一扫下方二维码或搜索微信号coder_online即可关注,我们可以在线交流。

    android apk 防止反编译技术第二篇-运行时修改Dalvik指令

     

    本文原始地址:http://www.coderonline.net/android-apk-prevent-decompilation-technology-modified-second-run-time-dalvik-instructions.html

    本站所有文章,除特别注明外,均为本站原创,转载请注明出处来自http://www.coderonline.net/

    否则保留追究法律责任的权利!

    关于

    发表评论

    表情 格式

    暂无评论

    切换注册

    登录

    忘记密码 ?

    切换登录

    注册