精华内容
下载资源
问答
  • 使用来自smali项目的dexlib2进行DEX字节码检测 二手软件 JesusFreke的要旨发布在这里: ://gist.github.com/JesusFreke/6945806 来自Smali项目的dexlib2: : 番石榴:适用于Java的Google核心库: :
  • 从生成的vdex文件中反编译和提取android dex字节码的命令行工具
  • dex字节码介绍和二进制译码分析

    千次阅读 2019-07-06 03:48:23
    对于dex字节码的详细介绍,官方提供了三篇文档对其进行比较详尽的介绍,分别是: Dalvik bytecode :主要介绍的是Dalvik字节码的总体设计理念,还提供了全部的字节码指令介绍。如果没有一点计算机系统相关知识,...

    对于dex字节码,官方提供了三篇文档对其进行比较详尽的介绍,分别是:

    上面三篇文章,通读下来,如果不认真仔细看,很难把它们之间的关系串联起来,在实际阅读分析系统源码或者一些字节码指令时,还是较为困难的。下面就以一个实际例子,分析dex字节码指令的运用和阅读。
     

    源码例子

    public class Main {
    
        public static void main(String[] args) {
            Hello hello = new Hello();
            String sentence = hello.sayHello();
            System.out.printf(sentence);
        }
    
        public static class Hello {
            public String sayHello() {
                return "hello!!!!";
            }
        }
    
    }
    

    我们主要分析 String sentence = hello.sayHello(); 这行代码的字节码指令情况。

    使用工具,将上面源码编译成dex文件,用 010编译器 打开 :
    dex文件格式
    从上图看,dex 文件总体的格式,就如 Dalvik Executable format 中介绍的一样。上图中对应字段,和下图dex 文件格式是一致吻合的。

     
    要找到 String sentence = hello.sayHello(); 该语句的对应二进制指令,就要在dex 文件中,首先找到 main 方法。
    根据官方文档,它是在 :


    dex文件 —>class_defsclass_def_item —> class_data_item —> direct_methods


    在本例子中,main 方法隐藏在字节码中,如下图:

    main 方法的二进制字节码指令就在 insns 这个18位数组中。
     
    我们看看 insns 这些指令的二进制:

    如果仅仅看二进制,很难明白这么多条指令的内容,我们可以借助dexdump,先看看二进制译码后的字节码指令究竟是怎样的,dexdump 如下(只包含 dexdumpmain 方法的部分):

    从上图看到,对于语句 :
    String sentence = hello.sayHello();
    其对应的dex字节码指令是:
    invoke-virtual {v0}, LMain$Hello;.sayHello:()Ljava/lang/String; // method@0001
    该指令在二进制中的表示是:
    6e10 0100 0000
     
    这么复杂的一个dex字节码指令,对应的二进制表示,是如此的简单。这个编码和译码的关系就是 Dalvik bytecodeDalvik Executable instruction formats 里面说的内容.
     
    接下来,就是详细介绍该如何译码 6e10 0100 0000 这条二进制指令 。
    要译码指令,首先要清楚,指令的格式 如何。
    Dalvik bytecode 知道:


    指令 = 指令码op + 指令格式format + 参数


    先不要管这几个组成部分在指令中的排列顺序,一条指令就是上面的三部分组成的,三部分确定一条字节码指令。
     

    步骤一 :译码op

    要译码,首先,我们要确定op(指令码)是什么?
    6e10 0100 0000 二进制指令中,op = 6e
    这里有一个疑问,从 Dalvik bytecodeDalvik Executable instruction formats 中,我们知道一条指令,大概 (仅仅是大概)是下面的类似形式:

    B|A|op CCCC
    

    从直观阅读来看, op 在参数 B|A 之后,那么在这里,10 才是 op, 为什么是 6e 呢?
    主要原因是,字节码的字节序为 Little Endian 。这样,在16进制表示中,我们用编辑器看到op 在前面,而实际上,指令的格式是op 在后面,这有利于程序按字节序解释指令的。
    那么,在6e10 0100 0000 中,6e10 对应到字节码指令,实际是 1|0|6e 的形式。
     

    步骤二 :确立Format

    知道 op=6e 后,下一步,就是确定指令format。查阅 Dalvik bytecode 的指令集表格:

    op & format Mnemonic / Syntax Arguement
    6e 35c 6e: invoke-virtual {vC, vD, vE, vF, vG}, meth@BBBB A: argument word count (4 bits)
    B: method reference index (16 bits)
    C…G: argument registers (4 bits each)

    从表格中,看到,op=6e 对应的 format=35copformat 是多对一关系) 。
     
    format=35c ,实际上,这个 35cformatID,这个我们可以在 Dalvik Executable instruction formats 中提供的表格中查到:

    Format ID Syntax
    A|G|op
    BBBB
    F|E|D|C
    35c [A=5] op {vC, vD, vE, vF, vG}, meth@BBBB
    [A=5] op {vC, vD, vE, vF, vG}, site@BBBB
    [A=5] op {vC, vD, vE, vF, vG}, type@BBBB
    [A=4] op {vC, vD, vE, vF}, kind@BBBB
    [A=3] op {vC, vD, vE}, kind@BBBB
    [A=2] op {vC, vD}, kind@BBBB
    [A=1] op {vC}, kind@BBBB
    [A=0] op {}, kind@BBBB

    这里,我们就可以确立 6e10 0100 0000 二进制指令对应的字节码指令格式为 :


    A|G|op
    BBBB
    F|E|D|C


    步骤三 :分析参数

    前面我们已经知道指令的Format,这时候我们需要 代入参数
    6e10 0100 0000 中,6e 后面的10 ,对应Format,可以代入 A=1G=0,确立,字节码指令语法为:


    op {vC}, kind@BBBB


     
    op 实际为 invoke-virtual , C=0 , kindmethodBBBB=0001 (注意 Little Endian )。
    最终, 6e10 0100 0000 的字节码指令(其实只是助记符,方便人理解指令) :

    invoke-virtual {V0}, method@0001
    

     
    invoke-virtual {V0}, method@0001 这条指令实际上就是调用一个virtual方法(非private,非static,非final,非构造函数),这个方法的索引由 参数 0001 指定。
    那么,0001 方法索引在哪里?这个就要到dex文件中的method_ids中去找。

    method_ids 数组中,准确找到了index=0x0001 的对应方法为 Main$Hello.sayHello()

    剩下的参数是 {V0} , 其意思是需要使用 V0 寄存器的值作为方法调用的参数,但 sayHello 是不带参数的方法。在 Dalvik bytecode 中提及,对于实例方法(instantce methods)的调用,第一个参数为 调用者本身,所以 V0 存有的肯定是 Hello 类的实例对象,这符合前面指令new-instance 时,V0 寄存器是作为目的寄存器的情况。

     

    总结

    上文全部,只是其中一个方法调用的例子,但是实际上,任何二进制指令都是可以按以上步骤进行译码:

    • 指令 = 指令码op + 指令格式format + 参数
    • 译码步骤:确立op --> 查 format --> 读参数 --> 最终译码
    • 字节码指令实际上不是必然要存在的,它只是反编译dex文件的产物,帮组人更易理解指令,也可以理解为一种IR
    • 理解字节码指令和dex 文件相关的知识,利于对android虚拟机,AOT等模块的进行深入了解。
    展开全文
  • 关于dex字节码

    2012-12-10 21:33:00
    dalvik-bytecode.html中描述了字节码的顺序,其中,OP & Format op指示执行何种操作,Format描述了该种操作所对应的数据流格式。 这是师兄的一个case,记录下:  1 class add { 2 public static void ...

    没办法,自己没有看下去,又被说了“好弱”,自嘲下,在这个实验室,习惯了

    dalvik-bytecode.html中描述了字节码的顺序,其中,OP & Format

    op指示执行何种操作,Format描述了该种操作所对应的数据流格式。

    这是师兄的一个case,记录下:

          1 class add {
          2     public static void main (String[] args)
          3     {
          4         int i = 2;                                                                                         
          5         int k = 0;
          6         for (i = 1; i < 100; i++)
          7             k += i;
          8         System.out.println("k = " + k);
          9
         10     }
         11 }

    makefile:

          1 add.dex: add.jar                                                                                           
          2     dx --dex --verbose --dump-to=$@ --verbose-dump $^
          3 add.jar: add.class
          4     jar cf $@ $^
          5 add.class: add.java
          6     javac $^
          7
          8 clean:
          9     rm add.jar add.class

     

    看看dex字节码:

        219 0001c0: 1200              |  0000: const/4 v0, #int 0 // #0
        220 0001c2: 1211              |  0001: const/4 v1, #int 1 // #1
        221                                |  0002: code-address
        222                                     |  0002: code-address
        223                                     |  0002: local-snapshot
        224 0001c4: 1302 6400     |  0002: const/16 v2, #int 100 // #0064
        225 0001c8: 3521 0600     |  0004: if-ge v1, v2, 000a // +0006
        226                                    |  0006: code-address
        227                                    |  0006: code-address
        228                                    |  0006: local-snapshot
        229 0001cc: b010              |  0006: add-int/2addr v0, v1
        230 0001ce: d801 0101     |  0007: add-int/lit8 v1, v1, #int 1 // #01
        231                                     |  0009: code-address
        232 0001d2: 28f9              |  0009: goto 0002 // -0007
        233                                    |  000a: code-address
        234                                    |  000a: local-snapshot
        235                                    |  000a: code-address
        236 0001d4: 6201 0000    |  000a: sget-object v1, java.lang.System.out:Ljava/io/Pr
        237                                    |        intStream; // field@0000

    只看一个:13026400

    主机x86,dalvik一次读取16bits,故先读取0213,根据dalvik-bytecode.html,获取 13 操作码的数据流格式为 21s,

    查看instruction-formats.html,可以得知完整指令格式为  AA|op BBBB -------op vAA, #+BBBB

    故对于13026400所对应的是02 13 0064 ,对应const/16 v2, #int 100 // #0064

     

     

    展开全文
  • http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html Dalvik字节码解析/指令的位描述表 http://www.netmite.com/android/mydroid/dalvik/docs/instruction-formats.html Dalvik字节码...





    http://www.netmite.com/android/mydroid/dalvik/docs/dalvik-bytecode.html Dalvik字节码解析/指令的位描述表

    http://www.netmite.com/android/mydroid/dalvik/docs/instruction-formats.html Dalvik字节码解析/指令的语法格式表
    展开全文
  • 一.概述 有的场景下可能会有通过smali指令获取对应opcode的需求,那这时就需要知道smali指令和其字节码(包含opcode)转化关系了。 二.dex 字节码 1.先给出两篇关于dalvik指令的官方文档链接: ...1)查看dex字节码

    一.概述

    有的场景下可能会有通过smali指令获取对应opcode的需求,那这时就需要知道smali指令和其字节码(包含opcode)转化关系了。

    二.dex 字节码

    1.先给出两篇关于dalvik指令的官方文档链接:

    Bytecode for the Dalvik VM (列出了dalvik虚拟机上所有的指令)
    Dalvik VM Instruction Formats (给出了上一篇链接中所有指令对应的字节码模式)
    或者离线版本:DexBytecodeGuidance.zip

    2.smali指令与对应字节码相互转换

    1)查看dex字节码的工具

    可以解析dex的工具:jeb、ida、gda、jadx、dex2jar/jd-gui、dexdump等,但能给出smali指令和字节码对应关系的目前好像看到只有ida和gda,截图分别如下:
    ida中对dex文件解析截图
    GDA中对dex文件解析截图

    注意:仔细观察,就会发现IDA和GDA中呈现字节码的大小为方式是不同的,IDA中是大尾巴方式给出,GDA中是小尾方式。目前观察到的dex文件中字节码大多是以小尾方式排列的,在文件头有个四字节的78563412内容则是小尾方式排列,如果是12345678的内容,则是大尾方式排列。

    2)怎么查找1中给出的两篇官方文档

    以IDA中的如下指令为例:

    this = v2
    savedInstanceState = v3
    206F 0021 0032                 invoke-super                    {this, savedInstanceState}, <void Activity.onCreate(ref) imp. @ _def_Activity_onCreate@VL>
    

    invoke-super 在Bytecode for the Dalvik VM 中查找如下:
    在这里插入图片描述
    opcode为6f可以与指令对应上,然后通过Format id:35c到Dalvik VM Instruction Formats 中查看对应的指令组成格式,如下:
    在这里插入图片描述
    也即:

    A|G|op BBBB F|E|D|C    35c      [A=5] op {vC, vD, vE, vF, vG}, meth@BBBB
    

    意思是:该条指令中使用了五个寄存器做参数,寄存器的下标是安照指令中左边的排列顺序。不过如果A的值小于5,则从vC~vG的顺序填充,剩下部分填0(因为字节码是模2的,用不上的位置会填充0)。例如:

    [A=3] op {vC, vD, vF}对应的 A=3,G=0, F也为0,即:3|0|op 0|E|D|C
    

    当然还有一中情况是参数个数大于5,则会转用 invoke-super/range 指令。
    回到该小节开头给出的指令,invoke-super的opcode为6f,参数有两个,所以对应第一个字节的第一位2,因为参数不够5个,第一个字节的第二位用不上,用0填充。Activity.onCreate这个methodid是0x21,使用010打开dex文件可验证(验证确实是),所以BBBB 用0x0021填充。只有两个参数,F|E位用不上,用0填充,C、D为对应this, savedInstanceState(寄存器对应分别是v2、v3),因此C位是2,D位是3,组合起来是206f00210032,这是大尾排列顺序,每两字节转成小尾,则是6f2021003200,大多数dex文件中存储方式是这种小尾格式。
    以此类推,其它的smali指令查找对应的字节码,也是通过类似方式查找的,总结为:
    1)Bytecode for the Dalvik VM 中查找对应指令的format id
    2)Dalvik VM Instruction Formats中通过format id查找对应的字节码组成格式。

    3)smali指令学习

    平时工作中,也许对字节码了解可能不需要很多,而是对smali指令需要了解很多。smali指令在Bytecode for the Dalvik VM 介绍的很全面,以后就在这上面学习smali了,嘿哈。

    三.总结

    本篇文章简单介绍了smali指令中opcode及寄存器等信息和字节码中对应关系的查找方法,简单来说还是:
    1)Bytecode for the Dalvik VM 中查找对应指令的format id
    2)Dalvik VM Instruction Formats中通过format id查找对应的字节码组成格式。
    3)通过已知的字节码和smali指令,获知其中更细节的opcode及寄存器等与字节码中内容的对应关系,或者在熟悉后也就可以通过字节码解析出smali指令,或者通过smali指令得到字节码内容。

    展开全文
  • Android 设备上运行的 DEX 字节码,该工具支持您在应用的代码中使用 Java 8 语言功能。 d8 还作为独立工具纳入了 Android 构建工具 28.0.1 及更高版本中:android_sdk/build-tools/version/’ 1、d8基本用法 d8 ...
  • 基于一个dex文件解析程序修改而成,指定要隐藏的方法的sig即可。
  • Dex文件及Dalvik字节码格式解析

    千次阅读 2016-09-16 23:54:19
    Dex文件介绍Dex文件是Dalvik的可执行文件,Dalvik是针对嵌入式设备设计的java虚拟机,所以Dex文件和Class文件的结构上有很大区别。为了更好的利用嵌入式你设备的资源,Dalvik在java程序编译后,还需要用dx工具将编译...
  • ReDex是最初在Facebook开发的Android字节码dex)优化器。 它提供了一个用于读取,编写和分析.dex文件的框架,以及一组使用此框架来改进字节码的优化过程。 由ReDex优化的APK应该比其源更小更快。
  • Android: .java文件转.dex和java字节码

    千次阅读 2016-12-16 15:13:43
    一、.java文件转.dex 首先将 .java 文件转成 .class 文件(例如:Hello.java) javac Hello.java —> 得到Hello.class [这里有一个坑,请大家注意:如果你的java版本是1.7的话,在转dex文件的时候很有可能会报错,请...
  • 一、 热修复框架简介、 1、类替换、 2、so 替换、 3、资源替换、 4、全平台支持、 5、生效时间、 6、性能损耗、 7、总结、 二、 将 Java 字节码文件打包到 Dex 文件、
  • 咋把dex文件变成java源码 还原剂 Redexer 是一个重新设计的工具,用于操作 Android 应用程序二进制文件。 该工具能够将 DEX 文件解析为内存中的数据结构; 推断应用程序使用哪些参数使用某些权限(我们将此功能命名...
  • dex2jar.rar

    2017-12-13 20:24:14
    dex2jar是一款将dex字节码转成jar包的工具,共工具适用于安卓平台
  • 查看字节码

    2016-03-29 10:32:00
    使用dexdump.exe(位于Android SDK的platform-tools目录下)查看函数的Dalvik字节码,执行 dexdump.exe -d ***.dex 使用javap反编译***.class 查看java字节码, Javap -c -classpath . *** 转载于:...
  • Dalvik 字节码的读取

    2017-10-24 09:56:12
    前言想要读取 Dalvik 字节码,需要参考两篇说明文档,分别是:字节码格式 和 Dalvik 可执行指令格式,下面以我的上篇博文 Android 虚拟机 — .dex 文件格式 中的例子为例,实战讲解一下 Dalvik 字节码怎么读取。...
  • -- 字节码插桩-- https://juejin.im/post/5c886d4ce51d4560fd3ea9a7 生成Android Dex编译过程: .java -> .class -> .dex 插桩,就是在.class转为.dex之前,修改....字节码修改工具。如AspectJ,ASM,javas...
  • Dalvik字节码

    千次阅读 2017-03-03 16:33:07
    每一框架包含一个特定数量的寄存器(由函数指定)和一些需要执行该函数的附属的数据,例如(但不限制在这些)程序计数器和包含该方法的.dex文件的引用。 当用于位值的时候(例如整数和浮点数),寄存器被认为是32位...
  • ASM字节码插桩

    2020-02-25 22:32:19
    ASM字节码插桩 前言 热修复的多Dex加载方案中,对于5.0以下的系统存在CLASS_ISPREVERIFIED的问题,而解决这个问题的一个方案是:通过ASM插桩,在类的构造方法里引入一个其它dex里的类,从而避免被打上CLASS_...
  • 细说dex2oat(1)

    千次阅读 2016-03-24 18:32:31
    dex2oat是将dex字节码编译成oat格式的可执行文件的工具,我们先从命令行参数,和makefile调用它的时候所给的参数开始了解它吧
  • Dalvik字节码编辑器

    2014-04-22 17:30:08
    传统的破解很麻烦,要在pc上进行,搭建开发环境,反编译dex代码回java,修改后,再编译成dex(困难),打包apk Dalvik字节码编辑器则选择了完全不同的技术路线.既然java编译字节码,而字节码的文档是公开的,那就能够直接解释...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 803
精华内容 321
关键字:

dex字节码