Setting up an Android emulator on a remote machine (to avoid destroying my laptop battery) in a state to capture traffic from an app was a bit annoying, and I wanted to store the shortened set instructions somewhere so I can reference it later.

If you’re not me, replace 192.168.1.223 with whatever your host machine is on your LAN.

Setup

Host

Just in case the machine I really don’t care to backup bites the dust…

  • Assuming a Debian-like system, apt-get install default-jdk
    • I initially tried to do this in a Linux Container (LXC) - but nested virtualization via /dev/kvm doesn’t pass through. Oh well.
  • Create or reuse a user. In my case, I did:
    • useradd -m android
    • usermod -a -G kvm android (otherwise the emulator + nested virtualization won’t work)
    • passwd android to something I could remember (needed later)
  • su android, install Android Platform tools, emulator, etc. One of the links below should help.
    • If it’s been a while, sdkmanager --update to pull the latest SDK
  • Add android tools to path. e.g. create .localrc and set contents to PATH=$HOME/cmdline-tools/latest/bin:$HOME/platform-tools:$HOME/emulator:$PATH
  • Get the image: sdkmanager --install "system-images;android-35;google_apis;x86_64"
  • Create AVD: avdmanager create avd --name pixel-android-api-35 --package "system-images;android-35;google_apis;x86_64" --tag "google_apis" --abi "x86_64" --device "pixel_6"
  • Install the mitmproxy cert into the emulator after making the system partiton writable. I won’t copy those steps, follow them here.

Client

brew install scrcpy

Execute

Host

  • Start screen or similar
  • In one terminal of your main user with sudo: sudo docker run --rm -it -v ~/.mitmproxy:/home/kevin/.mitmproxy -p 0.0.0.0:8080:8080 -p 0.0.0.0:8081:8081 mitmproxy/mitmproxy:latest mitmweb --showhost --web-host 0.0.0.0
  • In another terminal: emulator -avd pixel-android-api-35 -writable-system -no-window -http-proxy http://192.168.1.223:8080
  • In another terminal:
    • adb forward tcp:1234 tcp:5555
    • adb tcpip 5555
    • ssh -Nfg -L 1234:localhost:5555 localhost

Remote

  • adb connect 192.168.1.223:1234
  • scrcpy -m1024
  • Open http://192.168.1.223:8081
  • Run your scenario and hopefully it’s captured. If not, you might have a problem with cert pinning or an app bypassing the proxy.

Unclear if this is necessary with the -http-proxy argument with the emulator (I discovered that later), but found it useful enough to document. Run on either host or remote.

adb shell settings put global http_proxy 192.168.1.223:8080
adb shell settings put global global_http_proxy_host 192.168.1.223
adb shell settings put global global_http_proxy_port 8080

Future

At some point, I think I’m going to need a packet capture for my next step in the reverse engineering journey I started down…

Resources

This terse set of instructions was compiled from:

I never did get Frida working, it just hung on my emulator device and the client timed out connecting. But for my case, that wasn’t important.

Interesting things from 2025-01-05