Steamed rice. 2015/05/15 10:01

0 x00 sequence

As mobile security becomes more and more popular, various debugging tools emerge in an endless stream. However, due to different environments and requirements, no tool is a panacea. Tools are dead, people are alive, and if you can understand the principles of tools combined with your own experience, you can create your own debugging weapons. Therefore, the author will share some frequently used or original debugging tools and means in this series of articles, hoping to play a catalytic role in domestic mobile security research.

The directory is as follows:

Android dynamic debugging seven weapons of the eternal sword – Smali Instrumentation

Android dynamic debugging of seven weapons – Ida

Android dynamic debugging of seven weapons parting hook – Hooking

Android Dynamic debugging seven weapons – Customized DVM

Android dynamic debugging seven weapons – Customized Kernel

Android dynamic debugging of seven weapons of the Overlord gun – Anti Anti-debugging

Android Dynamic Debugging of 7 Weapons fists – Tricks & Summary

0 x01 immortality sword

Changsheng jian is a magical sword, matched by Bai Yujing. The name of the sword comes from a poem by Li Bai: “The immortal touches my head, and when I grow my hair, I will live forever.” Changsheng Sword is the first weapon in the series of seven weapons, and the debugging method I will introduce next is also the first debugging method I learned, and this method is just like Changsheng sword, simple and always has good effects. This method is Smali Instrumentation, also known as Smali piling. The biggest advantage of using this method is that you don’t need to root your phone, you don’t need to specify the android version, and it can have unexpected effects when combined with tricks.

0x02 Smali/baksmali

The first thing you will encounter when doing android reverse is smali language. Smali was first proposed by Jasmin, and then jesusfreke developed the most famous smali and baksmali tools to carry it forward. Almost all static analysis tools on dex are built on the basis of this project. What? You haven’t heard of Smali and Baksmali? You’ve only used Apktool? If you read the description on the Apktool website carefully, you will see that Apktool is really just a lazy tool combining various tools. And I recommend ditching Apktool for now. The reasons are as follows: First, Apktool updates are not as frequent as smali/ Baksmali updates, and smali/ Baksmali updates take a very short time to merge into Apktool, before which you may have to put up with a lot of weird bugs. Second, Apktool will only provide error exception information when decompiling or repacking dex. However, if you use smali/baksmali, the tool will tell you the specific error cause, which is of great help to debugging after repacking. Finally, many APKs try to counter counter debugging by adding a lot of junk code to the resource files, causing Apktool parsing to crash, decompiling to fail, or failing to repackage. But you won’t have these problems if you only use classes.dex.

The best way to learn smALI is to write your own programs in Java, convert them into SMALI statements using Baksmali, and then learn from them. For example, here is a comparative analysis of the Java code and the decompilated smali file using Baksmali.

The MZLog class mainly uses log.d () to output debugging information. The Java code is as follows:

package com.mzheng;

public class MZLog {

    public static void Log(String tag, String msg)
        Log.d(tag, msg);

    public static void Log(Object someObj)
        Log("mzheng", someObj.toString());

