Preface We have talked about the tools for android decompilation and how to decompile. After decompilation, you can get a jar or smali file. Android is developed in Java, but the Android system has its own virtual machine Dalvik. The code is not compiled in Java, but in Smali. If we decompile the code in jar, many parts may not be correctly explained. If we decompile smali, we can correctly understand the meaning of the program. Therefore, it is necessary for us to be familiar with the smali syntax. Type Representation There are two types in Java, primitive types and reference types (including objects), and these two types are also mapped to Smali. Primitive Types - V void (can only be used for return value types)
- Z boolean
- B byte
- S short
- C char
- I int
- J long
- F float
- D Double
Object Type - Lpackage/ name /ObjectName; equivalent to package.name.ObjectName in Java
L indicates that this is an object type package/name The package where the object is located ObjectName object name ; Marks the end of the object name Array Representation [I represents a one-dimensional array of int type, equivalent to int[]; To add a dimension, add a [, such as [[I represents int[][] Each dimension of the array has a maximum of 255; The representation of object arrays is similar, such as the representation of String arrays is [Ljava/lang/String Registers and variables In Java, variables are stored in memory. In order to improve performance, Android stores variables in registers. Registers 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 with v and p v represents the local register, p represents the parameter register, and the relationship is as follows If a method has two local variables and three parameters - v0 first local register
- v1 second local register
- v2 p0 ( this )
- v3 p1 first parameter
- v4 p2 second parameter
- v5 p3 The third parameter
Of course, if it is a static method, there are only 5 registers, and there is no need to store this. .registers Use this directive to specify the total number of registers in the method .locals Use this directive to indicate the total number of non-parameter registers in a method, placed on the first line of the method. Method and field representation Method signature - methodName(III)Lpackage/name/ObjectName;
If you have done NDK development, you should be familiar with this kind of signature. This is how a method is identified. In the above, methodName identifies the method name, III represents three integer parameters, and Lpackage/name/ObjectName; represents the type of the return value. Method Representation Lpackage/name/ObjectName;——>methodName(III)Z That is, function boolean methondName(int a, int b, int c) in package.name.ObjectName is similar to this Field Representation - Lpackage/name/ObjectName;——>FieldName:Ljava/lang/String;
That means: package name, field name and field type Definition of method For example, the following method - private static int sum( int a, int b) {
- return a+b;
- }
After using the compilation - .method private static sum(II)I
- .locals 4 # indicates that 4 local registers need to be applied for
- .parameter
- .parameter #This indicates that there are two parameters
- .prologue
- .line 27
- move v0, p0
- .local v0, a:I
- move v1, p1
- .local v1, b:I
- move v2, v0
- move v3, v1
- add- int /2addr v2, v3
- move v0, v2
- .end local v0 #a:I
- return v0
- .end method
From the above, we can see that the function declaration starts with .method and ends with .end method. The Java keywords private, static, etc. can be used. At the same time, the signature is used to represent the only method, here is sum(II)I. Declaring Members .field private name:Lpackage/name/ObjectName; For example: private TextView mTextView; means .field private mTextView:Landroid/widget/TextView; private int mCount; .field private mCount:I Instruction Execution Smali bytecode is similar to assembly. If you have a basic understanding of assembly, it is very easy to understand. for example: move v0, v3 #Move the value of register v3 to register v0. const v0, 0x1 #Assign the value 0x1 to register v0. invoke-static {v4, v5}, Lme/isming/myapplication/MainActivity;->sum(II)I #Execute the method sum(), the values of v4 and v5 are used as the parameters of sum respectively. other As we can see above, smali is similar to assembly language. For many commands, we can check its manual to find the corresponding commands. When learning, we can write a simple java file and then convert it into a smali file for reference. Below, I post a relatively simple java file I wrote and its corresponding smali, which contains if judgment and for loop. java file: - package me.isming.myapplication;
- import android.support.v7.app.ActionBarActivity;
- import android.os.Bundle;
- import android.view.Menu;
- import android.view.MenuItem;
- import android.widget.TextView;
- public class MainActivity extends ActionBarActivity {
- private TextView mTextView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super .onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mTextView = (TextView) findViewById(R.id.text);
- mTextView.setText( "a+b=" + sum( 1 , 2 ) + "a>b?" + max( 1 , 2 ) + "5 accumulate:" + accumulate( 5 ));
- }
- private static int sum( int a, int b) {
- return a+b;
- }
- private boolean max( int a, int b) {
- if (a > b) {
- return true ;
- } else {
- return false ;
- }
- }
- private int accumulate( int a) {
- if (a <= 0 ) {
- return 0 ;
- }
- int sum = 0 ;
- for ( int i = 0 ; i <= a; i++) {
- sum += a;
- }
- return sum;
- }
- }
Corresponding smali: - . class public Lme/isming/myapplication/MainActivity;
- . super Landroid/support/v7/app/ActionBarActivity;
- .source "MainActivity.java"
- # instance fields
- .field private mTextView:Landroid/widget/TextView;
- # direct methods
- .method public constructor <init>()V
- .locals 2
- .prologue
- .line 10
- move-object v0, p0
- .local v0, this :Lme/isming/myapplication/MainActivity;
- move-object v1, v0
- invoke-direct {v1}, Landroid/support/v7/app/ActionBarActivity;-><init>()V
- return - void
- .end method
- .method private accumulate(I)I
- .locals 6
- .parameter
- .prologue
- .line 39
- move-object v0, p0
- .local v0, this :Lme/isming/myapplication/MainActivity;
- move v1, p1
- .local v1, a:I
- move v4, v1
- if -gtz v4, :cond_0
- .line 40
- const / 4 v4, 0x0
- move v0, v4
- .line 46
- .end local v0 # this :Lme/isming/myapplication/MainActivity;
- :goto_0
- return v0
- .line 42
- .restart local v0 # this :Lme/isming/myapplication/MainActivity;
- :cond_0
- const / 4 v4, 0x0
- move v2, v4
- .line 43
- .local v2, sum:I
- const / 4 v4, 0x0
- move v3, v4
- .local v3, i:I
- :goto_1
- move v4, v3
- move v5, v1
- if -gt v4, v5, :cond_1
- .line 44
- move v4, v2
- move v5, v1
- add- int /2addr v4, v5
- move v2, v4
- .line 43
- add- int /lit8 v3, v3, 0x1
- goto :goto_1
- .line 46
- :cond_1
- move v4, v2
- move v0, v4
- goto :goto_0
- .end method
- .method private max(II)Z
- .locals 5
- .parameter
- .parameter
- .prologue
- .line 31
- move-object v0, p0
- .local v0, this :Lme/isming/myapplication/MainActivity;
- move v1, p1
- .local v1, a:I
- move v2, p2
- .local v2, b:I
- move v3, v1
- move v4, v2
- if -le v3, v4, :cond_0
- .line 32
- const / 4 v3, 0x1
- move v0, v3
- .line 34
- .end local v0 # this :Lme/isming/myapplication/MainActivity;
- :goto_0
- return v0
- .restart local v0 # this :Lme/isming/myapplication/MainActivity;
- :cond_0
- const / 4 v3, 0x0
- move v0, v3
- goto :goto_0
- .end method
- .method private static sum(II)I
- .locals 4
- .parameter
- .parameter
- .prologue
- .line 27
- move v0, p0
- .local v0, a:I
- move v1, p1
- .local v1, b:I
- move v2, v0
- move v3, v1
- add- int /2addr v2, v3
- move v0, v2
- .end local v0 #a:I
- return v0
- .end method
- # virtual methods
- .method protected onCreate(Landroid/os/Bundle;)V
- .locals 8
- .parameter
- .prologue
- .line 16
- move-object v0, p0
- .local v0, this :Lme/isming/myapplication/MainActivity;
- move-object v1, p1
- .local v1, savedInstanceState:Landroid/os/Bundle;
- move-object v2, v0
- move-object v3, v1
- invoke- super {v2, v3}, Landroid/support/v7/app/ActionBarActivity;->onCreate(Landroid/os/Bundle;)V
- .line 17
- move-object v2, v0
- const v3, 0x7f030017
- invoke-virtual {v2, v3}, Lme/isming/myapplication/MainActivity;->setContentView(I)V
- .line 19
- move-object v2, v0
- move-object v3, v0
- const v4, 0x7f08003f
- invoke-virtual {v3, v4}, Lme/isming/myapplication/MainActivity;->findViewById(I)Landroid/view/View;
- move-result-object v3
- check-cast v3, Landroid/widget/TextView;
- iput-object v3, v2, Lme/isming/myapplication/MainActivity;->mTextView:Landroid/widget/TextView;
- .line 21
- move-object v2, v0
- iget-object v2, v2, Lme/isming/myapplication/MainActivity;->mTextView:Landroid/widget/TextView;
- new -instance v3, Ljava/lang/StringBuilder;
- move-object v7, v3
- move-object v3, v7
- move-object v4, v7
- invoke-direct {v4}, Ljava/lang/StringBuilder;-><init>()V
- const -string v4, "a+b="
- invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- move-result-object v3
- const / 4 v4, 0x1
- const / 4 v5, 0x2
- invoke- static {v4, v5}, Lme/isming/myapplication/MainActivity;->sum(II)I
- move-result v4
- invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
- move-result-object v3
- const -string v4, "a>b?"
- invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- move-result-object v3
- move-object v4, v0
- const / 4 v5, 0x1
- const / 4 v6, 0x2
- invoke-direct {v4, v5, v6}, Lme/isming/myapplication/MainActivity;->max(II)Z
- move-result v4
- invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Z)Ljava/lang/StringBuilder;
- move-result-object v3
- const -string v4, "5 accumulate:"
- invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
- move-result-object v3
- move-object v4, v0
- const / 4 v5, 0x5
- invoke-direct {v4, v5}, Lme/isming/myapplication/MainActivity;->accumulate(I)I
- move-result v4
- invoke-virtual {v3, v4}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
- move-result-object v3
- invoke-virtual {v3}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
- move-result-object v3
- invoke-virtual {v2, v3}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
- .line 23
- return - void
- .end method
References Finally, some references: http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html https://code.google.com/p/smali/w/list http://www.miui.com/thread-409543-1-1.html Original URL: http://blog.isming.me/2015/01/14/android-decompile-smali/ |