001

共 3781字,需浏览 8分钟

 ·

2021-12-11 06:54

虚拟机 ->   APK 文件结构   ->   dalvik 
  • JDK
  • Android 集成开发环境搭建
  • NDK
  • AndroidKiller
  • Jeb
  • IDA
  • WinHex

虚拟机

  • java 虚拟机
  • dalvik 虚拟机(5.0以下)
  • art 虚拟机(5.0及以上)

.dex => dexopt => .odex   dalvik 加载执行的 odex 文件

.dex => dex2oat => .oat    art 加载执行的 oat 文件

APK 文件结构

  • class.dex 应用程序的可执行文件,方法数超过 65535 ,进行分包处理会有多个 dex 文件。通过反编译工具 dex2jar 转换为 jar 包,在通过 jd-gui 查看代码
  • resources.arsc   资源索引表


dalvik 寄存器

  • v: 局部变量寄存器   v0-vn    参数寄存器    vn-vn + m
  • p: 参数寄存器  p0-pn    变量寄存器:v0-vn

Dalvikjava
Bbyte
Cchar
Sshort
Iint
Jlong
Ffloat
Ddouble
Zboolean
Vvoid
Ljava 类类型
[数组类型

Lpackage/name/ObjectName;->FieldName:Ljava/lang/String;

字段格式:类型(包名+类名)-> 字段名称:字段类型

dalvik 指令

基础字节码 - 名称后缀/字节码后缀   目的寄存器   源寄存器

  • nop   空操作指令,值为 00,对其代码,无实际操作

  • move  数据操作指令

    move 作用:

    1、赋值

    2、接受方法返回值操作

    3、处理异常操作

    • move vA, vB    将 vB 寄存器的值赋给 vA 寄存器,源寄存器和目的寄存器都为 4 位
    • move-wide vA, vB 为 4 位的寄存器赋值,源和目的寄存器都为 4 位
    • move/form16 vAA, vBBBB  将 vBBBB 寄存器的值赋给 vAA 寄存器,源寄存器为 16 位, 目的寄存器 8 位
    • move-object vA, vB  object 是对象的意思,出现这个词即为对象。给对象赋值,源寄存器和目的寄存器都为 4 位
    • move-object/from16 vAA, vBBBB 给对象赋值,源寄存器为 16 位, 目的寄存器为 8 位
    • move-object/16 vAA, vBBBB 给对象赋值,源寄存器和目的寄存器都为 16 位。
    • move-result vAA 将上一个 invoke 类型指令操作的字非对象结果赋给 vAA 寄存器
    • move-result-wide vAA  将上一个 invoke 类型指令操作的字非对象结果赋给 vAA 寄存器
    • move-result-object vAA  将上一个 invoke 类型指令操作的对象结果赋给 vAA 寄存器
    • move-exception vAA 保存运行时发生的异常到 vAA 寄存器
  • return 返回指令

    • return-void  一个 void 方法返回,返回值为空
    • return vAA  函数返回一个 32 位非对象类型的值,返回值寄存器为 8 位的 vAA
    • return-wide vAA  函数返回一个 64 位非对象类型的值,返回值为8位的寄存器 vAA
    • return-object vAA   函数返回一个对象类型的值,返回值为8 位的寄存器 vAA
  • const 数据定义指令(定义常量,字符串,类等数据)

    • const/4 vA, #+B   将数值符号扩展为 32 位后赋给寄存器 vA
    • const/16 vAA, #+BBBB  将数据符号扩展为 32 位 后赋给寄存器 vAA
    • const vAA, #+BBBBBBBB    将数值赋给寄存器 vAA
    • const/high16 vAA, #+BBBB0000  将数值右边零扩展为 32 位后赋给寄存器 vAA
    • const-wide/16 vAA, #++BBBB   将数值符号扩展为 64 位后赋值给寄存器 vAA
    • const-wide/32 vAA, #+BBBBBBBB  将数值符号扩展为 64 位后赋值给寄存器 vAA
    • const-wide vAA, #+BBBBBBBBBBBBBBBB 将数值赋给寄存器 vAA
    • const-string vAA, string@BBBB  通过字符串索引构造一个字符串并赋给寄存器 vAA
    • const-string vAA, string@BBBBBBBB   通过字符串索引 (较大) 构造一个字符串并赋给寄存器 vAA
    • const-class vAA, type@BBBB  通过类型索引获取一个类引用并赋给寄存器 vAA
    • const-class/jumbo vAAAA, type@BBBBBBBB  通过给定的类型索引获取一个类引用并赋给 vAAAA。这条指令占用两个字节,值为 0xooff (Android4.0新增)
  • 实例操作指令

    • check-cast vAA, type@BBBB  将 vAA 寄存器中的对象引用转换为指定类型
    • instance-of vA, vB   判断 vB 的对象引用是否可以转换为指定类型。如果可以 vA  赋值 1,否则 vA  赋值 0
    • new-instance vAA, type@BBBB   构造一个指定类型对象的实例,并将对象引用赋值给  vAA 寄存器
  • 数组操作指令

    • array-length vA, vB   获取 vB 寄存器中数组的长度并赋值给 vA 寄存器
    • new-array vA, vB, type@CCCC 构造指定类型(type@CCCC)与大小 (vB)的数组,赋值给 vA 寄存器
    • filled-new-array {vC, vD, vE, vF, vG}, type@BBBB  构造指定类型(type@BBBB)与大小 (vA)的数组并填充数组内容。vA 寄存器是隐含使用的,除了指定数组的大小外还指定了参数的个数,vC~vG 是使用到的参数寄存序列。
    • filled-new-array/range {vCCCC ..vNNNN}, type@BBBB  指令功能与 filled-new-array {vC, vD, vE, vF, vG}, type@BBBB  相同,只是参数寄存器使用 range 字节码指定了取值范围
    • fill-array-data vAA, +BBBBBBBB  用指定的数据填充数组, vAA 寄存器为数组引用,引用必须为基础类型的数组,在指令后面会紧跟一个数据表
  • 异常指令

    • throw vAA  抛出 vAA 寄存器中指定类型的异常
  • 跳转指令

    • if-eq 等于    if-ne  不等于
    • if-lt 小于    if-le  小于等于
    • if-gt 大于    if-ge  大于等于
    • if-eqz 等于0    if-nez  不等于0
    • if-ltz 小于0    if-lez  小于等于0
    • if-gtz 大于0   if-gez  大于等于0
    • packed-switch  有规律跳转
    • sparse-switch   无规律跳转
    • goto  无条件跳转
    • switch  分支跳转
    • if  条件跳转
  • cmp  比较指令(浮点型或长整型)

    大于(1)/等于(0)/小于(-1)  =>   cmpg、cmp

    大于(-1)/等于(0)/小于(1)  =>   cmpl

    • cmp-long vAA, vBB, vCC  比较两个长整型数,如果 vBB 大于 vCC,  则 vAA 等于 1,相等则结果为 0, 小于则结果为 -1
    • cmpl-float vAA, vBB, vCC 比较两个单精度浮点数.  大于 为 -1, 等于 0 ,小于为 1
    • cmpl-double vAA, vBB, vCC  比较双精度浮点数
  • 字段操作指令

    • 普通字段 =>  iget  读  / iput  写
    • 静态字段 =>  sget   读 /  sput
  • 方法调用指令

    • invoke-virtual      调用实例的虚方法(普通方法)
    • invoke-super           调用实例的父类/基类方法
    • invoke-direct          调用实例的直接方法(构造方法)
    • invoke-static          调用实例的静态方法
    • invoke-interface    调用实例的接口方法
  • 数据转换指令

    • opcode vA, vB    vB 存放需要转换的数据,转换后的结果保存在 vA

    • neg-数据类型  =>  求补

    • not-数据类型   =>  求反

      数据类型1-to-数据类型2  =>  将数据类型1转换为数据类型2

  • 数据运算指令

    • add/sub/mul/div/rem  加、减、乘、除、模
    • and/or/xor       与、或、异或
    • shl/shr/ushr    有符号左移、有符号右移、无符号右移


浏览 99
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报