    public static void Log(Object[] someObj)

Copy the code

The corresponding smali code is as follows:

#! bash .class public Lcom/mzheng/MZLog; # class name. Super Ljava/lang/Object; Method public constructor <init>()V # This is a class constructor implementation Registers 1 # The number of registers used by this method. Prologue # prologue is not useful. Return -void # return null.end method. method public static Log(Ljava/lang/Object) Registers 3. Param P0, "someObj" # Ljava/lang/Object; Prologue. Line 16 const-string v0, "mZHENG" # assign "mzheng" invoke-virtual {p0}, Ljava/lang/Object; ->toString()Ljava/lang/String; # save toString() to v1 invoke-static {v0, v1}, Lcom/mzheng/MZLog; ->Log(Ljava/lang/String; Ljava/lang/String;) Line 17 return-void. End method. method public static Log(Ljava/lang/String; Ljava/lang/String;) Registers 2. Param P0, "tag" # Ljava/lang/String; registers 2. .param p1, "msg" # Ljava/lang/String; .prologue .line 11 invoke-static {p0, p1}, Landroid/util/Log; ->d(Ljava/lang/String; Ljava/lang/String;) Line 12 return-void. End method. Method public static Log([Ljava/lang/Object; Registers 3. Param p0, "someObj" # [Ljava/lang/Object;  .prologue .line 21 const-string v0, "mzheng" invoke-static {p0}, Ljava/util/Arrays;->toString([Ljava/lang/Object; Invoke-static {v0, v1}, Lcom/mzheng/MZLog; ->Log(Ljava/lang/String;Ljava/lang/String;)V # call Log(String, String).line 22 return-void. End methodCopy the code

Finally, a brief description of the data types commonly used by SmALI:

V - void
Z - boolean
B - byte
S - short
C - char
I - int
J - long (64 bits)
F - float
D - double (64 bits)
Copy the code

0 x03 Smali pile

If you just use Smali to analyze your code, it’s not as intuitive as using Dex2JAR and JD-GUI, because it’s easier to see decomcompiled Java code. But Smali’s strength is its ability to pile at will. What is piling? To quote wiki: Program of pile, the earliest is put forward by professor J.C. Huang, it is in guarantee the program to be measured in a program on the basis of the original logical integrity some probes (also known as the “instrument”), through the execution of the probe and throw the characteristics of the program is running data, through the analysis of these data, can get the program control flow and data flow information, Then the dynamic information such as logical coverage is obtained, so as to achieve the test purpose. Now I will combine an example to explain how to carry out SMALI piling.

The test program is a simple Crackme (Figure 1). Enter the password and click Check. If the password is correct, it will print yes, otherwise it will print no.

Figure 1 Interface of Crackme1

First we unzip the CRACKme apK and decompile it. We’ll see a getKey (String,int) function in MainActivity. This seems like a very complicated function, so let’s leave it at that. Let’s start by analyzing the logic behind button. We found that the program calculates the real password using getKey (“mrkxqcroxqtskx”,42), and then compares it with the password we entered. The Java code looks like this:

#! java public void onClick(View arg0) { String str = editText0.getText().toString(); if (str.equals(getkey("mrkxqcroxqtskx",42))) { Toast.makeText(MainActivity.this,"Yes!" , Toast.LENGTH_LONG).show(); } else { Toast.makeText(MainActivity.this,"No!" , Toast.LENGTH_LONG).show(); }}Copy the code

This is the time for smali peg to show its skill, we can directly get getKey (“mrkxqcroxqtskx”,42) this function return value, and then Log out. So we don’t need to study the implementation of getKey. The specific process is as follows:

1 Decompress apk first and decompile with baksmali.

unzip crackme1.apk
java -jar baksmali-2.0.3.jar classes.dex
Copy the code

2 copy the mzlog. smali file from the MZLog class in the previous section to the com/mzheng directory. This file has three LOG functions, which can output String values, Object values, and Object array values respectively. Note that if the original program does not have the directory com/mzheng, you will need to create it yourself using mkdir. The directory structure is as follows:

├ ─ sci-imp (1), sci-imp (2), sci-imp (2), sci-imp (2), sci-imp (2), sci-imp (2), sci-imp (2), sci-imp (3), sci-imp (3), sci-imp (3), sci-imp (3), sci-imp (3 R$dimen.smali R$drawable.smali R$id.smali R$layout.smali R$menu.smali R$string.smali R$style.smali R.smaliCopy the code

3 Use a text editor to open the MainActivity$1.smali file for staking. Why MainActivity$1.smali instead of MainActivity. Smali? Because the main judgment logic is in the OnClickListener class, which is an inner class of MainActivity, and we didn’t specify a name for this class at implementation time, this class is represented by $1. After adding the mzlog. smali file, we just need to add the following line to MainActivity$1.smali: invoke-static {v1}, Lcom/mzheng/MZLog; ->Log(Ljava/lang/Object;) V to print the value of getKey. Invoke is a method invocation instruction, and since the class we are calling is a static method, invoke-static is used. For non-static methods, the first argument should be an instance of the method, followed by each argument. The specific insertion situation is as follows:

const-string v1, "mrkxqcroxqtskx" const/16 v2, 0x2a # invokes: Lcom/mzheng/crackme1/MainActivity; ->getkey(Ljava/lang/String; I)Ljava/lang/String; invoke-static {v1, v2}, Lcom/mzheng/crackme1/MainActivity; ->access$0(Ljava/lang/String; I)Ljava/lang/String; move-result-object v1 ############################## begin ############################## invoke-static {v1}, Lcom/mzheng/MZLog; ->Log(Ljava/lang/Object;) V ############################## end ############################### invoke-virtual {v0, v1}, Ljava/lang/String; ->equals(Ljava/lang/Object;) Z move-result v1Copy the code

4 Use smali.jar to compile the modified smali file, overwrite the old classes.dex with the compiled classes, and use signapk.jar to sign the APK. The key instructions are as follows:

#! bash java -jar smali.jar out java -jar signapk.jar testkey.x509.pem testkey.pk8 update.apk update_signed.apkCopy the code

5. Install the program on Android, type anything, click the Check button, and see the return value of getKey (” mrkxqCroxqtskx “,42) in logcat (Figure 2).

Figure 2. Get the return value of getKey by logcat

0 x03 Smali modification

With Smali/ Baksmali tools, we can not only peg, but also modify the logic of APK. A few points to note are as follows:

1. If condition judgment and jump statement

The most common type of conditional jump statement in SMALI is the if conditional jump statement, which has 12 instructions:

#! Bash if-eq vA, VB, cond_** jump to cond_** if vA equals VB If (vA==vB) if-ne vA, vB, cond_** if vA is not equal to vB, cond_** Equivalent to if (vA! =vB) if-lt vA, vB, cond_** jump to cond_** if vA is less than vB. If (vA<vB) if-le vA, vB, cond_** if vA<vB, cond_** If (vA<=vB) if-gt vA, vB, cond_** cond_** If (vA>vB) if-ge vA, vB, cond_** if vA>vB, cond_** If (vA>=vB) if-eqz vA, :cond_** if (vA ==0) if-nez vA, :cond_** If (vA ==0) if-eqz vA, :cond_** If (vA <0) if-lez vA, :cond_** if (vA <0) if-lez vA, Cond_ ** if (vA <=0) if-gtz vA, cond_** if (vA >0) if-gez vA, cond_** if (vA >0) if-gtz vA, cond_** if (vA >0) if-gez vA, Cond_ ** if (vA >=0) :cond_** if (vA >=0)Copy the code

For example, the smali code snippet we used in Crackme1 to determine if the password is correct:

#! bash invoke-virtual {v0, v1}, Ljava/lang/String; ->equals(Ljava/lang/Object;) Z move-result v1 if-eqz v1, :cond_25 # if (v1==0) iget-object v1, p0, Lcom/mzheng/crackme1/MainActivity$1; ->this$0:Lcom/mzheng/crackme1/MainActivity; const-string v2, "Yes!" invoke-static {v1, v2, v3}, Landroid/widget/Toast; ->makeText(Landroid/content/Context; Ljava/lang/CharSequence; I)Landroid/widget/Toast; move-result-object v1 invoke-virtual {v1}, Landroid/widget/Toast; ->show()V :cond_25 iget-object v1, p0, Lcom/mzheng/crackme1/MainActivity$1; ->this$0:Lcom/mzheng/crackme1/MainActivity; const-string v2, "No!" invoke-static {v1, v2, v3}, Landroid/widget/Toast; ->makeText(Landroid/content/Context; Ljava/lang/CharSequence; I)Landroid/widget/Toast; move-result-object v1 invoke-virtual {v1}, Landroid/widget/Toast; ->show()VCopy the code

If we don’t care about the password and just want the program to print “yes”. We can change if-eqz v1, :cond_25 to if-nez v1, :cond_25. The logic goes like this: When you enter a wrong password, the program will print “yes” instead.

2. Register problems

One important thing to keep in mind when modifying Smali is the registers. Messing with registers can crash your program. The method begins with a declaration of the number of registers, which is the sum of parameters and local variables. All parameters are represented by P. If the method is non-static, p0 represents this and p1-pn represents individual parameters. For static methods, p0-pn represents each parameter. Local variables are uniformly represented by v. If you want to add new local variables, add the corresponding value to the registers number at the beginning of the method.

For example, this method:

#! bash .method public constructor <init>()V .registers 1 .prologue .line 7 invoke-direct {p0}, Ljava/lang/Object; -><init>()V return-void .end methodCopy the code

Since this is not a static method, p0 stands for this. If you want to add a new local variable, say v0. So I’m going to have to change.registers 1 to.registers 2.

3. A way to add a lot of logic to the original program

I strongly advise against adding a lot of logic to a program’s existing methods, as this can lead to a lot of register errors that cause compilations to fail. A better method is to first write the logic you want to add into an APK in Java, and then decompile the APK into a SmALI file. Then insert the smALI file of the decompilated part of the logic into the smALI folder of the target program, and invoke the newly added logic on the original method. In this case, no matter how much logic is added, only a few lines of the original program are changed. This idea is also a common trick used by many viruses to repackage, and it is very convenient to use.

0x04 APK signature Tricks

When we are in the field, we sometimes encounter apKs that implement their own signature checks internally. The Smali Instrumentation method we introduced this time will change the original signature because it needs to be repackaged. Of course, you can remove the logic for checking signatures by modifying APK, but this is time-consuming and laborious. The author here briefly introduces two very convenient methods to solve the problem of signature checking.

1. Masterkey

There are three Masterkey vulnerabilities that can affect Android versions below 4.4. Using this vulnerability, we can replace the classes.dex with a new one without re-signing the APK itself. If APK itself has signature verification logic, this vulnerability is perfect for Smali Instrumentation. First, you need a virtual machine or a real machine with android version 4.4 or lower, and then exploit apK using a MasterKey exploit tool. At the end of the article, use the following command:

#! bash java -jar AndroidMasterKeys.jar -a orig.apk -z -o out.apkCopy the code

Orig. Apk is the original APK file. ModdedClassesDex. If you successfully open the file with rar, you’ll see two classes.dex.

Figure 3. The APK file generated by Masterkey has two classes.dex files

The apK file signature packaged by MasterKey will not have any change, so there is no need to worry about signature verification.

2. Customize ROM

If we can customize ROM, we just need to modify the libcore\luni\ SRC \main\ Java \ Java \security\MessageDigest. Java file in AOSP source path. Comment out the judgment statement in the isEqual function:

#! java public static boolean isEqual(byte[] digesta, byte[] digestb) { if (digesta.length ! = digestb.length) { return false; } // for (int i = 0; i < digesta.length; i++) { // if (digesta[i] ! = digestb[i]) { // return false; // } // } return true; }Copy the code

That way, if you run APk on your own ROM, no matter how much you modify the classes.dex file, you don’t need to worry about the signature, and the system will always return the correct signature.

0 x05 summary

Although now more and more APK began to use so files for logic processing and reinforcement, Android 4.4 also added art runtime environment, but Dalvik will always be the most classic thing in Android. If you want to learn Android reverse, be sure to learn this part of the knowledge. And after a thorough study of SMALI, it will be of great help to the customized Dalvik VIRTUAL machine we will talk about in the future. In addition all the mentioned in the article code and tools can be downloaded in my lot to address is:

0x06 Reference article

Way of the AndroidCracker

Android Master Key Exploit – Uncovering Android Master Key

Min Zheng, Patrick P. C. Lee, John C. S. Lui. “ADAM: An Automatic and Extensible Platform to Stress Test Android Anti-Virus Systems”, DIMVA 2012