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

Enhance unlock_bootloader with better status messages #1001

Merged
merged 1 commit into from
Dec 27, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 50 additions & 10 deletions pwnlib/adb/adb.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def __do_deferred_initialization(self):
return

with context.local(device=self.serial):
abi = str(properties.ro.product.cpu.abi)
abi = getprop('ro.product.cpu.abi')
context.clear()
context.arch = str(abi)
self._arch = context.arch
Expand Down Expand Up @@ -959,17 +959,17 @@ def fastboot(args, *a, **kw):
@with_device
def fingerprint():
"""Returns the device build fingerprint."""
return str(properties.ro.build.fingerprint)
return getprop('ro.build.fingerprint')

@with_device
def product():
"""Returns the device product identifier."""
return str(properties.ro.build.product)
return getprop('ro.build.product')

@with_device
def build():
"""Returns the Build ID of the device."""
return str(properties.ro.build.id)
return getprop('ro.build.id')

@with_device
@no_emulator
Expand All @@ -979,9 +979,33 @@ def unlock_bootloader():
Note:
This requires physical interaction with the device.
"""
AdbClient().reboot_bootloader()
fastboot(['oem', 'unlock'])
fastboot(['continue'])
w = log.waitfor("Unlocking bootloader")
with w:
if getprop('ro.oem_unlock_supported') == '0':
log.error("Bootloader cannot be unlocked: ro.oem_unlock_supported=0")

if getprop('ro.boot.oem_unlock_support') == '0':
log.error("Bootloader cannot be unlocked: ro.boot.oem_unlock_support=0")

if getprop('sys.oem_unlock_allowed') == '0':
log.error("Bootloader cannot be unlocked: Enable OEM Unlock in developer settings first", context.device)

AdbClient().reboot_bootloader()

# Check to see if it's unlocked before attempting unlock
unlocked = fastboot(['getvar', 'unlocked'])
if 'unlocked: yes' in unlocked:
w.success("Already unlocked")
fastboot(['continue'])
return

fastboot(['oem', 'unlock'])
unlocked = fastboot(['getvar', 'unlocked'])

fastboot(['continue'])

if 'unlocked: yes' not in unlocked:
log.error("Unlock failed")

class Kernel(object):
_kallsyms = None
Expand Down Expand Up @@ -1038,7 +1062,7 @@ def lastmsg(self):

def enable_uart(self):
"""Reboots the device with kernel logging to the UART enabled."""
model = str(properties.ro.product.model)
model = getprop('ro.product.model')

known_commands = {
'Nexus 4': None,
Expand Down Expand Up @@ -1086,6 +1110,7 @@ def enable_uart(self):

class Property(object):
def __init__(self, name=None):
# Need to avoid overloaded setattr() so we go through __dict__
self.__dict__['_name'] = name

def __str__(self):
Expand All @@ -1107,6 +1132,15 @@ def __setattr__(self, attr, value):
attr = '%s.%s' % (self._name, attr)
setprop(attr, value)

def __eq__(self, other):
# Allow simple comparison, e.g.:
# adb.properties.ro.oem_unlock_supported == "1"
return type(other)(self) == other
Copy link
Member

Choose a reason for hiding this comment

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

This causes strange behavior in sphinx testing environment, when being compared against None (they should not do it in the first place, since is None is the preferred way).
Also I don't think that we need anything but str here.

Suggested change
return type(other)(self) == other
return str(self) == other


def __hash__(self, other):
# Allow hash indices matching on the property
return hash(self._name)

properties = Property()

def _build_date():
Expand Down Expand Up @@ -1209,8 +1243,8 @@ def compile(source):

# If we have an attached device, use its settings.
if context.device:
abi = str(properties.ro.product.cpu.abi)
sdk = str(properties.ro.build.version.sdk)
abi = getprop('ro.product.cpu.abi')
sdk = getprop('ro.build.version.sdk')

if abi is None:
log.error("Unknown CPU ABI")
Expand Down Expand Up @@ -1381,3 +1415,9 @@ def packages():
"""Returns a list of packages installed on the system"""
packages = process(['pm', 'list', 'packages']).recvall()
return [line.split('package:', 1)[-1] for line in packages.splitlines()]

@context.quietfunc
def version():
"""Returns rthe platform version as a tuple."""
prop = getprop('ro.build.version.release')
return [int(v) for v in prop.split('.')]