In 0ctf2016 ,there are many hard challenges,the ‘state of art’ is one of that. This article will not only talk about that challenge but also introduce some details of Android ART.If you find something wrong, please don’t hesitate to tell me,thanks!

2. Android ART

I won’t introduce the all of Android ART in this article .if  you want to learn more about ART,i strongly recommend you to read these series article:

2.1  what is boot.art and boot.oat

In Android system’s booting time,there are two important file: boot.art and boot.oat. boot.art is an image file which comprises an image of the compacted heap of pre-initialized classes and related objects.The file format of art file is in /art/runtime/image.h,some of the words are shown below:

In a word, boot.art tells the system where to find boot.oat ,some pre-initialized classes and related objects.Usually boot.oat is just adjacent to boot.art in memory.

boot.oat contains many jars:

some features of boot.oat should be paid attention:

  • In every process, the memory of boot.oat is totally fixed (unless you recompile the boot.oat)!
  • almost every apk will use the classes or functions in boot.oat
  • once you recompile the boot.oat , all of apps will be recompiler!

2.2  oat file format

In fact the oat file is an extension of ELF, overview of oat file format is shown below(from http://blog.csdn.net/luoshengyang/article/details/39307813):


oat add two additional sections to ELF: oat data section and oat exec section. oat data section contains oat header and the original dex files, oat exec section contains each method’s native code.When apk executing,the art virtual machine will find  native code of a method through oat data’s control header,and then directly execute the native code in oat exec section.This is why art virtual machine is much faster than dalvik virtual machine.

屏幕快照 2016-03-18 下午12.34.49

The offset from oat file header to oat data section usually is 0x1000,

2.3  oatdump

oat magic for different version of Android:

one thing should be noticed that oat file can only be disassembled by corresponding version of oatdump .

the result of oatdump looks like this:

the sample above tells that the oatdump result contains each method’s small code and disassemble code. take the first line of disassembled code as an example:

there are two important points of this line:

  • the address 0x00371d08:  the address is an offset relative to oatdata section .
  • the byte code f5bd5c00: this codes are disassembled by thumb2 mode , actually ,every instruction in thumb mode should be 2 bytes alignment ,thumb2 is not an exception .So ,the true byte order in file should be ” 0xbd 0xf5 0x00 0x5c ” !

3. Solve the challenge

after learning all the knowledges above,it’s time to solve the challenge.

the challenge gave us 3 files:

  1. the result of oatdump for an unknown apk (get rid of the smali code of function ‘check’)
  2. memory maps of the unknown apk
  3. boot.oat

the function of ‘check’ is the key to solve the problem,but we only have it’s native code.There is no way to fully disassemble the native code to smali code. So the only way to solve the problem is to read the disassemble code.To make the disassemble code easier to be read ,

3.1 dump the byte code of ‘check’

we should dump the byte code of the function ‘check’.

3.2 Some important disassemble code

ADR produces position-independent code, because the assembler generates an instruction that adds or subtracts a value to the PC.

this instruction do the following: PC + label0 –> R1, that is  0xb02b7eb0 + 8 + labe0 –> R1

There are many instructions at the begin of the function ‘check’ like below:

These instructions load some bytes to an array.Register R0 contains a reference to the type of the array (i.e., byte[]),R1 contains the begin addr of array.The memory layout of Android array is like below:

屏幕快照 2016-03-18 下午7.32.53

the 8-12 bytes of array contain this array’s len,following with it’s data.

3.3 Calculate the Java function’s addr

after rebase the disassemble code,we can see many unresolved functions. In fact,these functions is in boot.oat,so next step is to calculate the addr and find out it’s corresponding functions:

屏幕快照 2016-03-18 下午2.58.54

We take the above function ‘sub_72a08970’ as example.From the given maps ,we can see the base addr of boot.oat is 0x70eee000, the base addr of the apk is 0xaff45000:

the offset of this functions is:   0x72a08970 – 0x70eee000  = 0x1b1a970

the addr of native code in oat exec section is relative to oat data section’s begin , so we should minus the offset between elf header and oat data section:  0x1b1a970 – 0x1000 = 0x1b19970

then we use oatdump to disassemble boot.oat and find the addr ‘0x1b19970’:

it’s ‘equal’ function. next use the same way to calculate the other functions:

屏幕快照 2016-03-18 下午7.55.28

through reversing ,we can get the flag: 0ctf{1ea5n_2_rE_ART}