Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple ADB performance and functionality fixes #811

Merged
merged 7 commits into from
Dec 14, 2016

Conversation

zachriggle
Copy link
Member

@zachriggle zachriggle commented Dec 13, 2016

Currently, adb.wait_for_device performs incorrectly when:

  • Multiple devices are available
  • context.device or $ANDROID_SERIAL are set

The intended result is that the chosen Device object is returned via adb.wait_for_device(). However, the first device is always returned.

Separately, the constructor for AdbDevice objects is slow due to fetching properties for the device. Since adb.devices() creates an AdbDevice object for each device, and adb.wait_for_device() uses adb.devices(), this makes the process of waiting much slower than it needs to be -- we effectively run shell getprop for each device.

$ git checkout dev
$ export ANDROID_SERIAL=00a1d5381d8e1c4f
$ time python -c 'from pwn import *; print adb.wait_for_device()'
[+] Waiting for device to come online: HT6640200015 (marlin NDE63V 2016-Oct-23)
HT6640200015 #<-- wrong serial
python -c 'from pwn import *; print adb.wait_for_device()'  0.26s user 0.19s system 8% cpu 5.118 total #<-- five seconds
$ git checkout adb-3.2-fixes
Switched to branch 'adb-3.2-fixes'
Your branch is up-to-date with 'origin/adb-3.2-fixes'.
$ export ANDROID_SERIAL=00a1d5381d8e1c4f
$ time python -c 'from pwn import *; print adb.wait_for_device()'
[+] Waiting for device to come online: Done
00a1d5381d8e1c4f #<-- correct serial
python -c 'from pwn import *; print adb.wait_for_device()'  0.17s user 0.10s system 32% cpu 0.841 total #<-- 0.8 seconds

Compare with the native functionality, and baseline.

$ time python -c 'from pwn import *'
python -c 'from pwn import *'  0.14s user 0.08s system 96% cpu 0.234 total
$ time adb devices -l >/dev/null
adb devices -l > /dev/null  0.00s user 0.00s system 2% cpu 0.230 total

Separately, the following may cause a qemu warning to be emitted:

>>> context.device = adb.wait_for_device()
[x] Waiting for device to come online
[+] Waiting for device to come online: Done
>>> context.device = adb.wait_for_device()
[x] Waiting for device to come online
[!] Neither 'qemu-aarch64' nor 'qemu-aarch64-static' are available
[+] Waiting for device to come online: Done

This is because context.arch has been set, and we're attempting to locate the correct qemu-xxx to run the binary. However, no foreign-architecture binaries are actually being executed locally.

We resolve this by attempting to execute the binary first, and catching ENOEXEC, and then checking the type of the target binary.

@zachriggle
Copy link
Member Author

Apparently the SYNC:WRITE command silently swallows writing to a directory, and creates a temporary file.

>>> adb.listdir('/data/local/tmp')
[]
>>> adb.write('/data/local/tmp', 'hello')
>>> adb.listdir('/data/local/tmp')
['tmpyXj6mS']

@zachriggle zachriggle changed the title Fix adb.wait_for_device behavior and performance Multiple ADB performance and functionality fixes Dec 14, 2016
@zachriggle zachriggle changed the base branch from dev to stable December 14, 2016 01:05
@zachriggle zachriggle merged commit 386e686 into Gallopsled:stable Dec 14, 2016
Copy link
Contributor

@TethysSvensson TethysSvensson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not looked enough at the adb code to actually understand the context, but LGTM nevertheless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants