APK decompilation tutorial novice lesson 1: Android Basics

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:

  1. mt manager It's better to open a vip Support big man

On the computer side:

  1. AndroidKillern
  2. 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

Added by itsinmyhead on Fri, 21 Jan 2022 21:49:15 +0200