APK decompilation tutorial novice lesson 1: Android Basics
APK, Dalvik bytecode, and smali files
Learning route
Please click to view the blog post
Reverse common tools
On the mobile phone:
- mt manager It's better to open a vip Support big man
On the computer side:
- AndroidKillern
- jadx-gui-1.0.0
APK file basic structure
• assets\ <Resource directory 1: assets,Store some loaded resources.This is especially true for some common scripting tools, such as autojs,andlua,easyclick etc.> • lib\ <so Inventory location, generally by Android NDK Compiled, common in the use of game engines or JNI native In the called Project,Research is not recommended for beginners so> • |---armeabi\ |---<so Library files are divided into different types CPU framework> • |---armeabi-v7a <so Library files are divided into different types CPU framework.x86,arm • META-INF\ <Store some signature documents of the project, such as Manifest.MF.Can use v1 autograph bug Signature verification> • res\ <Resource directory 2: generally, pictures and layouts are stored xml file> • |---drawable\ |---<Picture and corresponding xml resources> • |---layout\ |---<Defines the of the layout xml resources> • |---... • AndroidManifest.xml <Android Basic configuration properties file of the project.It can usually be modified app Package name> • classes.dex <Java Code compiled Dalvik VM The files directly executed by the virtual machine are introduced below> • resources.arsc <yes res An index file of resources under the directory, which can usually be modified app name>
Note: the difference between asset and res resource directories lies in:
Generally speaking, in addition to audio and video resources (which need to be placed under raw or asset), the resource files used by Android projects developed in Java will be placed under res
Dalvik bytecode
Dalvik is a virtual machine specially designed by google for Android operating system, which has been deeply optimized. Although programs on Android are developed using java, Dalvik and the standard java virtual machine JVM are two different things. Dalvik VM is register based, while JVM is stack based; Dalvik has its own file execution format, dex (dalvik executable), while the JVM executes java bytecode. Dalvik VM is faster and takes less space than JVM. Of course, more art virtual machines are used now The difference is
ART (Android RunTime) virtual machine adopts AOT (ahead of time) technology, which is converted into machine language (before running) when the application is installed, and is no longer interpreted during execution, so as to optimize the speed of application running.
Dalvik is Android 4 4. The virtual machine previously used uses JIT (just in time) technology for code translation. It is compiled into machine language for execution every time the application is executed (runtime).
In reverse, the difference is not too great At the same time, Dalvik can find the most information It's convenient for everyone to understand, so we'll use Dalvik directly
It should be noted that:
Through Dalvik's bytecode, we can't directly see the original logic code. At this time, we need to use tools such as Apktool or dex2jar + JD GUI to help us view it. However, it should be noted that the files we need to modify APK are The smali file, rather than the exported Java file, is recompiled (besides, this is basically impossible).
smali file
Here are the key points: smali and its syntax
One key point: some people say
smali can be converted to java, so can we directly convert to java and repackage it to run?
No, the converted java is pseudo code If you can't use it directly, you will find that most of them can't run It needs to be modified before it can run
In fact, the transfer out is mainly to help us analyze
In short, smali is the core code executed inside Dalvik VM. It has its own set of syntax, which will be introduced below. Children's shoes with JNI development experience can quickly understand it.
1, Data type of smali
In smali, the data type is the same as that in Android, except that the corresponding symbol changes:
Smali basic grammar
.field private isFlag:z Define variables .method method .parameter Method parameters .prologue Method start .line 12 This method is on line 12 invoke-super Call parent function const/high16 v0, 0x7fo3 Put 0 x7fo3 Assign to v0 invoke-direct Call function return-void Function return void .end method End of function new-instance Create instance iput-object Object Assignment iget-object Call object invoke-static Call static function ============ Conditional jump branch(Most commonly used.): nez change eqz,eq change ne This kind of logic is reversed to achieve the purpose of cracking. among eq be equal to ne Not equal to z yes zero(0)Abbreviation for therefore eqz Is equal to 0 nez Is not equal to 0 "if-eq vA, vB, :cond**" If vA be equal to vB Then jump to:cond** "if-ne vA, vB, :cond**" If vA Not equal to vB Then jump to:cond** "if-lt vA, vB, :cond**" If vA less than vB Then jump to:cond** "if-ge vA, vB, :cond**" If vA Greater than or equal to vB Then jump to:cond** "if-gt vA, vB, :cond**" If vA greater than vB Then jump to:cond** "if-le vA, vB, :cond**" If vA Less than or equal to vB Then jump to:cond** "if-eqz vA, :cond**" If vA If equal to 0, jump to:cond** "if-nez vA, :cond**" If vA Jump to if not equal to 0:cond** "if-ltz vA, :cond**" If vA Less than 0, jump to:cond** "if-gez vA, :cond**" If vA Greater than or equal to 0, jump to:cond** "if-gtz vA, :cond**" If vA If greater than 0, jump to:cond** "if-lez vA, :cond**" If vA Less than or equal to 0, jump to:cond** ============= if Functional java code: private boolean ifSense(){ boolean tempFlag = ((3-2)==1)? true : false; if (tempFlag) { return true; }else{ return false; } } if Function analysis: .method private ifSense()Z .locals 2 .prologue .line 22 const/4 v0, 0x1 // v0 is assigned to 1 .line 24 .local v0, tempFlag:Z if-eqz v0, :cond_0 // Judge whether v0 is equal to 0, go down if it does not meet the conditions, and execute cond if it meets the conditions_ 0 branch .line 25 const/4 v1, 0x1 // Eligible branch .line 27 :goto_0 return v1 :cond_0 const/4 v1, 0x0 // cond_0 branch goto :goto_0 .end method ###Text description: if it conforms to the if branch, the program goes down and finally returns; If the conditions are not met, you will go to: cond_0 branch, and finally execute goto: goto_0 walk back: goto_0 return ============ for function java code: private void forSense(){ listStr = new ArrayList(COUNT); for (int i = 0; i < COUNT; i++) { listStr.add("Now it's my turn to play"); } } for Function analysis: .line 40 const/4 v0, 0x0 .local v0, i:I :goto_0 if-lt v0, v3, :cond_0 // If LT determines that the value v0 is less than v3. If it does not comply, go down and comply with the execution branch: cond_0 .line 43 return-void .line 41 :cond_0 // label iget-object v1, p0, Lcom/example/smalidemo/MainActivity;->listStr:Ljava/util/List; // Reference object const-string v2, "\u73b0\u5728\u8f6e\u5230\u6211\u4e0a\u573a\u4e50" invoke-interface {v1, v2}, Ljava/util/List;->add(Ljava/lang/Object;)Z // List is an interface, so the interface method add is executed .line 40 add-int/lit8 v0, v0, 0x1 // Put the value in the second v0 register plus the value of 0x1 into the first register to realize self growth goto :goto_0 // Go back: goto_0 label const/4 v0, 0x0 On top, use v0 Local register and set the value to 0 x0 Save to v0 Medium 0 x0 That is 0,What about the usual reverse,Yes, the value is 0 x1
We have documented the complete syntax Interested can Direct download