Androidmanifest ambiguity scheme principle and code

Source: Internet
Author: User

1 description

A androidmanifest ambiguity scenario was seen in a previous time in an Android security PDF in Bluebox. The solution is based on an android system that resolves the axml feature: When Android parses the properties of a axml, it is positioned by the Res ID number of the property rather than by the property name. The so-called Axml is the androidmanifest.xml corresponding binary file, the APK package is stored in the axml. For example, attributes:

<public type= "attr" name= "name" id= "0x01010003"/>

Its property name is Name,id number 0x01010003.

The approximate principle of the scheme is as follows:

Let me briefly summarize:

We add a property in Axml (note that axml is not androidmanifest.xml), the property name is name, the value of the property is Some.class, and the ID number of the property is 0. According to the previous article, the Android system is not parsed for an illegal res ID number. So when we add this useless property, it doesn't affect the APK's normal work (shown in the lower left corner), but for reverse tools like Apktool, they parse this useless property (shown in the lower right corner). So, if we were to repackage, Apktool would change the property to an ID number 0x01010003 a property that could be parsed by the system. The result of this is this: because our apk does not implement the Trap.class class, the APK starts with an error "There is no trap.class~~".

2 Implementation Scenarios

Although the PDF proposed this scheme, but did not give the implementation of the Code (in fact, it gave the above picture ~ All the other wood has ~), Google is also blank. So when I read the principle, I want to realize it myself. It's not as simple as I thought.

2.1 Axml file format

The first challenge is: The online search is not the format of the Axml file!!! At that time almost gave up, but later a thought, since Apktool can parse axml that it is to understand Axml file format, so on the internet to search for a parse axml of various parsing code, after the synthesis of Claud greatly axml Parser code is more advantageous to summarize the Axml file format. So we summarize the file format with this code, as shown in the following table:

0x0~0x3 magic:0x03000800 Fixed value

0x4~0x7 FileSize: Overall file size

0x8~0xb Stringtag: string block start flag, 0x01001c00 fixed value

0XC~0XF stringchunksize: string block size

0x10~0x13 count of strings: number of strings,

0x14~0x17 Count of styles: number of types

0X18~0X1B Reserve field: reserved for 0

0x1c~0x1f the starting offset value of the string: Note that this offset is relative to Stringchunk!

0x20~0x23 styles Start Offset value: Ibid.

The following storage is the offset value of n consecutive string, each offset value of 4 bytes, it should be noted that this offset value plus a string starting offset value and 0x8 is the true offset value! The size of n is the size of 0x10~0x13.

Then there is the offset value of n consecutive style, ditto ~

String Data block


Style data block


Note: Here, Stringchunk is over.

The following is the Resourcechunk, which holds the resource ID number


Resourcechunksize: Size of the resource ID block

Continuous RESOURCECHUNKSIZE/4-2 res ID values. -2 is mainly to remove the above 8 byte resourcechunkheader.

4 bytes per res ID

Resourcechunk End

Here are some of the successive chunk blocks:

Chunk_startns:doc start sign, 0x00011000


Line number

Unknown, 0xFFFFFFFF

Here is a namespace record structure, referred to as Nsrecord



It is then recursive to perform chunk operations, because a namespace often contains many sub-chunk

chunk_type:0x02011000->0x00100102 to Chunk_starttag


Line number

Unknown, 0xFFFFFFFF

Current tag ' s namespace ' s URI

The name of the current tag is a string index value

Flags, unknown usage

The current label contains the number of attr, note that the final result to &0X0000FFFF

ClassAttribute, Unknown usage

The following is the structure of a continuous n attribution chunk,attribution as follows:

/* attribute structure within tag */

typedef struct{

uint32_t URI; /* URI of its namespace index of strings*/

uint32_t name; /* Property name, indexed value Index of strings */

uint32_t string; /* Attribute value if type = = attr_string, index value */

uint32_t type; /* Attribute type, = = attr_* */Note that the value needs to be shifted right by 24 bits

uint32_t data; /* attribute value, encoded on type */

} attribute_t;

In turn


2.2 Considerations for modifying Axml

Knowing the file format of Axml, we can think of a property insertion. But before a property is inserted, we have to plan a specific implementation, because it involves little or nothing.

1) First, the attribute structure needs to be further analyzed. It has the following format:

/* attribute structure within tag */

typedef struct{

uint32_t URI; /* URI of its namespace index of strings*/

uint32_t name; /* Property name, indexed value Index of strings */

uint32_t string; /* Attribute value if type = = attr_string, index value */

uint32_t type; /* Attribute type, = = attr_* */Note that the value needs to be shifted right by 24 bits

uint32_t data; /* attribute value, encoded on type */

} attribute_t;

The focus is name, string, data. I extracted an attribute fragment from a axml, as follows:

Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F

0C (XX) (FF FF FF FF), 7F

0C (xx), XX, FF FF FF, XX, 7F

