Android developers can use the ADB tool to control and extract information from an Android device. This tool is normally used on your development machine, but I embedded ADB into Bugjaeger, so that I can use ADB features directly on my Android device. ADB offers a lot functionality that is only available to a privileged user on Android. It allows you to install and remove apps, delete files, execute shell commands, and many other things. This makes it a very versatile tool, but it also introduces some additional complexity. I tried to make Bugjaeger as easy and intuitive as possible, but I also didn't want to remove features only to make the UI too simple. In this post I want to show some possibilities that you have with Bugjager that you might not know about, or just features that you might not find that easily within the UI.

Permissions and Initial Connection

I mentioned this step in my previous posts, but I'll quickly summarize it here for the sake of completeness. These are the initial steps that you need to perform in order to work with another connected device.

  1. Enable developer options and USB debugging on the target Android device

  2. Plug the USB OTG Cable into the target Android device

  3. Confirm the USB dialog on the Android device with Bugjaeger ("host") installed. Android usually displays an additional system popup when you connect a new USB device to your Android device with USB host support. If you click on the check box to make Bugjaeger the default app for handling this type of ADB device, the system USB popup should not appear the next time you reconnect the same USB device.

  4. Give authorization for USB debugging on the target device. You might tick the checkbox next to "Always allow from this computer", so that you don't need to confirm the authorization dialog every time you plug in the USB cable.

Executing Custom Shell Commands With Bugjaeger

Bugjaeger currently offers 2 options to run shell scripts 1.) You can add and save your custom command on the first Commands screen. To create a new command click on to plus button in the top toolbar. Next you need to insert a name for this command and the actual shell commands that will be executed. Remember that Bugjager already prepends adb shell in front of your commands, so you should not append that part (you might be used to it when working with ADB).

2.) Start the interactive shell from Commands section - <>.

Simulating Taps, Swipes, and Keyboard Input

Android devices usually contain the input executable that can be used to simulate user input from various sources like keyboard, mouse, or touchpad. To simulate swipe to the right you can enter the following command (see above section on how to enter custom commands)

input touchscreen swipe 1000 1000 0 1000

The numbers at the end are the starting and ending coordinates for the swipe - startX, startY, endX, endY.

To tap to a specific location on screen

input touchpad tap 500 500

Another thing you can do is to type in some text

input text "bugjaeger"

You can also simulate input by entering keycodes. For example to lock the screen by simulating the press of the power button you can do the following

input keyevent KEYCODE_POWER

Here the keyevent doesn't have to mean an actual hardware button present on your device. It can also trigger some functionality for which there is no button actually present on you device. For examle - using KEYCODE_MUSIC should start a music player app, or KEYCODE_VOLUME_MUTE should mute the speaker on your device. You can find more keycodes in the official documentation.

To combine multiple commands you can do the following

input keyevent KEYCODE_POWER & input touchscreen swipe 500 500 5000

This would simulate power button press and a swipe up, which would unlock the screen (if there is no lock setup or similar).

For more options that you can use with the input command, just execute the command by itself.

Get Memory Information For Specific App

To dump some detailed information related to apps memory usage

dumpsys meminfo <package_name> -d

Replace <package_name> with the package name of the app you are interested in. You can use my Power Apk app to get the package name of specific app installed on your Android device.

This is the output for Bugjaeger whose package name is eu.sisik.hackendebug

Applications Memory Usage (in Kilobytes):
Uptime: 403991493 Realtime: 1459783227

** MEMINFO in pid 15807 [eu.sisik.hackendebug] **
                   Pss  Private  Private  SwapPss     Heap     Heap     Heap
                 Total    Dirty    Clean    Dirty     Size    Alloc     Free
                ------   ------   ------   ------   ------   ------   ------
  Native Heap     2843     2736        0        7    10240     4390     5849
  Dalvik Heap      701      528       64       15     5307     1211     4096
 Dalvik Other      904      904        0        0
        Stack      252      252        0        0
    Other dev        4        0        4        0
     .so mmap      367       76       20       30
    .apk mmap    10078     9648       72        0
    .dex mmap     1180        4      148        0
    .oat mmap       95        0        4        0
    .art mmap     4378     3864      308        1
   Other mmap       10        4        0        0
      Unknown      290      232       28        0
        TOTAL    21155    18248      648       53    15547     5601     9945

 App Summary
                       Pss(KB)
                        ------
           Java Heap:     4700
         Native Heap:     2736
                Code:     9972
               Stack:      252
            Graphics:        0
       Private Other:     1236
              System:     2259

               TOTAL:    21155       TOTAL SWAP PSS:       53

 Objects
               Views:        0         ViewRootImpl:        0
         AppContexts:        2           Activities:        0
              Assets:       16        AssetManagers:        2
       Local Binders:       10        Proxy Binders:       12
       Parcel memory:        3         Parcel count:       12
    Death Recipients:        1      OpenSSL Sockets:        0
            WebViews:        0

 SQL
         MEMORY_USED:      206
  PAGECACHE_OVERFLOW:       29          MALLOC_SIZE:      117

 DATABASES
      pgsz     dbsz   Lookaside(b)          cache  Dbname
         4      108            109       28/35/15  /data/user/0/eu.sisik.hackendebug/databases/google_app_measurement.db

