Pages

Sunday, January 13, 2013

Android system calls hooking to trace system calls


There are definitely many tutorials on the internet which you can use for system calls hooking but now I try to keep track of all the things I am doing in my own words.

Following tutorial will help you to hook system calls for Android 2.6.29 and then you can trace system calls against any APK installed on your emulator.

I assume, you already know how to build and compile Android source code and you have done it, so I will go one step further from here now.

Basically, our_sys_table is pointing to a memory location where it stores all the system call numbers and pointers to each of those system calls. So if we get pointer to this  memory address, we can easily get pointers to all the system calls using predefined macros like __NR_<sysCall>. Then we can modify these pointers to point to our own system call routines and in this routine, we will call original system call routine so that original functionality may still work.

In this tutorial, I will only talk about read() system call and all of the other system calls will work the same way. And if you are reading this post, I assume, you are a programmer and you can easily understand the code given in trapcall.c file after reading the above given explanation. One hint: this code starts from init_module() method.

Step 1:

Create a directory 'LKM' in the home directory.

Step 2:

Copy the code given below and save in a file called 'trapcall.c'.

I have moved code from here to trapcall.c . This is the final version of the code.


Step 3:

Put this file in LKM directory such that its location is: 

/home/<userName>/LKM/trapcall.c

Step 4:

Go to /home/kernel-source/goldfish/ and open System.map file in a text editor. Find the entry 'sys_call_table' and copy the address. For example, in following case:

c0028aa4 T sys_call_table

address is c0028aa4

Step 5:

Open trapcall.c in a editor and go to the first line of function: init_module(). Change the address in the first line with the one copied from System.map in step 4. Do not forget to put 0x infront of the number copied.


Step 6:

Create a file named exactly 'Makefile' without 
quotes and extension like .txt and copy given below content in it. Save this file in the LKM directory.

Makefile

obj-m += trapcall.o

all:
 make -C /home/<userName>/kernel-source/goldfish/ M=$(PWD) modules

clean:
 make -C /home/<userName>/kernel-source/goldfish/ M=$(PWD) clean
 
Step 7:

Replace <userName> with your account name and save this file.

Step 8:

From terminal, navigate to the directory : /home/<userName>/LKM
Use the following command to compile the module:


$ make ARCH=arm CROSS_COMPILE=/home/<userName>/android/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-

If you don't get any error, your module is ready to use.


Step 9:

Open a new terminal and run emulator via following command. I assume, you already have an avd named 'test'.



$ cd kernel-source/goldfish
$ emulator -avd test -kernel /home/<userName>/kernel-source/goldfish/arch/arm/boot/zImage -show-kernel -verbose

Step 10:

After the emulator is loaded, go to /home/<userName>/LKM from the first terminal and give the command:

$ adb push trapcall.ko /data/trapcall.ko
$ adb shell

Step 11:

 When you get the shell of emulator, type:

# cd data

# sudo insmod trapcall.ko


When you issue insmod command on the first terminal, you will start getting list of system calls on the second terminal where you started the emulator from.

Troubleshooting:

If you get some error related to memory write permissions because of modifying the function pointers, use accepted solution on the stackoverflow.

Filtering system calls based on UID:

Right now we have only one system call (read), but when we have all the system calls, we would be getting damn lot of system calls. So I would suggest to increase the buffer limit of the terminal to unlimited to get the complete list.

There is one more problem: after looking at the system calls list, we cannot find which system call belongs to which APK. So we can exploit the fact that each app gets a unique UID and PID on its installation time but if we run the emulator second time with installed app remains there or we reinstall it by running our project on Eclipse, we will find the same UID but different PID. Which means, if we get the uid, we can use a conditional statement for printk().

There is a file packages.xml in the emulator which you find through DDMS perspective in Eclipse or by using ls command on the terminal. Anyway, once you find the location of the file, download it and find uid of your APK in the file. In my case, uid =100028.

And your final trapcall.c will look like this.

Due credit to my frient Sarker Rumee who actually told me the basic steps.



3 comments:

  1. its really handy!!!

    ReplyDelete
  2. Here's a technique describing how to write a LKM to find the syscall table address, you can combine with this and you won't have to hardcode it from system.map: http://blog.seguesec.com/2013/01/544/

    ReplyDelete

  3. @Anon.. ty =)

    @pof.. Thanks for your link.

    ReplyDelete