Experiences in Debugging Non-Symbol Android Shared Library

The shared library which shipped with the Android’s APK file usually do not have the symbol file. And if the application stopped working, usually it is related to problems in the shared library. To perform a detailed information of why it is not working, one of the method is to perform a debugging session.

But unfortunately, some game vendors will creates some measures to make the debugging process very difficult.

I will include an analysis of lib__57d5__.so, which is part of popular Final Fantasy game, which is failed to execute in my android device. In my case, it is used in Final Fantasy IV.

When I try to launch the program in the emulator, nothing happened and the screen just goes back to the launcher. Let’s see what the content of the last log activities:

dd01

From the above log, it is identified that the main program is located at BootActivity, and there’s also an attempt to load the lib__57d5__.so. The cause of the abrupt stop without any message is because the program is exceeding the App freeze timeout value.

To get more information about BootActivity class, the apk should be decompiled, and the decompiled source at clinit constructor of BootActivity as follows:

dd02

Inside the clinit of MainActivitya class as follows:

dd03

Let’s try to load this library independently by creating the small program called hello and see the mechanisms during its loading process.

dd04

But after running this program, it shows “Loading Library” and then, nothing, not even a message that inform that it has failed to load the library.

dd05

Try to checks the logcat for any message reveals nothing. So let’s perform it in a debugging session:

dd06

You can see from the above debugging session that there is “File truncated” error and there are no information about the address boundary of the loaded library.

If I try to perform object dump of the library I have:

dd07

Let’s use another tool called readelf:

dd08

You can see that the developer of this mysterious library is also try to thwart the attempt to perform some dump of the library content and also debugging attempt. The only information I can get from the library is the start up routine as follows:

dd09

Depending on memory state on your machine, the start up address may different. In my case, it is located at 0xb6edc3a5 (value marked with green color above).

This address is important to perform some calculation later at this article.

So, when I try to get some more clue, I’ve notice the presence of __57d5__.log file inside /sdcard directory, which should be created from the loaded library. Let’s pull it for more examination:

dd10

The content of this log file as follows:

dd11

The error code is originated from r5 registers at the time of __errno call:

dd12

This can be proved by setting the r5 value to some other one, for example 70 below, and the content of the error code log will change from 60 to 70

dd13

When the r5 register is filled with error code = 60 ? To provide the answer to this question, it is necessary to perform debugging at the vicinity of the above stack trace of 0xb6f1612a. This value can be deduced from the start up routine location, obtained at library load event as follows:

dd14

Now, let’s stop again at the loading event of lib__57d5__.so, by examining the r4 register in the using the above method I have:

dd15

Examining the code at this location, I have:

dd16

This shows a gibberish data and clearly is not a normal arm instruction code. Let’s repeat the above step by breaking into __errno function and examine the callstack:

dd17

Now the above code location magically transformed into an arm instruction code. Try to perform breakpoint at this location also proves to be futile because it will instantly cause the SIGILL exception.

So, it is necessary to obtain the routine that changes the data at this specific location that transform the encrypted data to a workable arm instruction.

The location in question, examined using hex form is:

dd18

Change detection can be performed by performing memory access read when the emulator is inside WinDBG debugger. When it can be identified, the decryption routine can be deduced from program counter when the breakpoint is triggered. From here, this can be expanded and overall decryption routine can be analyzed.

The decryption process depends on the right key and it is calculated from the range of the encryption block. If any of the block range contains breakpoint instruction (i.e. 0xDE01 for thumb instruction), it will make the decryption key invalid and decoded encrypted instructions will be incomprehensible.

There are two blocks of encrypted routines and the first block will decrypt yet another core block which perform some checks that will cause the error 60 above.

So, in order to perform debugging for this library, the first task is to place the breakpoint just before the decryption routines, adjust the right key, place another breakpoint after decryption routine and after that you are safe to place any breakpoint inside the decrypted routine for further examination.

Here, the error code 60 means that the ro.hardware property string contains goldfish (i.e. the machine is goldfish) or if it is running inside the emulator (i.e. by checking the ro.kernel.qemu property string).

If it is not on either one above, the library may returned with error code 40, if it detects TracerPid is non zero. This is used to check whether the library is running under debugging mechanism.

If the library is not being debugged, it will return error code 1 if it not detecting the presence of /system/bin/app_process or /system2/bin/app_process in the /proc/self/status value. This means that the library is not running under Android Application Framework (i.e. runs the program from the Top Launcher Menu).

Later on, it will checks the user id that calls this library and when it is a root user (AID_ROOT) or AND_NOBODY, i.e. not identifed as AID_APP user ID which is 10000 and above, it also returns with error code 1.

The error code 1 can also mean that certain libary required for this library to be functioning properly is not found on the process space, for example /system/lib/libdvm.so.

If you found that you have still get the error even when the above basic checks, the starting point is to examine the error code inside the log file given by the library, performing the debugging process by decrypting using the right key 🙂

Advertisements

One Response to “Experiences in Debugging Non-Symbol Android Shared Library”

  1. site Says:

    There is definately a lot to find out about this topic.
    I love all of the points you have made.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: