android反编译高频汇编指令

简介: 汇编指令

1.反编译apk高频出现指令

const/4 v1, #int 2 表示存入int型常量2到v1,目的寄存器在第二个自己的低4位,常量2在更高的4位。
const/16 v0, #int 10 表示存入int型常量10到v0中。
move-object/from16 v1, v21 表示将v21寄存器中的对象引用到v1上。
check-cast v4 Test3 检查v4寄存器中的对象引用是否可以转换为Test3的实例。
Instance-of v0, v4, Test3 检查V4寄存器中的对象引用是否是Test3的实例,如果是V0存入非0值,否则v0存入0。
array-length v0, v1 计算v1寄存器中数组引用的元素长度并将长度存入V0。
cmpl-float v0, v6, v7 比较v6和v7的float值,并在v0存入int型的返回值。非数值默认为小于,如果参数为非数值将返回-1。
cmpg-float v0, v6, v7 比较v6和v7的float值,并在v0存入int型的返回值。非数值默认为大于,如果参数为非数值将返回1。
age v7,v3,v6 从数组获取一个int型值到v7,对象数组的引用位于v3,需获取的元素的索引位于v6。
age-byte v0, v0,v1 从byte数组获取一个byte值到v0,数组的引用位于v0,徐获取的元素的的索引位于v1。
aput v0, v3,v5 将v0的int值作为元素存入int数组,数组的引用位于v3,元素的索引位于v5。
move-result v0 移动上一次方法调用的返回值到v0。
move-result-wide v2 移动上一次方法调用的long/double型返回值到v2,v3。
new-array v2,v1, char[] 新建一个char数组,v1存入数组的长度,v2存入数组的引用。
invoke-virtual{v4,v0,v1,v2,v3}, Test.method:(IIII)V 表示调用Test的method方法,该指令共有5个参数,参数v4是this实例,v0,v1,v2,v3 是method方法的参数,返回值为Void
sput-object v0, test3.os1:Ljava/lang/object 将v0寄存器中的对象引用赋值到Test3的对象引用静态字段os1上。
iget-object v1,v2, LineReader.fis:Ljava/io/FileInputStream 读取FileInputStream对象引用字段fis到v1,v2寄存器中是LineReader实例的引用。
invoke-direct, java.lang.object.:()V 表示java.lang.object 的方法,参数v1是this的实例,()V表示方法没有参数,v是返回值为void。
intvoke-direct{0}, Landroid/app/TabActivity;->()v 这里init()就是定义TabActivity中的一个private函数。
iput-object v0, v2,LineRader.bis:Ljava/io/BufferedInputStream 将V0寄存器的值存入实例的对象引用字段bis,v2寄存器中是BufferedInputStream实例的引用。
rem-int v0 v2,v3计算v3%v2并将结果存入v0
add-int/lit8 v0, v0, 0x1 表示 v0++的意思

2.高频的结构

.method public constructor ()V #这是class的构造函数实现。
.registers 1 #这个方法所使用的寄存器数量。
invoke-direct {p0}, Ljava/lang/Object;->()V#调用Object的构造方法,p0相当于"this" 指针。
invoke-virtual {p0}, Ljava/lang/Object;->toString()Ljava/lang/String;#调用toString()函数。
其中for循环跟while循环的识别方法是for循环的加加放在后面(add-int/lit8 v0, v0, 0x1),而while循环的加加放在判断语句的后面。
new-instance v5, Ljava/lang/StringBuilder; 表示新建一个临时的StringBuilder对象,并将其引用赋值给v5寄存器。
invoke-direct {v1}, Ljava/lang/StringBuilder;->()V 调用stringBuilder中的构造方法。
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; 表示{v1, v2}大括号中v1寄存器中存储的是StringBuilder对象的引用,调用StringBuilder中的append(String, str)方法,v2寄存器则是参数寄存器。

3.反编译的出现高频语法数据解析

创建StringBuilder对象,并将其引用赋值给v1寄存器

new-instance v1, Ljava/lang/StringBuilder;

调用StringBuilder中的构造方法

invoke-direct {v1}, Ljava/lang/StringBuilder;->()V

v2寄存器中赋值为ther result:

const-string v2, "the result:"

{v1,v2}大括号中v1寄存器中存储的是StringBuilder对象的引用.

调用StringBuilder中的append(String str)方法,v2寄存器则是参数寄存器.

invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

获取上一个方法的执行结果,此时v1中存储的是append()方法执行后的结果,此处之所以仍然返回v1的

原因在与append()方法返回的就是自身的引用

move-result-object v1

继续调用append方法(),p0表示第一个参数寄存器,即上面提到的result参数

invoke-virtual {v1, p0}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;

同上

move-result-object v1

调用StringBuilder对象的toString()方法

invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

获取上一个方法执行结果,toString()方法返回了一个新的String对象,因此v1中此时存储了String对象的引用

