As an Android developer, the job is to decompile others ' apk, of course, the main purpose is to learn more, take the long, make up for the short. Let's summarize some of the knowledge about Android Decompile and two packaging today. First of all, the purpose of this article is to explain the principles and methods of decompile and two-pack by example, and then as a follow-up explanation to prevent two packaging and app security, not to encourage people to repackage others ' apps and steal the fruits of others ' labor.
This article first introduces the use of several Android decompile tools, and then realizes in the case of no need to know the source code, only modify the Smali file to achieve the purpose of modifying the APK logic function.
There are three commonly used decompile tools in Android: Dex2jar, Jd-gui, and Apktool, and these three tools work as follows:
Dex2jar: Converts the Classes.dex file in apk into a jar file.
Jd-gui: View the jar file converted by Dex2jar to display the reverse-compiled Java source code in the form of an interface.
Apktool: decompile generates Smali bytecode files and extracts resource files from APK.
To make the problem as clear as possible, let's implement a very simple example. First create a project Decompiledemo, define a layout in Mainactivity, which contains a button, click to print a 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 ');
}
Extract the APK from this engineering compilation, remove the Classes.dex in the Dex2jar tool directory, and execute the command
Class-dex2jar.jar files are generated in the current directory
Then open the Jd-gui, drag the Class-dex2jar.jar file in, you can see the reverse-compiled source code.
You can see that the decompile code differs little from the original code, and the main difference is that the original resource references all become numbers.
Let's modify the contents of this apk.
First we copy the APK to the Apktool tool 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 contents of the file are 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 <init> () v. Locals 0 prologue. Line 9 Invoke-direct {p0}, Landr Oid/support/v7/app/appcompatactivity;-><init> () V return-void. Method # virtual methods.
Click (Landroid/view/view) v. Locals 2 param p1, "v" # Landroid/view/view; . Prologue. Line 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 return-void. protected onCreate (Landroid/os/bundle;) v. Locals 1 . param P1, "savedinstancestate" # LanDroid/os/bundle; . Prologue. Line Invoke-super {p0, p1}, Landroid/support/v7/app/appcompatactivity;->oncreate (Landroid/os/Bundle ;) v. Line const V0, 0x7f040019 invoke-virtual {p0, v0}, Lcom/viclee/decompiledemo/mainactivity;->setcontentv Iew (I) v. Line const V0, 0x7f0c0050 invoke-virtual {p0, v0}, Lcom/viclee/decompiledemo/mainactivity;->findvie
Wbyid (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 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 Return-void.
36-40 of these lines are the location of the print log, the contents of the file are clear, and each area has the following meanings:
. Class Name
. Super Parent class name
. source file Name
. Implements interface implemented by this class
. field member variables
. Method methods
Then create a new project to implement the code you want to replace in this project, where we want to replace the print log in the original project with a pop-up 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 am a modified after decompile.) ", Toast.length_long). Show ();
}
Then execute the apktool command as before, and the resulting Smali file contents are as follows:
. class public lcom/viclee/decompiledemo/mainactivity;. Super landroid/support/v7/app/appcompatactivity;. source Mainactivity.java "# Direct methods. Method public Constructor <init> () v. Locals 0 prologue. Line 7 Invo Ke-direct {p0}, landroid/support/v7/app/appcompatactivity;-><init> () V return-void. End Method # Virtual Meth
ODS. Method protected OnCreate (Landroid/os/bundle;) v. Locals 1 param p1, "savedinstancestate" # landroid/os/bundle; . Prologue. Line Invoke-super {p0, p1}, Landroid/support/v7/app/appcompatactivity;->oncreate (Landroid/os/Bundl e;) v. Line one const V0, 0x7f040019 invoke-virtual {p0, v0}, Lcom/viclee/decompiledemo/mainactivity;->setcontent View (I) v. line invoke-virtual {p0}, Lcom/viclee/decompiledemo/mainactivity;->showtoast () v. Line return- void. Method public Showtoast () v. Locals 2 prologue. Line Const-string V0, \u6211\u662f\u53cd\u 7f16\u8bd1\u540e\u8fdb\u884c\u7684\u4fee\u6539\u3002 "CONST/4 v1, 0x1 invoke-static {p0, V0, v1}, Landroid/widget/toast;->maketext (Landroid/conte Nt/context;
Ljava/lang/charsequence;i) Landroid/widget/toast; Move-result-object v0 invoke-virtual {v0}, Landroid/widget/toast;->show ()-return-void.
in the above code, 33, 39-56 lines is the part of the code that pops up toast. Copy the entire Showtoast method above to the original project's Smali file, paying special attention to modifying the line number, which represents the line number of the code in the original Java file, which needs to be modified by reference to the line number of the two Smali file. I think that as long as the line number within the method is not disorderly, and the line number between the methods does not conflict. Then, you need to replace the code for the print log in the original project with the code that displays toast, which is to modify 36-40 lines in the original Smali file to the contents of 33, 39-56 lines in the new project. The revised content is as follows, mainly focus on the following 36 lines, 75-91 lines and the original Smali file differences.
. 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 <init> () v. Locals 0 prologue. Line 9 Invoke-direct {p0}, Landr Oid/support/v7/app/appcompatactivity;-><init> () V return-void. Method # virtual methods.
Click (Landroid/view/view) v. Locals 2 param p1, "v" # Landroid/view/view; . Prologue. Line invoke-virtual {p0}, Lcom/viclee/decompiledemo/mainactivity;->showtoast () V-line return- void. End method-Method protected OnCreate (Landroid/os/bundle;) v. Locals 1 param p1, "savedinstancestate" # Landro
Id/os/bundle; . Prologue. Line Invoke-super {p0, p1}, landroid/support/v7/App/appcompatactivity;->oncreate (Landroid/os/bundle) v. Line const V0, 0x7f040019 invoke-virtual {p0, v0}, L Com/viclee/decompiledemo/mainactivity;->setcontentview (I) v. Line 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 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 Return-void.-Method Public Showtoast () v. Locals 2 prologue. Line const-string V0, "\u6 211\u662f\u53cd\u7f16\u8bd1\u540e\u8fdb\u884c\u7684\u4fee\u6539\u3002 "CONST/4 v1, 0x1 invoke-static {p0, V0, v1}, L Android/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 return-void
Then we need to repackage the modified file directory and execute the command Apktool b app-release, which will generate two folders in the App-releae directory: The build folder contains some intermediate files (Classes.dex, etc.), dist The folder contains the repackaged apk files.
Finally, remember to sign the generated apk, or you will get an error when you install it. Execute the following command line:
Jarsigner-verbose-keystore Viclee.keystore-signedjar app-release-signed.apk app-release.apk viclee.keystore
-verbose Output Signature Details
-keystore the storage path for the specified key pair
-signedjar The following three parameters are signed apk, unsigned apk, and the alias of the key pair
After the signing of the APK, click the button, did pop up toast, the content and we set the consistent, indicating that our changes succeeded.
We note that the modification of the Smali file is not directly in the file to modify, after all, Smali file readability, direct modification is very difficult. Our solution is to create a new project will need to increase the code implementation, preferably a separate method (convenient replacement), and then the new project packaging generated apk decompile, get the corresponding Smali file, and then use the contents of the original Smali file to replace. This modification reduces the difficulty of modification and reduces the risk of making mistakes.
In addition, APK can also modify the resources, the reverse-compiled resource file to modify a pass, and then in accordance with the previous method, repackaged, signed, installed. The following two pages are a comparison before and after modification.
Here, the entire content of this article is finished, welcome everyone comments Exchange ~