0C XX [W1] the xx xx [W2] xx xx [W3] XX [W4] xx xx [W5]

[W1]uri: URI of the namespace, which is the index value of string

[W2]name: Property name, also an indexed value of string

[W3]string: If the property type is attr_string, this value is the index value of the attribute android:name= "xxx", xxx in string. The rest of the case is 0xFFFFFFFF

[W4]type: The type of the property, for Android:name, the type value is 0x03000008

[W5]data: The data value of the property, and for Attr_string, its value is the value of string.

It can be found that there is no member in the struct called Res ID, then how does the system get the ID number of a property? It turns out that the name member here is a two-job , a string index as a property name and an index to the Res ID. Here, for example, name = 4, which corresponds to the string "name" in Stringchunk, corresponds to the res ID 0x01010003 in Resourcechunk. So to insert a property named Name,id and 0, we have to create a new string with the value of name, a new res ID, a value of 0, and both in the respective Chunk The index value of the zone is equal ( This is the focus).

2) Second, it is the alignment of string in the Stringchunk (originally made of brain hole open ~).

Almost all of the members in Axml are UInt32, except for the use of UTF-16 encoded string data blocks. Therefore, the string data block must be 4-byte aligned after the string is joined. And if the original Axml string data block has been 4-byte aligned (that is, artificially populated with a few 0x00), we need to note that the size of the first byte of the last string of UTF-16 encoding does not contain the 0x00 of these several fills ( This byte represents the number of bytes that the string occupies, and the details can be found in the UTF-16 encoding related data. To circumvent the annoying alignment problems, we use trickery to get the length of the string:

Stringlen = Stringchunksize-stringoffset; The Stringlen must be 4-byte aligned at this point.

Of course, this is in the absence of a style, if there is, you have to take extra action (the implementation Code has ~). For the sake of simplicity, I added the string directly after this alignment, so I just need to consider whether the added string needs to be aligned ~

3) Then, is the expansion of the Resourcechunk.

In 1), the value of the name of the inserted property has been mentioned while acting as the Res ID index value. In general, the number of res IDs in Resourcechunk is much less than the number of strings, so we need to expand the resourcechunk. The extension is simple, all assigned to a value of 0.

4) Finally, in addition to the need to add data, but also need to modify some of the original file "metering", these measures are related to the size of the block or offset values, summarized as follows:



③count of String

The starting offset value of the ④styles (if there is a style, it needs to be modified)


⑥application belongs to Chunk chunksize

⑦applicationh contains the number of attributes

2.3 Modifying Axml steps

1) Modify Stringchunk, add UTF-16 to represent the string chouchou.class and name, and add an offset value entry for both strings. At the same time, the starting offset values of stringchunksize, Count of string, styles are fixed;

2) Modify the Resourcechunk, mainly for the Res ID extension and the Resourcechunksize repair

3) Modify the chunk of the application, insert the attributes, and fix the number of attributes Chunksize and Applicationh.

4) Copy the parts that do not need to be modified to the appropriate location;

5) Repair FileSize

Of course, the specific implementation is certainly more complicated than the appeal step, but the realization of the source code has more detailed comments, you can refer to the source reading ~

3 Code Description

AXMLPARSER.H/.C is Claud greatly parse Axml source, out of the author's thanks and let us know more about Axml parsing process (in fact, I really do not want to write the parsing code o (╯-╰) o), I will implement the code to merge with it into a piece. AXMLMODIFY.C is what I wrote to implement the Axml modification function.

4 How to use

The current code is not perfect, only the initial implementation of the insertion application.attr ("name", "Chouchou.class", 0x0) function. So it's not the final version.

The code can only run under Linux, and after the code is downloaded, the executable file manifestambiguity is generated. Then run directly./manifestambiguity can be used for complete instructions.

Before modification:

After modification:

Overwrite the XML in the original APK with the modified XML, then delete the original signature folder and then sign it. If you re-pack the APK that was modified following this scenario, you will find that the re-packaged APK has failed to boot.

5 Next work

Since the current APK software protection is mainly based on the Dex code encryption and so library file encryption, the Androidmanifest.xml did not do anything, and Androidmanifest.xml as the APK entry file, its importance is self-evident. So I would like to be able to do some "hands and feet" in this file, and then combine the corresponding processing code to achieve another perspective of software protection.

For example, we can fully implement the trap class Trap.class, and this class inherits from application and so on, so that the re-packaged apk can also run. Just from the start, the APK runs in the wrong environment, and as for the subsequent operation, you can play it out.

Alternatively, we can insert in other tags some properties that do not affect the APK run (that is, the newly added attribute is not recognized by the system, the property is recognized by the system but does not affect the operation of the APK). The code then checks to see if the Androidmanifest.xml contains the property, and if so, the software is repackaged.

Wait ~

If you have good suggestions or methods, please do not hesitate to enlighten ~ Thank you!

Androidmanifest ambiguity Scheme principle and code

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.