Skip to content

Commit

Permalink
(feat/wip) refactor spawning logic to support early instrumentation
Browse files Browse the repository at this point in the history
this commit contains many changes. the most important of which
is a completely rewritten Agent class, improving support for
early instrumentation.

pre this commit, because we we're injecting the frida gadget in
target applications, we expected communications to occur over
a tcp socket. as far back as frida 12.7+ support injecting the
frida-server into applications that are debuggable vastly
simplifies this process in jailed environments. as such, we can
use normal "usb" comms, and thereby more closely follow the
same logic as found in frida-* tools.

a small changelog for all the changes:

- remove the get_device_info() call that relied on frida scripts
  to get information about the platform. instead we're now using
  device.query_system_parameters()
- replace the old `explore` command with a new `start` command
- support spawning new applications
- support attaching to the frontmost application
- support enabling the node debug port, accessible via the chrome
  debugger
- support immediately resuming apps
- replace os with pathlib in some places
- remove the `objection device_type` command
- add the `resume` repl command to resume apps
- add a prompt token to show the current process state (pause/run)

no tests were fixed, so expect most of them to fail :P

related issues: #473, #474
  • Loading branch information
leonjza committed Oct 25, 2021
1 parent 74f0e79 commit 865fb7d
Show file tree
Hide file tree
Showing 20 changed files with 442 additions and 536 deletions.
49 changes: 2 additions & 47 deletions objection/commands/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,6 @@

from ..state.connection import state_connection
from ..state.device import device_state, Android, Ios
from ..utils.helpers import pretty_concat


def get_device_info() -> tuple:
"""
Get device information by first checking which runtimes
are available, and then extracting information about the
device based on the result.
"""

api = state_connection.get_api()

# set the frida version
frida = api.env_frida()
device_state.frida_version = frida['version']

environment = api.env_runtime()

# ios device information
if environment == 'ios':
device_state.device_type = Ios
package_info = api.env_ios()

# {'applicationName': 'za.sensepost.ipewpew',
# 'deviceName': 'iPhone 7 Plus',
# 'identifierForVendor': 'foo',
# 'model': 'iPhone', 'systemName': 'iOS', 'systemVersion': '12.1'}
device_state.os_version = package_info['systemVersion']

return pretty_concat(package_info['applicationName'], 30, left=True), \
package_info['systemName'], package_info['model'], package_info['systemVersion']

# android device information
if environment == 'android':
device_state.device_type = Android
package_info = api.env_android()

# {'application_name': 'com.sensepost.apewpew',
# 'board': 'universal5422', 'brand': 'samsung', 'device': 'foo',
# 'host': 'foo.bar', 'id': '1234', 'model': 'foo-bar',
# 'product': 'foo', 'user': 'root', 'version': '7.1.2'}
device_state.os_version = package_info['version']

return pretty_concat(package_info['application_name'], 30, left=True), \
package_info['device'], package_info['brand'], package_info['version']


def get_environment(args: list = None) -> None:
Expand All @@ -61,10 +16,10 @@ def get_environment(args: list = None) -> None:
:return:
"""

if device_state.device_type == Ios:
if device_state.platform == Ios:
_get_ios_environment()

if device_state.device_type == Android:
if device_state.platform == Android:
_get_android_environment()


Expand Down
60 changes: 30 additions & 30 deletions objection/commands/filemanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,10 @@ def cd(args: list) -> None:
does_exist = False

# check for existence based on the runtime
if device_state.device_type == Ios:
if device_state.platform == Ios:
does_exist = _path_exists_ios(path)

if device_state.device_type == Android:
if device_state.platform == Android:
does_exist = _path_exists_android(path)

# if we checked with the device that the path exists
Expand All @@ -89,16 +89,16 @@ def cd(args: list) -> None:
# see if its legit.
else:

proposed_path = device_state.device_type.path_seperator.join([current_dir, path])
proposed_path = device_state.platform.path_separator.join([current_dir, path])

# assume the proposed_path does not exist by default
does_exist = False

# check for existence based on the runtime
if device_state.device_type == Ios:
if device_state.platform == Ios:
does_exist = _path_exists_ios(proposed_path)

if device_state.device_type == Android:
if device_state.platform == Android:
does_exist = _path_exists_android(proposed_path)

# if we checked with the device that the path exists
Expand All @@ -122,10 +122,10 @@ def path_exists(path: str) -> bool:
:return:
"""

if device_state.device_type == Ios:
if device_state.platform == Ios:
return _path_exists_ios(path)

if device_state.device_type == Android:
if device_state.platform == Android:
return _path_exists_android(path)


Expand Down Expand Up @@ -169,10 +169,10 @@ def pwd(args: list = None) -> str:
if file_manager_state.cwd is not None:
return file_manager_state.cwd

if device_state.device_type == Ios:
if device_state.platform == Ios:
return _pwd_ios()

if device_state.device_type == Android:
if device_state.platform == Android:
return _pwd_android()


Expand Down Expand Up @@ -236,13 +236,13 @@ def ls(args: list) -> None:
else:
path = args[0]
if not os.path.isabs(path):
path = device_state.device_type.path_seperator.join([pwd(), path])
path = device_state.platform.path_separator.join([pwd(), path])

