Search code examples
androidserviceadb

Install directory of Android service


I am analyzing a custom Android device. I tried to enumerate services running in the system (adb shell service list) and I found out that there is a service (let's call it MyService) that I would like to analyze more in depth. It might be a privileged (system) service, if that is a relevant information.

When I run adb shell service list | grep MyService, it returns something like aaa.bbb.ccc.ddd.MyService. I would like to get the code/binary/APK of this service. However, when I run adb shell pm path aaa.bbb.ccc.ddd.MyService, it returns error code 1 and doesn't print any path. The same situation occurs when I execute adb shell pm list packages | grep -i XXX, where XXX is any of aaa,bbb,ccc,ddd or MyService (for the record, aaa and bbb return some packages, but they do not have anything in common with the specific service).

My question is: How can I extract the code/binary/APK/... of the service? How do I find where it is installed?

If root access is needed, that shouldn't be a problem.


Solution

  • I'm new to this problem as well, and had some fun exploring the Android internals. Eventually, I was only able to find the process id that provides the service, and any information associated with that, through /proc and /sys VFS.

    Here are my findings:

    My first discovery was that, dumpsys <SERVICE_SHORT_NAME> can connect to any service, and ask it to dump its internal state. But this doesn't always include the package name or install directory for that service. I decided to trace system calls from this dumpsys program, using strace. But it turns out that IPC happens through a non-standard /dev/binder device that strace doesn't understand:

    $ su
    # strace -f -y dumpsys telephony_ims | grep binder | tail 
    openat(AT_FDCWD, "/dev/binder", O_RDWR|O_CLOEXEC) = 3</dev/binder>
    ioctl(3</dev/binder>, BINDER_VERSION, 0x7fd88906b4) = 0
    ioctl(3</dev/binder>, BINDER_SET_MAX_THREADS, 0x7fd88906a8) = 0
    mmap(NULL, 1040384, PROT_READ, MAP_PRIVATE|MAP_NORESERVE, 3</dev/binder>, 0) = 0x7990b83000
    ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7fd8890460) = 0
    ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7fd8890110) = 0
    [pid 15836] ioctl(3</dev/binder>, BINDER_WRITE_READ, 0x7990b7e8a0) = 0
    [pid 15836] ioctl(3</dev/binder>, BINDER_WRITE_READ <unfinished ...>
    [pid 15836] ioctl(3</dev/binder>, BINDER_THREAD_EXIT, 0) = 0
    

    Luckily, there is still a method to trace what happens inside this binder device. With the help from this other Stack Overflow page, I was able to find the pid running any service.

    I will examine the service telephony_ims as an example.

    • Please run the following commands as root.
    • First, we need to set up Android Binder Tracing, using commands from the other Stack Overflow page.
      • cd /sys/kernel/debug/tracing; echo > set_event; echo 1 > events/binder/enable; echo 1 > tracing_on
    • Then, we must run dumpsys, and immediately afterwards, read the trace logs.
      • Prerequisite: I used less command, which isn't available on all android devices. If your bash cannot find less, then you could dump the results to a file on SD Card, and open it using a text viewer.
      • Run (cat /proc/uptime; dumpsys telephony_ims >/dev/null & echo $!; cat /proc/uptime; cat /sys/kernel/debug/trace | tail -n 1000) | less
    • Look at the resulting output
      • The first three lines are
        16682.46 92635.05
        20823
        16682.47 92635.12
        
      • Search for 20823 from the second line, which is the PID of dumpsys. (The first and third lines are start time timestamp, and end time timestamp, respectively)
      • Found out that dumpsys is talking with servicemanager:
        dumpsys-20823 [006] .... 16682.479173: binder_transaction: transaction=10738057 dest_node=1 dest_proc=563  # more content afterwards, ignored. pid 563 is "servicemanager"
        # ... more lines ...
        servicemanager-563   [003] .... 16682.479283: binder_transaction: transaction=10738058 dest_node=0 dest_proc=20823 # more content afterwards, ignored.
        
        
      • Then, it turns out that dumpsys-20823 started a child process, 20827:
             dumpsys-20823 [004] .... 16682.479808: binder_return: cmd=0x7206 BR_TRANSACTION_COMPLETE
             dumpsys-20823 [004] .... 16682.479810: binder_transaction_received: transaction=10738061
             dumpsys-20823 [004] .... 16682.479811: binder_return: cmd=0x80407203 BR_REPLY
             dumpsys-20823 [004] .... 16682.479812: binder_read_done: ret=0
             dumpsys-20823 [004] .... 16682.479813: binder_ioctl_done: ret=0
             dumpsys-20827 [006] .... 16682.480058: binder_ioctl: cmd=0xc0306201 arg=0x780a5668a0
             dumpsys-20827 [006] .... 16682.480060: binder_command: cmd=0x40406300 BC_TRANSACTION
             dumpsys-20827 [006] .... 16682.480077: binder_transaction: transaction=10738063 dest_node=29113 dest_proc=2574 dest_thread=0 reply=0 flags=0x10 code=0x5f444d50
        
      • Eventually, it's this child process who gave away the PID of the service ("dest_proc=2574"):
        dumpsys-20827 [006] .... 16682.480077: binder_transaction: transaction=10738063 dest_node=29113 dest_proc=2574 dest_thread=0 reply=0 flags=0x10 code=0x5f444d50
        
    • Look into this process for its package name / related jars and apks
      $ ps -A | grep 2574
      radio          2574    875 14414052 120280 SyS_epoll_wait     0 S com.android.phone
      $ ls -l /proc/2574/fd | egrep 'apk|jar' | head
      lr-x------ 1 root root 64 2020-12-15 13:42 10 -> /apex/com.android.art/javalib/bouncycastle.jar
      lr-x------ 1 root root 64 2020-12-15 13:42 102 -> /system/app/Stk/Stk.apk
      lr-x------ 1 root root 64 2020-12-15 13:42 11 -> /apex/com.android.art/javalib/apache-xml.jar
      lr-x------ 1 root root 64 2020-12-15 13:42 12 -> /system/framework/framework.jar
      lr-x------ 1 root root 64 2020-12-15 13:42 13 -> /system/framework/ext.jar
      lr-x------ 1 root root 64 2020-12-15 13:42 14 -> /system/framework/telephony-common.jar
      lr-x------ 1 root root 64 2020-12-15 13:42 15 -> /system/framework/voip-common.jar
      lr-x------ 1 root root 64 2020-12-15 13:42 16 -> /system/framework/ims-common.jar
      lr-x------ 1 root root 64 2020-12-15 13:42 18 -> /system/framework/framework-atb-backward-compatibility.jar
      lr-x------ 1 root root 64 2020-12-15 13:42 19 -> /apex/com.android.conscrypt/javalib/conscrypt.jar