Sorry, there are many things today, and the tutorials are coming soon. Please include them. It will be a little late in the next few days, but I will update it every day.
Today, let's take a closer look at the decompilation. If we want to modify an application and its code that comes with a system, we have to use the decompilation to modify the code without the source code.
Like many books, we also started helloactivity.apk from a simple program in order to respect the classic "Hello, world. After you install this APK on your phone and run it, a line of text "Hello, world!" is displayed on the screen! "(The world is coming! Yes, brothers and sisters. From today on, we are truly in the world of decompilation. We are here !)
1. Decompilation
For the convenience of introduction, from now on, I will use cracker ~ $ Is used as a command prompt, and the text after it indicates the command we need to run. If there are italics, it indicates the command output result.
Cracker ~ $ Apktool D helloactivity.apk
After this command is run, a directory named helloactivity is generated under the current directory.
The directory structure is (name followed by/indicates that this is a directory ):
Helloactivity/
| -------------- Androidmanifest. xml
| -------------- Apktool. yml
| -------------- Res/
| -------------- Smali/
Apktool. yml is a configuration file generated by apktool. Basically, you do not need to modify this file. The following sections describe the remaining androidmanifest. XML files, res, and smali directories one by one.
2. androidmanifest. xml
To fully understand this file, you have to be clear about the internal operating mechanism of Android. Fortunately, this file is basically not changed when we modify an APK. Here we will give you a general understanding.
The android installer is generally called an APK file (APK is the abbreviation of Android package, indicating the android installation package ). Generally, a program has one or more activities. What is an activity? In terms of concept, it is a window for user interaction, every day when you use an Android phone, basically every interface you are dealing with is an activity. Androidmanifest. XML is a configuration file in XML format, just like a shopping list, androidmanifest, is printed when you go to the supermarket to buy things. XML also acts as a list, which tells the system that I have these activities. (The actual situation is far more complex than this. For more information about Android programming, see http://developer.android.com/guide/index.html ).
You can find the androidmanifest. xml file in helloactivity as follows:
<Application
Android: Label = "@ string/app_name" Android: icon = "@ drawable/ic_launcher_hello">
<Activity Android: Name = "helloactivity">
<Intent-filter>
<Action Android: Name = "android. Intent. Action. Main"/>
<Category Android: Name = "android. Intent. Category. launcher"/>
</Intent-filter>
</Activity>
</Application>
One row contains <category Android: Name = "android. intent. category. launcher "/>, the activity containing this row will be displayed on the desktop, that is, you can start this activity through the icon displayed on the desktop. There is also Android: Label = "@ string/app_name" Android: icon = "@ drawable/ic_launcher_hello ". What are these two attributes? Android: label indicates the name of the program displayed on the desktop, Android: icon indicates the icon displayed on the desktop. If you want to change the display name and icon, modify the two resources and modify the resources, the next section will detail how to modify the resources.
3. Resources
All resources required by the program are stored in the res directory. What is a resource? Generally, a graphical user interface (GUI) program will always use some images or the size and color of the displayed text. Or the layout of the interface, such as text on the displayed interface and two buttons. An important feature of these programs is the separation of user interfaces and code logic. When we need to replace the image or simply modify the interface layout, we do not need to change the code. The android program puts all the files needed in these codes under the res directory, which is called a resource.
The contents of the res directory are as follows:
Res/
| -------- Drawable-hdpi/
| -----------Ic_launcher_hello.png
| -------- Layout/
| --------- Hello_activity.xml
| -------- Values/
| --------- IDs. xml
| --------- Public. xml
| --------- Strings. xml
For helloactivity, the res directory contains three subdirectories: drawable-hdpi, layout, and values. Helloactivity is relatively simple, so there is not much content under Res, but there will be more content under the res directory of a complicated program, but the basic principles are the same.
The subdirectories under Res are basically organized by resource type. The subdirectories starting with drawable indicate image resources. You may see drawable-hdpi, drawable-mdpi, drawable-ldpi, and so on, these hdpi, mdpi, and LPID indicate the high/medium/low resolution, and different images are selected based on different screen resolutions. To replace images, replace the images in these directories. (Replacing an image is a little more complex than this. It is recommended that you replace the image with the original image, such as the color, size, and parameters of the image ).
A Layout file starting with layout is used to describe the interface of the program. Anim sub-directories store animations used by programs, and directories starting with XML store some XML files used by programs.
The directories starting with values store some definitions that we call as basic elements. For example, colors. xml defines the color value and dimens. xml defines the size. Strings. XML is the definition of some strings. Let's take a look at the strings. xml file of hellloactivity.
<? XML version = "1.0" encoding = "UTF-8"?>
<Resources>
<String name = "hello_activity_text_text"> Hello, world! </String>
<String name = "app_name"> helloworld </string>
</Resources>
The string starting with <string is a string. name indicates the name of the resource, and the subsequent string indicates the value of the string. Android resources are organized in this way. The resources are divided into several types, and each type of resources is named by a name, this name corresponds to the value/content of the resource.
We generally modify resources by modifying images or Chinese images. It is relatively simple to Chinese. The values/strings. xml file stores all the English string values used by the program. First, create a directory values-ZH-RCN under values. Copy values/strings. XML to this directory and translate each string into Chinese. Copy strings. XML to the values-ZH-RCN directory and change the file content:
<? XML version = "1.0" encoding = "UTF-8"?>
<Resources>
<String name = "hello_activity_text_text"> Hello, world! </String>
<String name = "app_name"> Hello World </string>
</Resources>
Now we need to compile the modified file back to the APK file and run the following command:
Cracker ~ $ Apktool B helloactivity helloactivity.apk
This command is used to compile the content of the helloactivitydirectory, and the output file is helloactivity.apk. If you do not want to overwrite the original file, you can change the name or put it in another directory.
Next, download the compressed package sign.zip in the attachment and unzip it with a script sign. Sh. Suppose you put all the extracted files in the/home/cracker/tools directory. Run the following command:
Cracker ~ $ Export key_path =/home/cracker/tools
Cracker ~ $/Home/cracker/tools/sign. Sh helloactivity.apk
Cracker ~ $ ADB install-r helloactivity.apk. Signed. aligned
Note that if the last command fails, if you do not use the helloactivity provided by us to perform an experiment, the signature is inconsistent. In this case, uninstall the original one before installing it. Run and check, right. What is displayed in front of you is "Hello, world !"
Localization succeeded. Yes, localization is so simple. If you only want to stay at the Chinese or image replacement stage, you don't need to read any articles from here. If you do not have the Android programming foundation, you do not need to read any articles from here.
What magic has happened in the end. Why can we change the final running result by replacing or modifying a string like this? To Understand this, let's take a rough look at the compilation process of resources. First, let's take a look at the next interesting file publics. XML in the values directory. Its content is as follows:
<? XML version = "1.0" encoding = "UTF-8"?>
<Resources>
<Public type = "drawable" name = "ic_launcher_hello" id = "0x7f020000"/>
<Public type = "layout" name = "hello_activity" id = "0x7f030000"/>
<Public type = "string" name = "hello_activity_text_text" id = "0x7f040000"/>
<Public type = "string" name = "app_name" id = "0x7f040001"/>
<Public type = "ID" name = "text" id = "0x7f050000"/>
</Resources>
The ID of each row is followed by a seemingly strange number. What is this number? In Android, a resource compiler compiles all files in the res directory. It assigns a digital identifier to each resource name, which is divided into three parts, the first 1 byte indicates the package name. All APK bytes are 7f. Indicates that these resources are not shared and other APK files cannot be accessed. All the resources that can be shared are placed under the system/framework/framework-res.apk. /System/framework often has other shared resource packages. The first byte of these shared resource packages is increased from 0x1. A byte in the middle indicates the type of the resource. The numerical identifiers of each type are different. The last two bytes indicate the serial number of the resource, and the serial number of the unified type increases from 0 in sequence. Generally, the resource ID is automatically generated by the resource compiler (aapt), but the value defined in publics. xml tells the compiler that you must use this value for this ID. Apktool defines this value for all resource names in publics. xml. This ensures that the resource id remains unchanged after the resource is replaced.
Why is the resource ID so important? What will happen if it changes? It should be understood in combination with the code. We usually reference resources like R. String. app_name in Java code. After the Java code is compiled, this reference is directly changed to the resource ID 0x7f040001. Therefore, R is invisible in the decompiled smali code below. string. app_name: Only 0x7f040001 can be seen. The resource compiler generates a search table. For each ID, the search table stores the name and value corresponding to this ID (if it is a file, it is the path of the file ). When the program is running, It queries the search table based on the ID to find the corresponding resource value or file.
Finally, the resource ID is very important. Run ADB pull/system/framework/framework-res.apk to decompile this file and digest the content of this section.
4. smali
Finally, we ushered in the most important part of the smali Directory, which stores the decompiled Java code. The file name ends with smali, so it is called the smali file. These codes are much less readable than general Java codes, but they are much easier to read than traditional x86 or assembly files in other architectures. Although some tools can directly decompile the code into Java code, there is not much better, we still directly read and modify the smali file. From here, we are actually a programmer.
Let's take a look at helloactivity under the decompiled smali directory. the smali file is the same as the Java code organization method. The files under the smali directory also organize the directory structure according to the package name structure. The file content is as follows:
. Class public lcom/example/Android/helloactivity;
. Super landroid/APP/activity;
. Source "helloactivity. Java"
# Direct methods
. Method public constructor <init> () V
. Locals 0
. Prologue
. Line 27
Invoke-Direct {P0}, landroid/APP/activity;-> <init> () V
Return-void
. End Method
# Virtual Methods
. Method public oncreate (landroid/OS/bundle;) V
. Locals 2
. Parameter "savedinstancestate"
. Prologue
. Line 33
Invoke-Super {P0, P1}, landroid/APP/activity;-> oncreate (landroid/OS/bundle;) V
. Line 37
Const/high16 V1, 0x7f03
Invoke-virtual {P0, V1 },
Lcom/example/Android/helloactivity;-> setcontentview (I) V
. Line 38
Const/high16 V1, 0x7f05
Invoke-virtual {P0, V1 },
Lcom/example/Android/helloactivity;-> findviewbyid (I) landroid/View/view;
Move-result-object V0
Check-cast v0, landroid/widget/textview;
. Line 39
. Local v0, txtview: Android/widget/textview;
Const/high16 V1, 0x7f04
Invoke-virtual {v0, V1}, landroid/widget/textview;-> settext (I) V
. Line 40
Return-void
. End Method
The text starting with # in the file represents comments, and the text starting with. Is called annotations. The. Line in the file represents the corresponding source code line number, which is very important for debugging .. Metho and. End method indicate the beginning and end of a method definition. For the functions of these commands in the smali file, refer to commands.
The source code of the. Line 39 code is
Txtview. settext (R. String. hello_activity_text_text)
Now we want to change this line of code to txtview. settext ("happy, cracker! "), Change the code from. Line 39 to. Line 40:
. Line 39
. Local v0, txtview: Android/widget/textview;
Const-string V1, "Happy, cracker! "
Invoke-virtual {v0, V1}, landroid/widget/textview;-> settext (ljava/lang/charsequence;) V
Recompile, sign, install and run the code as mentioned in the previous section. Now, happy, cracker appears in front of you! Happy!
In the next two chapters, we will introduce how to directly modify the smali code to change the function of the program. This method is called code plug-in, in the next two chapters, we will use the code plug-in method to add the miui function to the native Rom.
Helloactivity.apk
Sign.zip