Android decompilation and Secondary packaging

Source: Internet
Author: User

Android decompilation and Secondary packaging

As an Android developer, it is essential to decompile other people's apk at work. Of course, the main purpose is to learn more, take the leader and make up for yourself. Today I will summarize some knowledge about Android decompilation and secondary packaging. The purpose of this article is to explain the principles and methods of decompilation and secondary packaging through examples, and then serve as the basis for subsequent explanations to prevent secondary packaging and App security, it does not encourage everyone to repackage others' apps to steal the fruits of others' work.

This article first introduces the use of several Android decompilation tools, and then implements the purpose of modifying the apk logic function by modifying the decompilation smali file without the need to know the source code.

There are three decompilation tools commonly used in Android: dex2jar, jd-gui, and apktool. The functions of these tools are as follows:

Dex2jar: Convert the classes. dex file in the apk to a jar file.

Jd-gui: view the jar file converted from dex2jar and display the decompiled Java source code in the form of an interface.

Apktool: decompile and generate the smali bytecode file to extract the resource file in the apk.

To clarify the problem as much as possible, we will implement a very simple example. First, create a project DecompileDemo and define a layout in MainActivity, which contains a Button. Click it to print a piece of log.

 

public class MainActivity extends AppCompatActivity implements View.OnClickListener {    private static final String TAG = "MainActivity";    private Button btn;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btn = (Button) findViewById(R.id.btn);        btn.setOnClickListener(this);    }    @Override    public void onClick(View v) {        Log.d(TAG,"Button is clicked");    }}
Decompress the apk generated by this project compilation, and put classes. dex in the directory of dex2jar, and then execute the command

 

The class-dex2jar.jar file is generated under the current directory

Then open jd-gui, drag the class-dex2jar.jar file in, you can see the decompiled source code.

We can see that the decompiled code is not much different from the original code. The main difference is that all the original resource references are converted into numbers.

Next we will modify the apk content.

First we copy the apk to the apktool directory and execute the command apktool d app-release.apk.

The generated directory contains the smali folder.

Then find our main class MainActivity. smali. The file content is as follows:

 

.class public Lcom/viclee/decompiledemo/MainActivity;.super Landroid/support/v7/app/AppCompatActivity;.source "MainActivity.java"# interfaces.implements Landroid/view/View$OnClickListener;?# static fields.field private static final TAG:Ljava/lang/String; = "MainActivity"# instance fields.field private btn:Landroid/widget/Button;# direct methods.method public constructor 
 
  ()V    .locals 0    .prologue    .line 9    invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;->
  
   ()V    return-void.end method# virtual methods.method public onClick(Landroid/view/View;)V    .locals 2    .param p1, "v"    # Landroid/view/View;    .prologue    .line 23    const-string v0, "MainActivity"    const-string v1, "Button is clicked"    invoke-static {v0, v1}, Landroid/util/Log;->d(Ljava/lang/String;Ljava/lang/String;)I    .line 24    return-void.end method.method protected onCreate(Landroid/os/Bundle;)V    .locals 1    .param p1, "savedInstanceState"    # Landroid/os/Bundle;    .prologue    .line 14    invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V    .line 15    const v0, 0x7f040019    invoke-virtual {p0, v0}, Lcom/viclee/decompiledemo/MainActivity;->setContentView(I)V    .line 17    const v0, 0x7f0c0050    invoke-virtual {p0, v0}, Lcom/viclee/decompiledemo/MainActivity;->findViewById(I)Landroid/view/View;    move-result-object v0    check-cast v0, Landroid/widget/Button;    iput-object v0, p0, Lcom/viclee/decompiledemo/MainActivity;->btn:Landroid/widget/Button;    .line 18    iget-object v0, p0, Lcom/viclee/decompiledemo/MainActivity;->btn:Landroid/widget/Button;    invoke-virtual {v0, p0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V    .line 19    return-void.end method
  
 

Lines 36-40 are the locations where logs are printed, and the file content is clear. The meaning of each region is as follows:

. Class name

. Super parent class name

. Source File Name

. Implements interface implemented by this class

. Field member variable

. Method

Create a new project and implement the Code to be replaced in this project. Here we want to replace the place where the log is printed in the original project with a Toast.

 

Public class MainActivity extends AppCompatActivity {@ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); showToast ();} public void showToast () {Toast. makeText (this, "I modified it after decompiling. ", Toast. LENGTH_LONG). show ();}}

Then run the apktool command as before. The generated smali file is as follows:

 

 

