pwnlib.adb
— Android Debug Bridge
Provides utilities for interacting with Android devices via the Android Debug Bridge.
Using Android Devices with Pwntools
Pwntools tries to be as easy as possible to use with Android devices.
If you have only one device attached, everything “just works”.
If you have multiple devices, you have a handful of options to select one, or iterate over the devices.
First and most important is the context.device
property, which declares the “currently”
selected device in any scope. It can be set manually to a serial number, or to a Device
instance.
# Take the first available device
context.device = adb.wait_for_device()
# Set a device by serial number
context.device = 'ZX1G22LH8S'
# Set a device by its product name
for device in adb.devices():
if device.product == 'shamu':
break
else:
error("Could not find any shamus!")
Once a device is selected, you can operate on it with any of the functions in
the pwnlib.adb
module.
# Get a process listing
print(adb.process(['ps']).recvall())
# Fetch properties
print(adb.properties.ro.build.fingerprint)
# Read and write files
print(adb.read('/proc/version'))
adb.write('/data/local/tmp/foo', 'my data')
- class pwnlib.adb.adb.AdbDevice(serial, type, port=None, product='unknown', model='unknown', device='unknown', features=None, **kw)[source]
Encapsulates information about a connected device.
Example:
>>> device = adb.wait_for_device() >>> device.arch 'amd64' >>> device.bits 64 >>> device.os 'android' >>> device.product 'sdk_...phone..._...' >>> device.serial 'emulator-5554'
- __getattr__(name)[source]
Provides scoped access to
adb
module propertise, in the context of this device.>>> property = 'ro.build.fingerprint' >>> device = adb.wait_for_device() >>> adb.getprop(property) == device.getprop(property) True
- class pwnlib.adb.adb.Partitions[source]
Enable access to partitions
Example:
>>> hex(adb.partitions.vda.size) '0x...000'
- pwnlib.adb.adb.adb(argv, *a, **kw)[source]
Returns the output of an ADB subcommand.
>>> adb.adb('get-serialno') b'emulator-5554\n' >>> adb.adb(['shell', 'uname']) # it is better to use adb.process b'Linux\n'
- pwnlib.adb.adb.boot_time() int [source]
- Returns:
Boot time of the device, in Unix time, rounded to the nearest second.
Example:
>>> import time >>> adb.boot_time() < time.time() True
- pwnlib.adb.adb.compile(source)[source]
Compile a source file or project with the Android NDK.
Example:
>>> temp = tempfile.mktemp('.c') >>> write(temp, ''' ... #include <stdio.h> ... static char buf[4096]; ... int main() { ... FILE *fp = fopen("/proc/self/maps", "r"); ... int n = fread(buf, 1, sizeof(buf), fp); ... fwrite(buf, 1, n, stdout); ... return 0; ... }''') >>> filename = adb.compile(temp) >>> sent = adb.push(filename, "/data/local/tmp") >>> adb.process(sent).recvall() b'... /system/lib64/libc++.so\n...'
- pwnlib.adb.adb.current_device(any=False)[source]
Returns an
AdbDevice
instance for the currently-selected device (viacontext.device
).>>> device = adb.current_device(any=True) >>> device AdbDevice(serial='emulator-5554', type='device', port='emulator', product='sdk_...phone..._...', model='...', device='...') >>> device.port 'emulator'
- pwnlib.adb.adb.devices(serial=None)[source]
Returns a list of
Device
objects corresponding to the connected devices.
- pwnlib.adb.adb.exists(path)[source]
Return
True
ifpath
exists on the target device.Examples:
>>> adb.exists('/') True >>> adb.exists('/etc/hosts') True >>> adb.exists('/does/not/exist') False
- pwnlib.adb.adb.fastboot(args, *a, **kw)[source]
Executes a fastboot command.
- Returns:
The command output.
- pwnlib.adb.adb.find_ndk_project_root(source)[source]
Given a directory path, find the topmost project root.
tl;dr “foo/bar/jni/baz.cpp” ==> “foo/bar”
- pwnlib.adb.adb.getprop(name=None)[source]
Reads a properties from the system property store.
- Parameters:
name (str) – Optional, read a single property.
- Returns:
If
name
is not specified, adict
of all properties is returned. Otherwise, a string is returned with the contents of the named property.
Example:
>>> adb.getprop() {...}
- pwnlib.adb.adb.install(apk, *arguments)[source]
Install an APK onto the device.
This is a wrapper around ‘pm install’, which backs ‘adb install’.
- Parameters:
apk (str) – Path to the APK to intall (e.g.
'foo.apk'
)arguments – Supplementary arguments to ‘pm install’, e.g.
'-l', '-g'
.
- pwnlib.adb.adb.isdir(path)[source]
Return
True
ifpath
is a on the target device.Examples:
>>> adb.isdir('/') True >>> adb.isdir('/init') False >>> adb.isdir('/does/not/exist') False
- pwnlib.adb.adb.listdir(directory='/')[source]
Returns a list containing the entries in the provided directory.
Note
This uses the SYNC LIST functionality, which runs in the adbd SELinux context. If adbd is running in the su domain (‘adb root’), this behaves as expected.
Otherwise, less files may be returned due to restrictive SELinux policies on adbd.
- pwnlib.adb.adb.logcat(stream=False)[source]
Reads the system log file.
By default, causes logcat to exit after reading the file.
- Parameters:
stream (bool) – If
True
, the contents are streamed rather than read in a one-shot manner. Default isFalse
.- Returns:
If
stream
isFalse
, returns a string containing the log data. Otherwise, it returns apwnlib.tubes.tube.tube
connected to the log output.
- pwnlib.adb.adb.makedirs(path)[source]
Create a directory and all parent directories on the target device.
Note
Silently succeeds if the directory already exists.
Examples:
>>> adb.makedirs('/data/local/tmp/this/is/a/directory/hierarchy') >>> adb.listdir('/data/local/tmp/this/is/a/directory') ['hierarchy']
- pwnlib.adb.adb.mkdir(path)[source]
Create a directory on the target device.
Note
Silently succeeds if the directory already exists.
- Parameters:
path (str) – Directory to create.
Examples:
>>> adb.mkdir('/') >>> path = '/data/local/tmp/mkdir_test' >>> adb.exists(path) False >>> adb.mkdir(path) >>> adb.exists(path) True >>> adb.mkdir('/init') Traceback (most recent call last): ... PwnlibException: mkdir failed for /init, File exists
- pwnlib.adb.adb.proc_exe(pid)[source]
Returns the full path of the executable for the provided PID.
Example:
>>> adb.proc_exe(1) b'/system/bin/init'
- pwnlib.adb.adb.process(argv, *a, **kw)[source]
Execute a process on the device.
See
pwnlib.tubes.process.process
documentation for more info.- Returns:
A
pwnlib.tubes.process.process
tube.
Examples:
>>> adb.root() >>> print(adb.process(['cat','/proc/version']).recvall().decode('utf-8')) Linux version ...
- pwnlib.adb.adb.pull(remote_path, local_path=None)[source]
Download a file from the device.
- Parameters:
- Returns:
The contents of the file.
Example:
>>> _=adb.pull('/proc/version', './proc-version') >>> print(read('./proc-version').decode('utf-8')) Linux version ...
- pwnlib.adb.adb.push(local_path, remote_path)[source]
Upload a file to the device.
- Parameters:
- Returns:
Remote path of the file.
Example:
>>> write('./filename', 'contents') >>> adb.push('./filename', '/data/local/tmp') '/data/local/tmp/filename' >>> adb.read('/data/local/tmp/filename') b'contents' >>> adb.push('./filename', '/does/not/exist') Traceback (most recent call last): ... PwnlibException: Could not stat '/does/not/exist'
- pwnlib.adb.adb.read(path, target=None, callback=None)[source]
Download a file from the device, and extract its contents.
- Parameters:
Examples:
>>> print(adb.read('/proc/version').decode('utf-8')) Linux version ... >>> adb.read('/does/not/exist') Traceback (most recent call last): ... PwnlibException: Could not stat '/does/not/exist'
- pwnlib.adb.adb.uninstall(package, *arguments)[source]
Uninstall an APK from the device.
This is a wrapper around ‘pm uninstall’, which backs ‘adb uninstall’.
- Parameters:
package (str) – Name of the package to uninstall (e.g.
'com.foo.MyPackage'
)arguments – Supplementary arguments to
'pm install'
, e.g.'-k'
.
- pwnlib.adb.adb.unlink(path, recursive=False)[source]
Unlinks a file or directory on the target device.
Examples:
>>> adb.unlink("/does/not/exist") Traceback (most recent call last): ... PwnlibException: Could not unlink '/does/not/exist': Does not exist >>> filename = '/data/local/tmp/unlink-test' >>> adb.write(filename, 'hello') >>> adb.exists(filename) True >>> adb.unlink(filename) >>> adb.exists(filename) False >>> adb.mkdir(filename) >>> adb.write(filename + '/contents', 'hello') >>> adb.unlink(filename) Traceback (most recent call last): ... PwnlibException: Cannot delete non-empty directory '/data/local/tmp/unlink-test' without recursive=True >>> adb.unlink(filename, recursive=True) >>> adb.exists(filename) False
- pwnlib.adb.adb.unlock_bootloader()[source]
Unlocks the bootloader of the device.
Note
This requires physical interaction with the device.
- pwnlib.adb.adb.uptime() float [source]
- Returns:
Uptime of the device, in seconds
Example:
>>> adb.uptime() > 3 # normally AVD takes ~7 seconds to boot True
- pwnlib.adb.adb.wait_for_device(kick=False)[source]
Waits for a device to be connected.
By default, waits for the currently-selected device (via
context.device
). To wait for a specific device, setcontext.device
. To wait for any device, clearcontext.device
.- Returns:
An
AdbDevice
instance for the device.
Examples:
>>> device = adb.wait_for_device()
- pwnlib.adb.adb.which(name, all=False, *a, **kw)[source]
Retrieves the full path to a binary in
$PATH
on the device- Parameters:
name (str) – Binary name
all (bool) – Whether to return all paths, or just the first
*a – Additional arguments for
adb.process()
**kw – Additional arguments for
adb.process()
- Returns:
Either a path, or list of paths
Example:
>>> adb.which('sh') '/system/bin/sh' >>> adb.which('sh', all=True) ['/system/bin/sh', '/vendor/bin/sh'] >>> adb.which('foobar') is None True >>> adb.which('foobar', all=True) []
- pwnlib.adb.adb.write(path, data=b'')[source]
Create a file on the device with the provided contents.
Examples:
>>> adb.write('/dev/null', b'data') >>> adb.write('/data/local/tmp/')
This file exists only for backward compatibility