Skip to content

Commit

Permalink
Merge pull request #346 from doronz88/feature/process_launch
Browse files Browse the repository at this point in the history
processes: Add `launch` process using `BackBoardService`
  • Loading branch information
doronz88 authored Feb 21, 2024
2 parents 9141612 + 1ad3880 commit 9fe42a4
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/rpcclient/rpcclient/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ class LastElementNotFoundError(ElementNotFoundError):
pass


class LaunchError(BadReturnValueError):
""" failed to launch a child process """
pass


class RpcFileExistsError(BadReturnValueError):
""" RPC version for FileExistsError (errno = EEXIST) """
pass
Expand Down
2 changes: 2 additions & 0 deletions src/rpcclient/rpcclient/ios/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from rpcclient.ios.backlight import Backlight
from rpcclient.ios.lockdown import Lockdown
from rpcclient.ios.mobile_gestalt import MobileGestalt
from rpcclient.ios.processes import IosProcesses
from rpcclient.ios.screen_capture import ScreenCapture
from rpcclient.ios.sprinboard import SpringBoard
from rpcclient.ios.telephony import Telephony
Expand All @@ -21,6 +22,7 @@ def __init__(self, sock, sysname: str, arch, create_socket_cb: typing.Callable):
self.backlight = Backlight(self)
self.reports = Reports(self, CRASH_REPORTS_DIR)
self.mobile_gestalt = MobileGestalt(self)
self.processes = IosProcesses(self)
self.lockdown = Lockdown(self)
self.telephony = Telephony(self)
self.screen_capture = ScreenCapture(self)
Expand Down
37 changes: 37 additions & 0 deletions src/rpcclient/rpcclient/ios/processes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from typing import Optional

from rpcclient.darwin.processes import DarwinProcesses
from rpcclient.exceptions import LaunchError


class IosProcesses(DarwinProcesses):

def launch(self, bundle_id: str, unlock_device: bool = True, disable_aslr: bool = False,
wait_for_debugger: bool = False, stdout: Optional[str] = None,
stderr: Optional[str] = None) -> int:
""" launch process using BackBoardService
https://github.com/swigger/debugserver-ios/blob/master/inc/BackBoardServices.framework/Headers
/BackBoardServices.h"""
debug_options = {}
options = {}
sym = self._client.symbols
debug_options[sym.BKSDebugOptionKeyDisableASLR[0].py()] = disable_aslr
debug_options[sym.BKSDebugOptionKeyWaitForDebugger[0].py()] = wait_for_debugger
if stdout is not None:
debug_options[sym.BKSDebugOptionKeyStandardOutPath[0].py()] = stdout
if stderr is not None:
debug_options[sym.BKSDebugOptionKeyStandardErrorPath[0].py()] = stderr

options[sym.BKSOpenApplicationOptionKeyUnlockDevice[0].py()] = unlock_device
options[sym.BKSOpenApplicationOptionKeyDebuggingOptions[0].py()] = debug_options

bkssystem_service = self._client.objc_get_class('BKSSystemService').new().objc_symbol
bkssystem_service.openApplication_options_clientPort_withResult_(self._client.cf(bundle_id),
self._client.cf(options),
bkssystem_service.createClientPort(),
self._client.get_dummy_block())

pid = bkssystem_service.pidForApplication_(self._client.cf(bundle_id)).c_int32
if pid == -1:
raise LaunchError()
return pid
7 changes: 7 additions & 0 deletions src/rpcclient/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from rpcclient.client_factory import create_tcp_client
from rpcclient.darwin.client import DarwinClient
from rpcclient.exceptions import BadReturnValueError
from rpcclient.ios.client import IosClient
from rpcclient.protos.rpc_pb2 import ARCH_ARM64


Expand Down Expand Up @@ -41,18 +42,21 @@ def pytest_configure(config):
'''local_only: marks tests that require features the CI lacks (deselect with '-m "not local_only"')'''
)
config.addinivalue_line('markers', 'darwin: marks tests that require darwin platform to run')
config.addinivalue_line('markers', 'ios: marks tests that require ios platform to run')
config.addinivalue_line('markers', 'local_machine: marks tests that require local_machine to run')
config.addinivalue_line('markers', 'arm: marks tests that require arm architecture to run')


def pytest_collection_modifyitems(config, items):
skip_local_only = pytest.mark.skip(reason='remove --ci option to run')
skip_not_darwin = pytest.mark.skip(reason='Darwin system is required for this test')
skip_not_ios = pytest.mark.skip(reason='Ios system is required for this test')
skip_not_arm = pytest.mark.skip(reason='Arm arch is required for this test')
skip_not_local_machine = pytest.mark.skip(reason='Local machine is required for this test')

with closing(create_tcp_client('127.0.0.1')) as c:
is_darwin = isinstance(c, DarwinClient)
is_ios = isinstance(c, IosClient)
is_arm = c.arch == ARCH_ARM64

for item in items:
Expand All @@ -62,6 +66,9 @@ def pytest_collection_modifyitems(config, items):
if 'darwin' in item.keywords and not is_darwin:
# Skip test that require Darwin on non Darwin system
item.add_marker(skip_not_darwin)
if 'ios' in item.keywords and not is_ios:
# Skip test that require ios
item.add_marker(skip_not_ios)
if 'arm' in item.keywords and not is_arm:
# Skip tests that require arm on non arm architecture
item.add_marker(skip_not_arm)
Expand Down
15 changes: 15 additions & 0 deletions src/rpcclient/tests/test_processes.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from pathlib import Path

import pytest

from rpcclient.client_factory import DEFAULT_PORT
from rpcclient.exceptions import LaunchError

LAUNCHD_PID = 1
LAUNCHD_PATH = '/sbin/launchd'
Expand Down Expand Up @@ -29,3 +32,15 @@ def test_process_object(client):
assert fds[0].fd == 0
assert fds[1].fd == 1
assert fds[2].fd == 2


@pytest.mark.ios
def test_launch_process(client):
pid = client.processes.launch('com.apple.MobileAddressBook')
client.processes.kill(pid)


@pytest.mark.ios
def test_launch_invalid_process(client):
with pytest.raises(LaunchError):
client.processes.launch('com.apple.cyber')
4 changes: 4 additions & 0 deletions src/rpcserver/ents.plist
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@
<true/>
<key>com.apple.backboardd.launchapplications</key>
<true/>
<key>com.apple.frontboard.debugapplications</key>
<true/>
<key>com.apple.frontboard.launchapplications</key>
<true/>
<key>com.apple.private.logging.admin</key>
<true/>
<key>com.apple.security.exception.shared-preference.read-write</key>
Expand Down

0 comments on commit 9fe42a4

Please sign in to comment.