.class public Lcom/viclee/decompiledemo/MainActivity;.super Landroid/support/v7/app/AppCompatActivity;.source "MainActivity.java"# direct methods.method public constructor 
   
    ()V    .locals 0    .prologue    .line 7    invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;->
    
     ()V    return-void.end method# virtual methods.method protected onCreate(Landroid/os/Bundle;)V    .locals 1    .param p1, "savedInstanceState"    # Landroid/os/Bundle;    .prologue    .line 10    invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V    .line 11    const v0, 0x7f040019    invoke-virtual {p0, v0}, Lcom/viclee/decompiledemo/MainActivity;->setContentView(I)V    .line 13    invoke-virtual {p0}, Lcom/viclee/decompiledemo/MainActivity;->showToast()V    .line 14    return-void.end method.method public showToast()V    .locals 2    .prologue    .line 17    const-string v0, "\u6211\u662f\u53cd\u7f16\u8bd1\u540e\u8fdb\u884c\u7684\u4fee\u6539\u3002"    const/4 v1, 0x1    invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;    move-result-object v0    invoke-virtual {v0}, Landroid/widget/Toast;->show()V    .line 18    return-void.end method
    
   

In the above Code, lines 33 and 39-56 are the code section of the pop-up Toast. Copy the entire showToast method to the smali file of the original project. Pay special attention to modifying the line number. This line number indicates the line number of the Code in the original Java file, you need to refer to the row numbers of the two smali files to modify. In my opinion, you only need to ensure that the row numbers in the method are not in disorder and that the row numbers between methods do not conflict. Then, you need to replace the code for printing logs in the original project with the code for displaying Toast, that is, change lines 36-40 in the original smali file to lines 33 and 39-56 in the new project. The modified content is as follows, mainly focusing on the differences between lines 36 and lines 75-91 in the following content and the original smali file.

 

.class public Lcom/viclee/decompiledemo/MainActivity;.super Landroid/support/v7/app/AppCompatActivity;.source "MainActivity.java"# interfaces.implements Landroid/view/View$OnClickListener;# static fields.field private static final TAG:Ljava/lang/String; = "MainActivity"# instance fields.field private btn:Landroid/widget/Button;# direct methods.method public constructor 
     
      ()V    .locals 0    .prologue    .line 9    invoke-direct {p0}, Landroid/support/v7/app/AppCompatActivity;->
      
       ()V    return-void.end method# virtual methods.method public onClick(Landroid/view/View;)V    .locals 2    .param p1, "v"    # Landroid/view/View;    .prologue    .line 23    invoke-virtual {p0}, Lcom/viclee/decompiledemo/MainActivity;->showToast()V    .line 24    return-void.end method.method protected onCreate(Landroid/os/Bundle;)V    .locals 1    .param p1, "savedInstanceState"    # Landroid/os/Bundle;    .prologue    .line 14    invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V    .line 15    const v0, 0x7f040019    invoke-virtual {p0, v0}, Lcom/viclee/decompiledemo/MainActivity;->setContentView(I)V    .line 17    const v0, 0x7f0c0050    invoke-virtual {p0, v0}, Lcom/viclee/decompiledemo/MainActivity;->findViewById(I)Landroid/view/View;    move-result-object v0    check-cast v0, Landroid/widget/Button;    iput-object v0, p0, Lcom/viclee/decompiledemo/MainActivity;->btn:Landroid/widget/Button;    .line 18    iget-object v0, p0, Lcom/viclee/decompiledemo/MainActivity;->btn:Landroid/widget/Button;    invoke-virtual {v0, p0}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V    .line 19    return-void.end method.method public showToast()V    .locals 2    .prologue    .line 27    const-string v0, "\u6211\u662f\u53cd\u7f16\u8bd1\u540e\u8fdb\u884c\u7684\u4fee\u6539\u3002"    const/4 v1, 0x1    invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;    move-result-object v0    invoke-virtual {v0}, Landroid/widget/Toast;->show()V    .line 28    return-void
      
     

 

Then we need to repackage the modified file directory and run the apktool B app-release command to generate two folders under the app-releae directory: the build folder contains some intermediate files (classes. the dist folder contains the re-packaged apk file.

Remember to sign the generated apk. Otherwise, an error will be reported during installation. Execute the following command line:

Jarsigner-verbose-keystore viclee. keystore-signedjar app-release-signed.apk app-release.apk viclee. keystore

-Verbose outputs Signature Details
-Keystore: Specifies the storage path of the key pair.
-The three parameters after signedjar are the signed apk, unsigned apk, and key pair alias.

After installing the signed apk, click the button and the Toast is displayed. The content is consistent with what we set, indicating that the modification is successful.

We have noticed that the modification of the smali file is not directly modified on the file. After all, it is very difficult to directly modify the smali file because of its poor readability. Our solution is to create a new project and implement the Code that needs to be added. We 'd better combine it into a separate method (for easy replacement), and then decompile the apk generated by packaging the new project, obtain the corresponding smali file, and replace the original smali file with the content. This modification method reduces the difficulty of modification and the risk of making mistakes.

In addition, you can modify the resources after decompiling the apk, modify the decompiled resource files, and repackage, sign, and install the files according to the previous method. The following two pages show the comparison between the modified and modified pages.

 

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.