Hacking Book | Free Online Hacking Learning


android 9patch image parsing heap overflow vulnerability analysis (cve

Posted by graebner at 2020-03-30


Google recently released a bug that was updated in January. This vulnerability fixes a problem existing in image rendering under Android version 5.1. You can see the relevant links.

9patch is a unique image format on Android, which is to add some pixel borders on the basis of ordinary PNG images, so that it can be stretched and scaled at will.

[9patch file format overview]

As mentioned earlier, the 9patch file is a special PNG image. Let's take a look at the PNG file structure.

At the beginning of a PNG file is something called signature, that is, the file signature. Many people call it the file header, which is 8 bytes long. The value of these 8 characters is fixed.

After the signature is a chunk block sequence. The size of each chunk block is uncertain, and image data is stored in it. The chunk block structure is as follows:

The pseudo code is described as follows:

At the beginning of the chunk is the chunk length, which is defined as a 4-byte large end integer. The chunk length is just the length of chunk data, not including the length of itself, type and CRC. Therefore, the length of the whole chunk block needs to add the size of these three fields. The next 4-byte character sequence can only be composed of English characters, indicating the type of chunk block. Then the chunk data part, the length is specified by the start length. When the length is 0, this field can not exist. Finally, the CRC code of the whole block. Further back? It's the next chunk.

Let's talk about the main 9 patch file of this article. It is a PNG file with the type "NPTC" in the chunk. Take a look at the official definition of Google (some irrelevant codes have been filtered):

Take a look at a normal 9patch file

The NPTC block of the 9patch file is located after the first IHDR block. The chunk length is 0x20, and the values of the data field are all 0. The figure indicates the positions of numxdivs, numydivs, and numcolors. The values of other data fields can be deduced in turn.

[vulnerability analysis]

If you don't want to see it, jump to the end to see the conclusion.

Loading a carefully constructed 9patch image on version 5.1 will cause the process to crash, as shown in the figure below.

Look at the error. It refers to an illegal address. Look at the Google patch:

There are two patches:

1. The definitions of numxdivs, numydivs and numcolors in chunk block are changed to unsigned

2. The assertion in the peek function of the NPTC block is changed to judge the unequal return

What should the three variables numxdivs, numydivs, and numcolors be changed to be unsigned? Why can't they be negative? What if they are negative? Analyze them again with questions to see where the three values are used.

It can be seen from this that xdivsofffset is the length of res ﹣ png ﹣ patch structure, which is a constant, generally 0x20. The value of ydivsofffset increases the length of int array with size of numxdivs, and the value of colorsofffset increases the length of int array with size of numydivs. Back again:

Ydivsofffset and colorsofffset determine the addresses of ydivs and colors. As long as numxdivs and numydivs are carefully constructed, they can access any other memory within a certain range. It seems that the illegal reference address just reported should be here.

There is also a reference to numxdivs, numydivs, numcolors.

Take a look at the call to serializedsize:

Here we use the return value of serializedsize() to compare with the length. Numxdivs, numydivs and numcolors can be negative, which affects the normal calculation of serializedsize, triggers assertions and interrupts programs.


We have analyzed so much to summarize the causes of the loopholes.

In the res PNG patch structure, numxdivs, numydivs and numcolors are defined as signed numbers. When they get negative values, they will affect the values of ydivsofffset, colorsofffset and serializedsize, resulting in heap overflow. The phenomenon is that the array is out of bounds.


This vulnerability can be verified by changing one of the three bits numxdivs, numydivs and numcolors in the previous file to a negative number (i.e. greater than 0x80).

[test plan]

After mastering the details of this vulnerability, it is easy to prevent it. As long as you traverse all chunk blocks of the PNG file and detect the NPTC blocks, you can judge whether numxdivs, numydivs and numcolors are negative. As long as one of them is negative, you can judge it as a malicious file. The relevant detection code is as follows: