Smali language is a register language of Davlik, similar to assembly language in syntax. One of the biggest differences between Dalvik VM and JVM is that Dalvik VM is regime-based. Register-based means that all operations in SMALI must go through registers.
Refer to the website
Static analysis of Android applications – smali file parsing
Blog.csdn.net/hp910315/ar…
Basic Grammar of Smali (1)
Blog.csdn.net/l_o_s/artic…
Android smali grammar
Blog.csdn.net/Rozol/artic…
Android Studio dynamically debugs SMALI
www.cnblogs.com/goodhacker/…
The data type
Smali type | Java type |
---|---|
V | Void (for return types) |
Z | boolean |
B | byte |
S | short |
C | char |
I | int |
J | long (64 bits) |
F | float |
D | double (64 bits) |
The class definition
Kotlin code
class MainActivity : AppCompatActivity() {... }Copy the code
Smali
.class public final Lapp/santaone/customer/voip/MainActivity;
.super Landroidx/appcompat/app/AppCompatActivity;
.source "MainActivity.kt".Copy the code
Conclusion:
- L means this is an object type
- .class < access > < keyword modifier > < class name; >
- .super < keyword modifier > < parent class name; >
- .source < source file name >
Variable definitions
Kotlin code
private var incomingSip: String? = null
private var isOutgoing = false
Copy the code
Smali
# instance fields
.field private incomingSip:Ljava/lang/String;
.field private isOutgoing:Z
Copy the code
Conclusion:
- Instance fields, which are fields of the instance.
- .field indicates that this is a field. Private, which stands for private, isOutgoing, which is the variable name. :Z is the type of the variable.
- [I: a one-dimensional array representing an integer.
Method definition
Kotlin code
override fun onStart() {
super.onStart()
}
Copy the code
Smali
.method protected onStart()V .locals 0 .line 248 invoke-super {p0}, Landroidx/appcompat/app/AppCompatActivity; ->onStart()Vreturn-void
.end method
Copy the code
Conclusion:
- .method means that this is a method. Protected, access rights. OnStart, method name. V, return type.
register
Kotlin code
private fun print(string: String) {
Log.d(TAG, string)
}
Copy the code
Smali
.method private print(Ljava/lang/String;) V .registers 3 .param p1,"string" # Ljava/lang/String;
.prologue
.line 29
const-string v0, "MainActivity"invoke-static {v0, p1}, Landroid/util/Log; ->d(Ljava/lang/String; Ljava/lang/String;) I .line 30return-void
.end method
Copy the code
Conclusion:
- Android variables are stored in registers, which are 32 bits and can support any type. Long and double are 64 bits and need to be stored in two registers.
- Registers are named v and P, with V representing the local register and P representing the parameter register.
- v0 v1 v2 v… // Name of the.locals register.
- p0 p1 p2 p… Registers the name of the registers.
- Registers 3 Indicates that the method has three registers. There is a local register, V0, and two parameter registers, P0 and P1. P0 is not seen because p0 stores this. If the method is static, there are only 2 registers, no need to store this.
operation
smali | describe |
---|---|
add-int v0, p1, p2 | v0 = p1 + p2 |
sub-int v0, p1, p2 | v0 = p1 – p2 |
mul-int v0, p1, p2 | v0 = p1 * p2 |
div-int v0, p1, p2 | v0 = p1 / p2 |
rem-int v0, p1, p2 | v0 = p1 % p2 |
and-int v0, p1, p2 | v0 = p1 & p2 |
or-int v0, p1, p2 | V0 = p1 │ p2 |
xor-int v0, p1, p2 | v0 = p1 ^ p2 |
shl-int v0, p1, p2 | v0 = p1 << p2 |
. | . |
instruction
smali | describe |
---|---|
return-void | Direct return |
return v0 | Return to where v0 |
return-object v0 | Return v0(object) |
return-wide v0 | Give v0(double register value) |
invoke-virtual | Calling general methods |
invoke-super | Call the parent class method |
invoke-direct | Call the private/ constructor |
invoke-static | Calling static methods |
invoke-interface | Call the interface method |
const(/4, /16, ,/high16) vx, num | Assign nun to vX register, num = (4bit, 16bit, 32bit(int), 16bit(float)) |
const-wide(/16, ,/high16) vx, num | Assign num to vx and vx+, where num is (? , 64bit(long), 64bit(double)) |
const-string( , -jumbo) vx, string | “Unicode” string assigned to VX (normal, too long) |
const-class vx, class | Assign Class to vx |
if-eq v0, v1 | if (v0 == v1) |
if-ne v0, v1 | f (v0 ! = v1) |
if-gt v0, v1 | if (v0 > v1) |
if-ge v0 | if (v0 >= v1) |
if-lt v0 | if (v0 < v1) |
if-le v0 | if (v0 <= v1) |
if-eqz v0 | if (v0 == 0) |
if-nez v0 | if (v0 ! = 0) |
if-gtz v0 | if (v0 > 0) |
if-gez v0 | if (v0 >= 0) |
if-ltz v0 | if (v0 < 0) |
if-lez v0 | if (v0 <= 0) |
iget0 | Value (int) |
iget-wide0 | Value (dual register value) |
iget-object0 | Value (object pointer) |
iget-boolean0 | Values (bool) |
iget-byte0 | Value (bytes) |
iget-char0 | Value (character) |
iget-short0 | Values (short) |
iput0 | Assignment (int) |
iput-wide0 | Assign (double register value) |
iput-object 0 | Assignment (object pointer) |
iput-boolean0 | Assignment (bool) |
iput-byte0 | Assignment (bytes) |
iput-char0 | Assign (a character) |
iput-short0 | Assignment (short) |
Insert smali pile
Smali piling, the principle of piling is to statically modify the APK samli file, and then repackage.
- Decompilation results in SMALI
- Modify the SMali code
- Repackage signature
At the end
Android APK file (1) Compilation and packaging process
Android APK file (2) decompression and decompilation
Android APK file (III. AAPT2 tool use)
Android APK file (4)