move-result-object v1
new-instance 表示java类中的new语句
例如:
new-instance v1, Lcom/nd/tq/GameEntity;
invoke-direct {v1}, Lcom/nd/tq/GameEntity;->()V
iput-object v1, p0, Lcom/nd/tq/MainActivity;->entity:Lcom/nd/tq/GameEntity;
java代码
entity =new GameEntity();
内部类格式:[外部类]内部类.smali,如果是匿名的内部类那么格式:[外部类]内部类.smali ,如果是匿名的内部类那么格式:[外部类]内部类.smali,如果是匿名的内部类那么格式:[外部类]NUM.smali。其中NUM代表从1开的数字。
对于Java文件中的每一个内部类,都会产生一个单独的smali文件,比如ActivityThread1.smali。这些文件的命名规范是如果是匿名内部类,则命名规则是外部类+1.smali。这些文件的命名规范是如果是匿名内部类,则命名规则是外部类+1.smali。这些文件的命名规范是如果是匿名内部类,则命名规则是外部类++数字,否则的话是外部类++内部类的名字例如:classOuterclassInner反编译上述代码后会生成两个文件:Outer.smali与Outer+内部类的名字 例如: class Outer { class Inner{} } 反编译上述代码后会生成两个文件:Outer.smali 与Outer+内部类的名字例如:classOuterclassInner反编译上述代码后会生成两个文件:Outer.smali与OuterInner.smali
静态方法中没有this指针,也就是p0不再是this指针,而是第一个参数, 非静态方法p0表示this指针。
invoke-virtual {p0} 这个p0就是this参数: invoke-virtual {p0}, Lcom/nd/tq/NDSecDataType;->toString()Ljava/lang/String; 这个表示 NDSecDataTyep.toString()
invoke-static {p1} 这个p1表示具体的参数非this 。 invoke-static {p1}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I 表示 Integer.parseInt(p1)
long和double型的值占用两个寄存器。例如:一个在v0寄存器的double值实际占用V0、v1两个寄存器。
boolean的值实际是转成int型的值进行操作,存储实际是1和0.
mov-object vx,vy:移动对象引用,从vy到vx。
mov-result-wide vx 移动上一次方法调用的long/double型返回值到vx,vx+1。
const-class vx,类型ID:存入类对象常量到vx,通过类型id或类型
例如:const-class v0,test3 表示存入test3.class的引用到v0。
check-cast vx,类型ID:检查vx寄存器中的对象引用是否可以转换城类型ID对应类型的实例。 如不可转换,抛出ClassCastException异常,否则继续执行。 check-cast vx4,test3 检查v4寄存器中的对象引用是否可以转换为test3的实例
new-array vx,vy 根据类型id或者类型新建一个数组,vy存入数组的长度,vx存入数组的引用:例如 new-array v1,v2, char[]:表示 char v1[v2]
age开头的都跟数组获取有关系的 比如: aget vx,vy,vz 从int数组获取一个int型值到vx中,其中对象数组引用是vy,数组元素索引是vz
age后面-跟的条件 只不过是获取值的对一个条件,比如 aget-object vx,vy,xz 表示的是从对象引用数组获取一个对象引用到vx,对象数组的的引用位于vy获取元素的索引位于vz。
aput开头的都跟数组存入有关系的的 比如: aput vx,vy,vz 表示将vx的int值作为元素存入int数组,数组的引用位于vy,元素的索引位于vz。
iget开头的对寄存器实例引用的赋值 比如: iget vx,vy,字段ID 根据字段ID读取实例的int型字段到vx,vy寄存器中是该实例的引用,例如: iget v0,v1 test2.i6:I表示读取int型字段i6到v0中,其中v1寄存器是test2实例的引用。
iput开头的是将寄存器的值存入实例中:比如 iput vx,vy,字段ID 根据字段ID将Vx寄存器的值存入实例的int型字段,vy寄存器是该实例的引用。
例如: iput v0,v2 test2.i6:I 将v0寄存器的值存入实例的int型字段i6,v2寄存器中是test2实例的引用。
sget开头的是读取静态相关字段信息 sget vx 字段ID 根据字段ID读取静态int型字段到vx
sput开头的是将寄存器的值赋值到静态字段中。
例如: sput vx,字段id 根据字段ID将vx寄存器中的值赋值到int型静态字段。
neg开头的表示相减的neg后面跟的是类型和寄存器 neg-int vx,vy 计算vx= -vy并将结果存入vx。
int-to-long vx,vy 转换vy寄存器中的int型值为long型值存入vx,vx+1
其中字段中间有个-to-的表示类型值的转换。

相关文章
|
6月前
|
存储 Unix 编译器
汇编语言----X86汇编指令
汇编语言----X86汇编指令
224 2
|
1月前
|
存储 移动开发 C语言
【ARM汇编速成】零基础入门汇编语言之指令集(三)
【ARM汇编速成】零基础入门汇编语言之指令集(三)
|
1月前
|
编译器 C语言 计算机视觉
【ARM汇编速成】零基础入门汇编语言之指令集(二)
【ARM汇编速成】零基础入门汇编语言之指令集(二)
146 0
|
6月前
|
存储 机器学习/深度学习 移动开发
汇编语言指令系列
汇编语言指令系列
672 0
几组汇编指令的比较
几组汇编指令的比较
|
4月前
|
存储 机器学习/深度学习 芯片
8086 汇编笔记(十二):int 指令 & 端口 & 直接定址表
8086 汇编笔记(十二):int 指令 & 端口 & 直接定址表
|
4月前
|
存储 算法 安全
深入理解汇编语言:基础语法和常用指令介绍
深入理解汇编语言:基础语法和常用指令介绍
|
5月前
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
汇编语言(第四版) 实验一 查看CPU和内存,用机器指令和汇编指令编程
8086 汇编笔记(九):call 指令 和 ret 指令
8086 汇编笔记(九):call 指令 和 ret 指令
|
4月前
|
编译器
8086 汇编笔记(八):转移指令的原理
8086 汇编笔记(八):转移指令的原理
下一篇
无影云桌面