# `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)

  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)

    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

  __init__(serial, type, port=None, product='unknown', model='unknown', device='unknown', features=None, **kw)
  __repr__()

    Return repr(self).

  __str__()

    Return str(self).

  __wrapped(function)

    Wrapps a callable in a scope which selects the current device.

class pwnlib.adb.adb.Partitions

  Enable access to partitions

  Example:

       >>> hex(adb.partitions.vda.size)
       '0x...000'

  __dir__()

    Default dir() implementation.

  __weakref__

    list of weak references to the object

pwnlib.adb.adb._build_date()

  Returns the build date in the form YYYY-MM-DD as a string

pwnlib.adb.adb.adb(argv, *a, **kw)

  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
  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.build()

  Returns the Build ID of the device.

pwnlib.adb.adb.compile(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)

  Returns an `AdbDevice` instance for the currently-selected device (via `context.device`).

       >>> device = adb.current_device(any=True)
       >>> device
       AdbDevice(serial='emulator-5554', type='device', port='emulator', product='sdk_...phone_...', model='...', device='generic...')
       >>> device.port
       'emulator'

pwnlib.adb.adb.devices(serial=None)

  Returns a list of `Device` objects corresponding to the connected devices.

pwnlib.adb.adb.disable_verity()

  Disables dm-verity on the device.

pwnlib.adb.adb.exists(path)

  Return `True` if `path` 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)

  Executes a fastboot command.

  Returns:

    The command output.

pwnlib.adb.adb.find_ndk_project_root(source)

  Given a directory path, find the topmost project root.

  tl;dr “foo/bar/jni/baz.cpp” ==> “foo/bar”

pwnlib.adb.adb.fingerprint()

  Returns the device build fingerprint.

pwnlib.adb.adb.forward(port)

  Sets up a port to forward to the device.

pwnlib.adb.adb.getprop(name=None)

  Reads a properties from the system property store.

  Parameters:

    name (str) – Optional, read a single property.

  Returns:

    If `name` is not specified, a `dict` 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)

  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.interactive(**kw)

  Spawns an interactive shell.

pwnlib.adb.adb.isdir(path)

  Return `True` if `path` 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='/')

  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)

  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 is `False`.

  Returns:

    If `stream` is `False`, returns a string containing the log data. Otherwise, it returns a `pwnlib.tubes.tube.tube` connected to the log output.

pwnlib.adb.adb.makedirs(path)

  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)

  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.packages()

  Returns a list of packages installed on the system

pwnlib.adb.adb.pidof(name)

  Returns a list of PIDs for the named process.

pwnlib.adb.adb.proc_exe(pid)

  Returns the full path of the executable for the provided PID.

  Example:

       >>> adb.proc_exe(1)
       b'/init'

pwnlib.adb.adb.process(argv, *a, **kw)

  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.product()

  Returns the device product identifier.

pwnlib.adb.adb.pull(remote_path, local_path=None)

  Download a file from the device.

  Parameters:

    - remote_path (str) – Path or directory of the file on the device.

    - local_path (str) – Path to save the file to. Uses the file’s name by default.

  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)

  Upload a file to the device.

  Parameters:

    - local_path (str) – Path to the local file to push.

    - remote_path (str) – Path or directory to store the file on the device.

  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)

  Download a file from the device, and extract its contents.

  Parameters:

    - path (str) – Path to the file on the device.

    - target (str) – Optional, location to store the file. Uses a temporary file by default.

    - callback (callable) – See the documentation for `adb.protocol.AdbClient.read`.

  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.reboot(wait=True)

  Reboots the device.

pwnlib.adb.adb.reboot_bootloader()

  Reboots the device to the bootloader.

pwnlib.adb.adb.remount()

  Remounts the filesystem as writable.

pwnlib.adb.adb.root()

  Restarts adbd as root.

       >>> adb.root()

pwnlib.adb.adb.setprop(name, value)

  Writes a property to the system property store.

pwnlib.adb.adb.shell(**kw)

  Returns an interactive shell.

pwnlib.adb.adb.uninstall(package, *arguments)

  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)

  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()

  Unlocks the bootloader of the device.

  Note

  This requires physical interaction with the device.

pwnlib.adb.adb.unroot()

  Restarts adbd as AID_SHELL.

pwnlib.adb.adb.uptime() → float
  Returns:

    Uptime of the device, in seconds

  Example:

       >>> adb.uptime() > 3 # normally AVD takes ~7 seconds to boot
       True

pwnlib.adb.adb.version()

  Returns rthe platform version as a tuple.

pwnlib.adb.adb.wait_for_device(kick=False)

  Waits for a device to be connected.

  By default, waits for the currently-selected device (via `context.device`). To wait for a specific device, set `context.device`. To wait for any device, clear `context.device`.

  Returns:

    An `AdbDevice` instance for the device.

  Examples:

       >>> device = adb.wait_for_device()

pwnlib.adb.adb.which(name, all=False, *a, **kw)

  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']

       >>> adb.which('foobar') is None
       True
       >>> adb.which('foobar', all=True)
       []

pwnlib.adb.adb.whoami()

  Returns current shell user

  Example:

      >>> adb.whoami()
      b'root'

pwnlib.adb.adb.write(path, data=b'')

  Create a file on the device with the provided contents.

  Parameters:

    - path (str) – Path to the file on the device

    - data (str) – Contents to store in the file

  Examples:

       >>> adb.write('/dev/null', b'data')
       >>> adb.write('/data/local/tmp/')

This file exists only for backward compatibility