# based on the runtime, execute the correct ls method.
if device_state.device_type == Ios:
if device_state.platform == Ios:
_ls_ios(path)

if device_state.device_type == Android:
if device_state.platform == Android:
_ls_android(path)


Expand Down Expand Up @@ -393,10 +393,10 @@ def download(args: list) -> None:
source = args[0]
destination = args[1] if len(args) > 1 else os.path.basename(source)

if device_state.device_type == Ios:
if device_state.platform == Ios:
_download_ios(source, destination)

if device_state.device_type == Android:
if device_state.platform == Android:
_download_android(source, destination)


Expand All @@ -412,7 +412,7 @@ def _download_ios(path: str, destination: str) -> None:
# if the path we got is not absolute, join it with the
# current working directory
if not os.path.isabs(path):
path = device_state.device_type.path_seperator.join([pwd(), path])
path = device_state.platform.path_separator.join([pwd(), path])

api = state_connection.get_api()

Expand Down Expand Up @@ -448,7 +448,7 @@ def _download_android(path: str, destination: str) -> None:
# if the path we got is not absolute, join it with the
# current working directory
if not os.path.isabs(path):
path = device_state.device_type.path_seperator.join([pwd(), path])
path = device_state.platform.path_separator.join([pwd(), path])

api = state_connection.get_api()

Expand Down Expand Up @@ -488,13 +488,13 @@ def upload(args: list) -> None:
return

source = args[0]
destination = args[1] if len(args) > 1 else device_state.device_type.path_seperator.join(
destination = args[1] if len(args) > 1 else device_state.platform.path_separator.join(
[pwd(), os.path.basename(source)])

if device_state.device_type == Ios:
if device_state.platform == Ios:
_upload_ios(source, destination)

if device_state.device_type == Android:
if device_state.platform == Android:
_upload_android(source, destination)


Expand All @@ -508,7 +508,7 @@ def _upload_ios(path: str, destination: str) -> None:
"""

if not os.path.isabs(destination):
destination = device_state.device_type.path_seperator.join([pwd(), destination])
destination = device_state.platform.path_separator.join([pwd(), destination])

api = state_connection.get_api()
click.secho('Uploading {0} to {1}'.format(path, destination), fg='green', dim=True)
Expand Down Expand Up @@ -543,7 +543,7 @@ def _upload_android(path: str, destination: str) -> None:
"""

if not os.path.isabs(destination):
destination = device_state.device_type.path_seperator.join([pwd(), destination])
destination = device_state.platform.path_separator.join([pwd(), destination])

api = state_connection.get_api()
click.secho('Uploading {0} to {1}'.format(path, destination), fg='green', dim=True)
Expand Down Expand Up @@ -583,16 +583,16 @@ def rm(args: list) -> None:
target = args[0]

if not os.path.isabs(target):
target = device_state.device_type.path_seperator.join([pwd(), target])
target = device_state.platform.path_separator.join([pwd(), target])

if not click.confirm('Really delete {0} ?'.format(target)):
click.secho('Not deleting {0}'.format(target), dim=True)
return

if device_state.device_type == Ios:
if device_state.platform == Ios:
_rm_ios(target)

if device_state.device_type == Android:
if device_state.platform == Android:
_rm_android(target)


Expand Down Expand Up @@ -662,10 +662,10 @@ def cat(args: list):
source = args[0]
_, destination = tempfile.mkstemp('.file')

if device_state.device_type == Ios:
if device_state.platform == Ios:
_download_ios(source, destination)

if device_state.device_type == Android:
if device_state.platform == Android:
_download_android(source, destination)

click.secho('====', dim=True)
Expand Down Expand Up @@ -768,10 +768,10 @@ def list_folders_in_current_fm_directory() -> dict:
resp = {}

# get the folders based on the runtime
if device_state.device_type == Ios:
if device_state.platform == Ios:
response = _get_short_ios_listing()

elif device_state.device_type == Android:
elif device_state.platform == Android:
response = _get_short_android_listing()

# looks like we landed in an unknown runtime.
Expand Down Expand Up @@ -799,10 +799,10 @@ def list_files_in_current_fm_directory() -> dict:
resp = {}

# check for existence based on the runtime
if device_state.device_type == Ios:
if device_state.platform == Ios:
response = _get_short_ios_listing()

elif device_state.device_type == Android:
elif device_state.platform == Android:
response = _get_short_android_listing()

# looks like we landed in an unknown runtime.
Expand Down
2 changes: 1 addition & 1 deletion objection/commands/ios/plist.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def cat(args: list = None) -> None:

if not os.path.isabs(plist):
pwd = filemanager.pwd()
plist = device_state.device_type.path_seperator.join([pwd, plist])
plist = device_state.platform.path_separator.join([pwd, plist])

api = state_connection.get_api()
plist_data = api.ios_plist_read(plist)
Expand Down
4 changes: 2 additions & 2 deletions objection/commands/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ def alert(args: list = None) -> None:
else:
message = args[0]

if device_state.device_type == Ios:
if device_state.platform == Ios:
_alert_ios(message)

if device_state.device_type == Android:
if device_state.platform == Android:
pass


Expand Down
Loading

0 comments on commit 865fb7d

Please sign in to comment.