mirror of
https://github.com/nganhkhoa/CTF-All-In-One.git
synced 2024-12-25 11:41:16 +07:00
finish 1.7.2
This commit is contained in:
parent
6c27b55b30
commit
bd2d914729
@ -19,10 +19,15 @@
|
|||||||
- [方法调用指令](#方法调用指令)
|
- [方法调用指令](#方法调用指令)
|
||||||
- [数据转换指令](#数据转换指令)
|
- [数据转换指令](#数据转换指令)
|
||||||
- [数据运算指令](#数据运算指令)
|
- [数据运算指令](#数据运算指令)
|
||||||
|
- [smali 语法](#smali-语法)
|
||||||
|
- [循环语句](#循环语句)
|
||||||
|
- [switch 语句](#switch-语句)
|
||||||
|
- [try-catch 语句](#trycatch-语句)
|
||||||
|
- [更多资料](#更多资料)
|
||||||
|
|
||||||
|
|
||||||
## Dalvik 虚拟机
|
## Dalvik 虚拟机
|
||||||
Android 程序运行在 Dalvik 虚拟机中,它与传统的 Java 虚拟机不同,完全基于寄存器架构,数据通过直接通过寄存器传递,大大提高了效率。Dalvik 虚拟机属于 Android 运行时环境,它与一些核心库共同承担 Android 应用程序的运行工作。Dalvik 虚拟机有自己的指令集,即 smali 代码,下面我们详细介绍它们。
|
Android 程序运行在 Dalvik 虚拟机中,它与传统的 Java 虚拟机不同,完全基于寄存器架构,数据通过直接通过寄存器传递,大大提高了效率。Dalvik 虚拟机属于 Android 运行时环境,它与一些核心库共同承担 Android 应用程序的运行工作。Dalvik 虚拟机有自己的指令集,即 smali 代码,下面会详细介绍它们。
|
||||||
|
|
||||||
|
|
||||||
## Dalvik 指令集
|
## Dalvik 指令集
|
||||||
@ -48,6 +53,7 @@ Dalvik 寄存器都是 32 位的,如果是 64 位的数据,则使用相邻
|
|||||||
|
|
||||||
#### 类型、方法和字段
|
#### 类型、方法和字段
|
||||||
Dalvik 字节码只有基本类型和引用类型两种。除了对象类型和数组类型是引用类型外,其余的都是基本类型:
|
Dalvik 字节码只有基本类型和引用类型两种。除了对象类型和数组类型是引用类型外,其余的都是基本类型:
|
||||||
|
|
||||||
|语法 | 含义 |
|
|语法 | 含义 |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
| V | void |
|
| V | void |
|
||||||
@ -252,3 +258,258 @@ move-result-object v0
|
|||||||
- `shl-type`:vBB << vCC
|
- `shl-type`:vBB << vCC
|
||||||
- `shr-type`:vBB >> vCC
|
- `shr-type`:vBB >> vCC
|
||||||
- `ushr-type`:(无符号数)vBB >> vCC
|
- `ushr-type`:(无符号数)vBB >> vCC
|
||||||
|
|
||||||
|
|
||||||
|
## smali 语法
|
||||||
|
类声明:
|
||||||
|
```
|
||||||
|
.class <访问权限> [修饰关键字] <类名>
|
||||||
|
.super <父类名>
|
||||||
|
.source <源文件名>
|
||||||
|
```
|
||||||
|
|
||||||
|
字段声明:
|
||||||
|
```
|
||||||
|
# static fields
|
||||||
|
.field <访问权限> static [修饰关键字] <字段名>:<字段类型>
|
||||||
|
|
||||||
|
# instance fields
|
||||||
|
.field <访问权限> [修饰关键字] <字段名>:<字段类型>
|
||||||
|
```
|
||||||
|
|
||||||
|
方法声明:
|
||||||
|
```
|
||||||
|
# direct methods
|
||||||
|
.method <访问权限> [修饰关键字] <方法原型>
|
||||||
|
[.locals]
|
||||||
|
[.param]
|
||||||
|
[.prologue]
|
||||||
|
[.line]
|
||||||
|
<代码体>
|
||||||
|
.end method
|
||||||
|
|
||||||
|
# virtual methods
|
||||||
|
.method <访问权限> [修饰关键字] <方法原型>
|
||||||
|
[.locals]
|
||||||
|
[.param]
|
||||||
|
[.prologue]
|
||||||
|
[.line]
|
||||||
|
<代码体>
|
||||||
|
.end method
|
||||||
|
```
|
||||||
|
需要注意的是,在一些老教程中,会看到 `.parameter`,表示使用的寄存器个数,但在最新的语法中已经不存在了,取而代之的是 `.param`,表示方法参数。
|
||||||
|
|
||||||
|
接口声明:
|
||||||
|
```
|
||||||
|
# interfaces
|
||||||
|
.implements <接口名>
|
||||||
|
```
|
||||||
|
|
||||||
|
注释声明:
|
||||||
|
```
|
||||||
|
# annotations
|
||||||
|
.annotation [注释属性] <注释类名>
|
||||||
|
[注释字段 = 值]
|
||||||
|
.end annotation
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 循环语句
|
||||||
|
```
|
||||||
|
# for
|
||||||
|
Iterator<对象> <对象名> = <方法返回一个对象列表>;
|
||||||
|
for(<对象> <对象名>:<对象列表>){
|
||||||
|
[处理单个对象的代码体]
|
||||||
|
}
|
||||||
|
|
||||||
|
# while
|
||||||
|
Iterator<对象> <迭代器> = <方法返回一个迭代器>;
|
||||||
|
while(<迭代器>.hasNext()){
|
||||||
|
<对象> <对象名> = <迭代器>.next();
|
||||||
|
[处理单个对象的代码体]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
比如下面的 Java 代码:
|
||||||
|
```Java
|
||||||
|
public void encrypt(String str) {
|
||||||
|
String ans = "";
|
||||||
|
for (int i = 0 ; i < str.length(); i++){
|
||||||
|
ans += str.charAt(i);
|
||||||
|
}
|
||||||
|
Log.e("ans:", ans);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
对应下面的 smali:
|
||||||
|
```
|
||||||
|
# public void encrypt(String str) {
|
||||||
|
.method public encrypt(Ljava/lang/String;)V
|
||||||
|
.locals 4
|
||||||
|
.parameter p1, "str" # Ljava/lang/String;
|
||||||
|
.prologue
|
||||||
|
|
||||||
|
# String ans = "";
|
||||||
|
const-string v0, ""
|
||||||
|
.local v0, "ans":Ljava/lang/String;
|
||||||
|
|
||||||
|
# for (int i 0 ; i < str.length(); i++){
|
||||||
|
# int i=0 =>v1
|
||||||
|
const/4 v1, 0x0
|
||||||
|
.local v1, "i":I
|
||||||
|
:goto_0 # for_start_place
|
||||||
|
|
||||||
|
# str.length()=>v2
|
||||||
|
invoke-virtual {p1}, Ljava/lang/String;->length()I
|
||||||
|
move-result v2
|
||||||
|
|
||||||
|
# i<str.length()
|
||||||
|
if-ge v1, v2, :cond_0
|
||||||
|
|
||||||
|
# ans += str.charAt(i);
|
||||||
|
# str.charAt(i) => v2
|
||||||
|
new-instance v2, Ljava/lang/StringBuilder;
|
||||||
|
invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
|
||||||
|
invoke-virtual {v2, v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
|
||||||
|
move-result-object v2
|
||||||
|
|
||||||
|
#str.charAt(i) => v3
|
||||||
|
invoke-virtual {p1, v1}, Ljava/lang/String;->charAt(I)C
|
||||||
|
move-result v3
|
||||||
|
|
||||||
|
# ans += v3 =>v0
|
||||||
|
invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(C)Ljava/lang/StringBuilder;
|
||||||
|
move-result-object v2
|
||||||
|
invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
|
||||||
|
# i++
|
||||||
|
add-int/lit8 v1, v1, 0x1
|
||||||
|
goto :goto_0
|
||||||
|
|
||||||
|
# Log.e("ans:", ans);
|
||||||
|
:cond_0
|
||||||
|
const-string v2, "ans:"
|
||||||
|
invoke-static {v2, v0}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I
|
||||||
|
return-void
|
||||||
|
.end method
|
||||||
|
```
|
||||||
|
|
||||||
|
#### switch 语句
|
||||||
|
```Java
|
||||||
|
public void encrypt(int flag) {
|
||||||
|
String ans = null;
|
||||||
|
switch (flag){
|
||||||
|
case 0:
|
||||||
|
ans = "ans is 0";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ans = "noans";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Log.v("ans:", ans);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
对应下面的 smali:
|
||||||
|
```
|
||||||
|
# public void encrypt(int flag) {
|
||||||
|
.method public encrypt(I)V
|
||||||
|
.locals 2
|
||||||
|
.param p1, "flag" # I
|
||||||
|
.prologue
|
||||||
|
|
||||||
|
# String ans = null;
|
||||||
|
const/4 v0, 0x0
|
||||||
|
.local v0, "ans":Ljava/lang/String;
|
||||||
|
|
||||||
|
# switch (flag){
|
||||||
|
packed-switch p1, :pswitch_data_0 # pswitch_data_0指定case区域的开头及结尾
|
||||||
|
|
||||||
|
# default: ans="noans"
|
||||||
|
const-string v0, "noans"
|
||||||
|
|
||||||
|
# Log.v("ans:", ans)
|
||||||
|
:goto_0
|
||||||
|
const-string v1, "ans:"
|
||||||
|
invoke-static {v1, v0}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
|
||||||
|
return-void
|
||||||
|
|
||||||
|
# case 0: ans="ans is 0"
|
||||||
|
:pswitch_0 # pswitch_<case的值>
|
||||||
|
const-string v0, "ans is 0"
|
||||||
|
goto :goto_0 # break
|
||||||
|
nop
|
||||||
|
:pswitch_data_0 #case区域的结束
|
||||||
|
.packed-switch 0x0 # 定义case的情况
|
||||||
|
:pswitch_0 #case 0
|
||||||
|
.end packed-switch
|
||||||
|
.end method
|
||||||
|
```
|
||||||
|
根据 switch 语句的不同,case 也有两种方式:
|
||||||
|
```
|
||||||
|
# packed-switch
|
||||||
|
packed-switch p1, :pswitch_data_0
|
||||||
|
...
|
||||||
|
:pswitch_data_0
|
||||||
|
.packed-switch 0x0
|
||||||
|
:pswitch_0
|
||||||
|
:pswitch_1
|
||||||
|
|
||||||
|
# spase-switch
|
||||||
|
sparse-switch p1,:sswitch_data_0
|
||||||
|
...
|
||||||
|
sswitch_data_0
|
||||||
|
.sparse-switch
|
||||||
|
0xa -> : sswitch_0
|
||||||
|
0xb -> : sswitch_1 # 字符会转化成数组
|
||||||
|
```
|
||||||
|
|
||||||
|
#### try-catch 语句
|
||||||
|
```Java
|
||||||
|
public void encrypt(int flag) {
|
||||||
|
String ans = null;
|
||||||
|
try {
|
||||||
|
ans = "ok!";
|
||||||
|
} catch (Exception e){
|
||||||
|
ans = e.toString();
|
||||||
|
}
|
||||||
|
Log.d("error", ans);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
对应的下面的 smali:
|
||||||
|
```
|
||||||
|
# public void encrypt(int flag) {
|
||||||
|
.method public encrypt(I)V
|
||||||
|
.locals 3
|
||||||
|
.param p1, "flag" # I
|
||||||
|
.prologue
|
||||||
|
|
||||||
|
# String ans = null;
|
||||||
|
const/4 v0, 0x0
|
||||||
|
.line 20
|
||||||
|
.local v0, "ans":Ljava/lang/String;
|
||||||
|
|
||||||
|
# try { ans="ok!"; }
|
||||||
|
:try_start_0 # 第一个try开始,
|
||||||
|
const-string v0, "ok!"
|
||||||
|
:try_end_0 # 第一个try结束(主要是可能有多个try)
|
||||||
|
.catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0
|
||||||
|
|
||||||
|
# Log.d("error", ans);
|
||||||
|
:goto_0
|
||||||
|
const-string v2, "error"
|
||||||
|
invoke-static {v2, v0}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I
|
||||||
|
return-void
|
||||||
|
|
||||||
|
# catch (Exception e){ans = e.toString();}
|
||||||
|
:catch_0 #第一个catch
|
||||||
|
move-exception v1
|
||||||
|
.local v1, "e":Ljava/lang/Exception;
|
||||||
|
invoke-virtual {v1}, Ljava/lang/Exception;->toString()Ljava/lang/String;
|
||||||
|
move-result-object v0
|
||||||
|
goto :goto_0
|
||||||
|
.end method
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## 更多资料
|
||||||
|
- 《Android软件安全与逆向分析》
|
||||||
|
- [Dalvik opcodes](http://www.blogjava.net/midea0978/archive/2012/01/04/367847.html)
|
||||||
|
- [android逆向分析之smali语法](http://lib.csdn.net/article/android/7043)
|
||||||
|
Loading…
Reference in New Issue
Block a user