IDA Dynamically Debugging Native Layer Programs¶
Here we will introduce how to debug the following types of programs.
- Basic native layer program, a simple C/C++ program.
- Native so program
Essential Tools¶
- already rooted phone
- IDA
Fundamental¶
When using ida to dynamically debug native layer programs, the android_server program is mainly used. The program is injected into the program to be debugged using ptrace technology.
Each process has a status file with a field TracerPid that identifies which process the process is ptrace to. If it is not ptrace by other processes, it returns 0, otherwise it returns the pid of the corresponding process.
Basic environment construction¶
No matter what native layer program is debugged, the basic environment is similar. You need to ensure that IDA communicates with the phone normally.
- Upload the android_server file (under ida's dbgsrv folder) and modify the permissions to make it executable
adb push android_server /data/local/tmp/
adb shell chmod 755 /data/local/tmp/android_server
- Open android_server, which will listen on port 23946 (running as root)
Adb shell # Enter adb
Su # switch root
./data/local/tmp/android_server #Start android_server
- Establish communication between the local computer 23496 port and the mobile phone port 23946. When the PC has a client connection to port 23946, the information it sends will be forwarded to the corresponding port on the phone, and android_server will receive the corresponding data, allowing IDA to debug the program. The port of the previous tcp refers to the port of the local PC, and the latter refers to the port of the mobile phone.
adb forward tcp:23946 tcp:23946
note:
> In fact, this connection establishes communication between the adb server and the adbd on the phone. So its communication is probably like this
IDA↔adb server<--->adbd<---->android_server
> computer | mobile phone
Among them, the first step only needs to be executed once, and you don't need to execute it again later. Steps 2-3 have to be executed each time, so you can write a script and place the script's path under the system's path environment variable so that we can execute a command directly.
Basic native program debugging - Method 1¶
A basic native program refers to a normal c/c++ program compiled into arm assembly.
Adding a program¶
Here we take the debugnativeapp in http://www.52pojie.cn/thread-554068-1-1.html as an example.
First, we need to put the native program on the android device and modify its permissions so that it can be executed. as follows
adb push debugnativeapp /data/local/tmp/
adb shell chmod 755 /data/local/tmp/debugnativeapp
Start debugging¶
Select the appropriate ida according to the number of bits in the native layer program, then select Debugger-Run-RemoteArmLinux/Android debugger, the following interface
Among them, the important parameters are as follows
-
Application
-
The absolute path of the program being debugged on the phone.
-
Directory
-
The directory of the debugged program in the phone
-
Hostname
-
That is, which host we communicate with, here we communicate directly with the local PC.
The Debug options are selected as follows
Mainly selected three events, so that our program can be automatically stopped at the entry point, when the thread starts, when the library is loaded. Of course, you can also choose.
After starting the program, as follows
Note:
> 1. If you find that you can not load plugin, it may be that the phone does not have root.
> 2. If you encounter the following problems, just cancel it. The specific reasons are not clear.
> 3. If you encounter error: only position independent executables (PIE) are supported. Generally because the version of android phone is greater than 5, you can try
> - Use the PIE version of android_server > - Use 010Editor to change the e_type in the elf header field in the header of the executable ELF file to ET_DYN(3).
so native program debugging¶
For so native programs, we might wonder what is different from ordinary native programs? Naturally there are, so files cannot be run separately. Usually some other programs call some basic functions in the so file. So here we can't directly use the above run method. In general, the so files in android are dependent on the apk file.
Here we take debugjniso.apk in http://www.52pojie.cn/thread-554068-1-1.html as an example.
First, you must build a basic debugging environment.
Installer¶
First, we need to install the apk on the phone.
adb install debugjniso.apk
Debug mode startup app¶
Secondly, we need to start the program in debug mode, so that IDA can easily capture the corresponding program and attach it.
```shell
adb shell am start -D -n packagename/.MainActivity
```
attach program¶
Start IDA pro, click Debugger-Attach-RemoteArmLinux/Android debugger, Hostname fills in localhost, port defaults to port 23946. In fact, it is the listening port of our local computer. as follows
Click ok to start debugging
note:
> If only one program /bin/sh can be attached at the end, it means that the android_server program is not running with root privileges.
Use ctrl+f to quickly locate and select the corresponding process, as follows
Then ok OK.
At this point we can see that we have attached success.
At this time, we click Debugger-Debugger options again, and the related options are as follows:
The meaning is similar to the native program.
> Why do you choose to set the corresponding breakpoint at this time? Because if you set it at the beginning of the attach, there is actually no such thing here. Everyone can try.
Resume app execution¶
At this time, the interface of the app is wait for debugger, and we have attached it. At this time, you need to let the program continue to run.
First, we open ddms to select the process we want to debug.
This is actually equivalent to direct execution.
# Display all user processes available for debugging on the phone
adb jdwp
# Establish a connection between the xxx port of the PC and the corresponding port of the mobile phone to facilitate communication
adb forward tcp:xxx jdwp:<pid>
The reason why we don't use the command to execute is because we have to determine the process number of our apk ourselves, which is more troublesome.
Here is a basic communication process
At this point, our computer has established communication with the app's app virtual machine.
At the same time, we need to use jdb in the java layer to attach our apk application to our computer, here we use the following command.
jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=xxx
Where xxx is the 8700 port we saw in ddms, the default is this. After execution
C:\Users\iromise
λ jdb.bat
jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
Set uncaught java.lang.Throwable
Set delayed uncaught java.lang.Throwable
Initializing jdb...
>
Let’s take a look at our mobile phone again.
At this point, the application has continued to run, no longer the previous wait for debugger.
Determining the native function address¶
Here we open an ida again, import the sok of the apk, and then look for our function in export, as follows
It can be seen that the offset is 0xc38.
We then run F9 in the previous debug IDA until it is no longer running, we will see the program break at the linker
At this point, we click on the app's interface to set the title button (the reason to press this, because the native API is called in the function), observe the IDA again, you can see that the so library has been loaded into
B3B05000: loaded /data/app/com.droider.debugjniso-1/oat/arm/base.odex
B39B9000: loaded /system/lib/hw/gralloc.msm8974.so
B39B2000: loaded /system/lib/libmemalloc.so
B39AA000: loaded /system/lib/libqdutils.so
B3B00000: loaded /data/app/com.droider.debugjniso-1/lib/arm/libdebugjniso.so
At this point, we use ctrl+s to locate 0xB3B00000 at the starting address of the library. Then according to
Absolute address = base address + relative offset
Get the address of the jnistring.
Observation results¶
Press g, then type +0xC38
and click ok to jump to the function
libdebugjniso.so:B3B00C38 Java_com_droider_debugjniso_TestJniMethods_jniString
libdebugjniso.so:B3B00C38 LDR R1, =(unk_B3B02148 - 0xB3B00C4C)
libdebugjniso.so:B3B00C3C STMFD SP!, {R4,LR}
libdebugjniso.so:B3B00C40 LDR R3, [R0]
libdebugjniso.so:B3B00C44 ADD R1, PC, R1 ; unk_B3B02148
libdebugjniso.so:B3B00C48 MOV LR, PC
We breakpoints at the beginning of this function, F2, and then execute the program again with F9. While watching the phone, we can see that the title of the app has changed to Hello! Nativemethod
.
At this point, the basic debugging steps of the so native program are over.
Note:
> If there is an add map dialog box in the middle, click Cancel, then apply.
Precautions¶
- When using the simulator to debug an apk exception, it is very likely that the application has detected whether it is running in the simulator environment, consider using a mobile phone.
- When using the real machine debugging apk, it is also possible to encounter an exception, stuck in a certain instruction, then we can manually execute this instruction, and then set the PC to the address of the next instruction.
Basic native program debugging - Method 2¶
To be added.
Multithreaded debugging¶
参考阅读¶
本页面的全部内容在 CC BY-NC-SA 4.0 协议之条款下提供,附加条款亦可能应用。