To get overall memory usage stats

cat /proc/meminfo

Or to get detailed overall summary for all packages

dumpsys meminfo

Getting Network Information

You can use ifconfig to dump some basic information related to your network adapters.

You can then use the names of the available adapter to get some more information with the ip command

ip addr show wlan0

This will display IP addresses of your WiFi adapter.

Finding Available Services to Dump Information From

To list all available services for dumpsys use the following command

adb shell dumpsys -l

Loading a Link in Browser or Youtube

The am utility allows you to broadcast intents that can trigger various actions in the system. One of the cool things you can do is to start the browser with a provided URL

am start -a android.intent.action.VIEW -d "https://www.youtube.com/watch?v=LxKdFlf4Y7E"

The command above will probably start the Youtube app with a link to my video. You can replace the link with something other than Youtube video and you should be able to start the default browser app also.

Record Screen Into a Video File

Bugjaeger already has a section where you can grab a screenshot of the screen (Screencap section). However, ADB also allows you to record a video from what is happening on the target device's screen. I didn't make this functionality available directly from the UI, yet. But you can still record a video by executing the following command

screenrecord /data/local/tmp/screen.mp4

The screenrecord utility will start to record a video. The vide should stop to record after about 3 minutes. You can also stop it earlier by clicking on the pause/stop button next to your custom command.

Once the video has been recorded, you can download it from the device by going to Files section in Bugjaeger and typing /data/local/tmp. Here you should be able to find the screen.mp4 on the list. Click the download icon next to the file name and choose your preferred download location. Remember that you'll need to give storage permission to Bugjager, so that it can store the file in external storage.

Running Privileged ADB Commands Directly on Device With Bugjaeger Installed

Bugjager uses ADB protocol to issue some commands that would normally require root access. Normally you would first need to connect a "target" device to the device where you have Bugjaeger installed and only then you would be able to issue commands to control this target device.

It turns out it is possible to actually run ADB commands directly on the device where Bugjager is installed. This however requires some initial configuration. First you need to tell the adbd daemon running on your Android device to listen for TCP/IP connections. Bugjager contains the client and server part of ADB. ADB server automatically checks for local devices within a certain port range (this is how it finds the Android emulator on your development computer). Once the adbd daemon enables TCP/IP connection, the ADB server tries to connect (thinking it's connecting to the emulator).

To enable TCP/IP connection you need to connect the Android device that has Bugjaeger installed to your computer and execute the following ADB command (you need to have ADB installed)

adb tcpip 5555

Alternatively, you can install Bugjaeger to another Android device, connect the two devices with USB OTG cable, and then in the command section of Bugjaeger app execute "Connect through WiFi" command.

After a couple of seconds, the regular authorization dialog for ADB device should appear.

This setup should persist until you reboot the device or until you disable Developer options.

Changing File Permissions

I didn't make this functionality available through the file manager inside of the app yet, but you can easily change file permissions through a custom command or trough the interactive shell. To check the current permissions for a file

ls -al /path/to/file

This was the output on my phone

drwxrwx--x 2 shell shell      4096 2019-03-02 17:45 .
drwxr-x--x 4 root  root       4096 1970-02-13 00:55 ..
-rwxrwxrwx 1 shell shell        13 2019-02-18 22:45 android.example.com.tflitecamerademo-build-id.txt
-rw-rw-r-- 1 shell shell     52493 2019-02-17 10:44 bugjaeger_screenshot.png
...

Here we see the regular Linux permissions for file owner, group and all other users. We can see that other users are not able to change the bugjaeger_screenshot.png file (r__ in the last part of permission column). Let's now change permissions to bugjaeger_screenshot.png to make it writable to all users

chmod 666 /data/local/tmp/bugjaeger_screenshot.png

Now the permissions look like this

-rw-rw-rw- 1 shell shell 52493 2019-02-17 10:44 /data/local/tmp/bugjaeger_screenshot.png

A quick reminder what the numbers after chmod mean

Position 1Position 2Position 3
OwnerGroupOther users


1--x
2-w-
3-wx
4r--
5r-x
6rw-
7rwx


Previous Post

Add a comment

Comments

Hi Fred, ADB only performs "privileged" tasks on the connected target device. The tasks are performed via adbd daemon and a shell that's running with some elevated privileges. My Bugjaeger app that is running on the "host" device only needs some regular USB and Internet related permissions. So no root access is required. That part is basically the ADB client and server. I did have to make quite a lot of adjustments to ADB source code to make it run directly on Android device though.
Written on Tue, 30 Apr 2019 11:56:49 by Roman
Hi, Great stuff! Just curious, how did you manage to bundle ADB in your apk and make it executable without root access?
Written on Tue, 30 Apr 2019 11:42:10 by Fred