Skip to content

Commit

Permalink
client: refactor: all class docstrings
Browse files Browse the repository at this point in the history
  • Loading branch information
doronz88 committed Feb 20, 2022
1 parent 69e9691 commit 0538e7b
Show file tree
Hide file tree
Showing 15 changed files with 66 additions and 23 deletions.
15 changes: 12 additions & 3 deletions src/rpcclient/rpcclient/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
from traitlets.config import Config

from rpcclient.darwin.structs import pid_t, exitcode_t
from rpcclient.exceptions import ArgumentError, SymbolAbsentError, SpawnError, ServerDiedError
from rpcclient.exceptions import ArgumentError, SymbolAbsentError, SpawnError, ServerDiedError, \
InvalidServerVersionMagicError
from rpcclient.fs import Fs
from rpcclient.network import Network
from rpcclient.processes import Processes
from rpcclient.protocol import protocol_message_t, cmd_type_t, exec_chunk_t, exec_chunk_type_t, UNAME_VERSION_LEN, \
reply_protocol_message_t, dummy_block_t
reply_protocol_message_t, dummy_block_t, SERVER_MAGIC_VERSION
from rpcclient.symbol import Symbol
from rpcclient.symbols_jar import SymbolsJar

Expand Down Expand Up @@ -49,6 +50,8 @@


class Client:
""" Main client interface to access remote rpcserver """

DEFAULT_ARGV = ['/bin/sh']
DEFAULT_ENVP = []

Expand Down Expand Up @@ -187,7 +190,7 @@ def poke(self, address: int, data: bytes):
self._sock.sendall(message)

def get_dummy_block(self) -> Symbol:
""" poke data at given address """
""" get an address for a stub block containing nothing """
message = protocol_message_t.build({
'cmd_type': cmd_type_t.CMD_GET_DUMMY_BLOCK,
'data': None,
Expand Down Expand Up @@ -340,8 +343,14 @@ def _ipython_run_cell_hook(self, info):
)

def reconnect(self):
""" close current socket and attempt to reconnect """
self._sock = socket()
self._sock.connect((self._hostname, self._port))
magic = self._recvall(len(SERVER_MAGIC_VERSION))

if magic != SERVER_MAGIC_VERSION:
raise InvalidServerVersionMagicError(f'got an invalid server magic: {magic.hex()}')

self._recvall(UNAME_VERSION_LEN)

def _execute(self, argv: typing.List[str], envp: typing.List[str]) -> int:
Expand Down
6 changes: 0 additions & 6 deletions src/rpcclient/rpcclient/darwin/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,6 @@ def roots(self) -> typing.List[str]:
""" get a list of all accessible darwin roots when used for lookup of files/preferences/... """
return ['/', '/var/root']

def set_airplane_mode(self, mode: bool):
""" set whether the device should enter airplane mode (turns off baseband, bt, etc...) """
preferences = self.symbols.objc_getClass('RadiosPreferences').objc_call('new')
preferences.objc_call('setAirplaneMode:', mode)
preferences.objc_call('synchronize')

def symbol(self, symbol: int):
""" at a symbol object from a given address """
return DarwinSymbol.create(symbol, self)
Expand Down
4 changes: 4 additions & 0 deletions src/rpcclient/rpcclient/darwin/crash_reports.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@


class CrashReports:
"""" manage crash reports """

def __init__(self, client, crash_reports_dir):
self._client = client
self._crash_reports_dir = crash_reports_dir

def list(self, prefixed='') -> List[CrashReport]:
""" get a list of all crash reports as CrashReport parsed objects """
result = []
for root in self._client.roots:
root = Path(root) / self._crash_reports_dir
Expand All @@ -24,5 +27,6 @@ def list(self, prefixed='') -> List[CrashReport]:
return result

def clear(self, prefixed=''):
""" remove all existing crash reports """
for entry in self.list(prefixed=prefixed):
self._client.fs.remove(entry.filename)
2 changes: 0 additions & 2 deletions src/rpcclient/rpcclient/darwin/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ def _deallocate(self):


class DarwinFs(Fs):
CHUNK_SIZE = 1024

@path_to_str('path')
def stat(self, path: str):
""" stat(filename) at remote. read man for more details. """
Expand Down
2 changes: 0 additions & 2 deletions src/rpcclient/rpcclient/darwin/ioregistry.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,6 @@ def temperature(self, value: int):
class IORegistry:
"""
IORegistry utils
For more information please read:
https://developer.apple.com/library/archive/documentation/DeviceDrivers/Conceptual/IOKitFundamentals/TheRegistry/TheRegistry.html
"""

Expand Down
3 changes: 1 addition & 2 deletions src/rpcclient/rpcclient/darwin/location.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ def from_value(cls, value: int):
class Location:
"""
Wrapper to CLLocationManager
For details: https://developer.apple.com/documentation/corelocation/cllocationmanager?language=objc
https://developer.apple.com/documentation/corelocation/cllocationmanager?language=objc
"""

def __init__(self, client):
Expand Down
15 changes: 15 additions & 0 deletions src/rpcclient/rpcclient/darwin/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@


class Recorder:
"""
Wrapper for AVAudioRecorder
https://developer.apple.com/documentation/avfaudio/avaudiorecorder?language=objc
"""

def __init__(self, client, session, recorder: DarwinSymbol):
self._client = client
self._session = session
Expand Down Expand Up @@ -39,6 +44,11 @@ def recording(self) -> bool:


class Player:
"""
Wrapper for AVAudioPlayer
https://developer.apple.com/documentation/avfaudio/avaudioplayer?language=objc
"""

def __init__(self, client, session, player):
self._client = client
self._session = session
Expand Down Expand Up @@ -76,6 +86,11 @@ def loops(self, value: int):


class AudioSession:
"""
wrapper for AVAudioSession
https://developer.apple.com/documentation/avfaudio/avaudiosession?language=objc
"""

def __init__(self, client):
self._client = client

Expand Down
8 changes: 8 additions & 0 deletions src/rpcclient/rpcclient/darwin/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ def _deallocate(self):


class DarwinNetwork(Network):
""" network utils """

def __init__(self, client):
super().__init__(client)
self._load_wifi_library()
Expand All @@ -115,6 +117,12 @@ def _load_wifi_library(self):
return
logger.warning('WiFi library isn\'t available')

def set_airplane_mode(self, mode: bool):
""" set whether the device should enter airplane mode (turns off baseband, bt, etc...) """
preferences = self._client.symbols.objc_getClass('RadiosPreferences').objc_call('new')
preferences.objc_call('setAirplaneMode:', mode)
preferences.objc_call('synchronize')

@property
def wifi_interfaces(self) -> List[str]:
""" get a list of all available wifi interfaces """
Expand Down
2 changes: 2 additions & 0 deletions src/rpcclient/rpcclient/darwin/processes.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class Ipv6UdpFd(Ipv6SocketFd):


class DarwinProcesses(Processes):
""" manage processes """

def get_proc_path(self, pid: int) -> Optional[str]:
""" call proc_pidpath(filename, ...) at remote. review xnu header for more details. """
with self._client.safe_malloc(MAXPATHLEN) as path:
Expand Down
1 change: 1 addition & 0 deletions src/rpcclient/rpcclient/darwin/symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ def _decode_cfdict(self) -> Mapping:

@property
def py(self):
""" get a python object from a core foundation one """
if self == 0:
return None

Expand Down
18 changes: 14 additions & 4 deletions src/rpcclient/rpcclient/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,58 +1,68 @@
class RpcClientException(Exception):
""" general exception """
pass


class InvalidServerVersionMagicError(RpcClientException):
""" server handshake failed due to an invalid magic """
pass


class ServerDiedError(RpcClientException):
""" server became disconnected during an operation """
pass


class SymbolAbsentError(RpcClientException):
""" trying to access a symbol which is not exported from any library currently loaded into the server's memory """
pass


class ArgumentError(RpcClientException):
""" at least one of the supplied arguments for a given function was invalid """
pass


class BadReturnValueError(RpcClientException):
""" remote c function returned an error """
pass


class NoSuchPreferenceError(RpcClientException):
""" attempt to read a preference data which doesn't exist """
pass


class CfSerializationError(RpcClientException):
""" failed to decode a cfobject into a python object """
pass


class SpawnError(RpcClientException):
pass


class InvalidArgumentError(RpcClientException):
""" failed to spawn a child process """
pass


class FailedToConnectError(RpcClientException):
""" failed to connect to rpcserver """
pass


class UnrecognizedSelectorError(RpcClientException):
""" tried to access a non-existing objc object selector """
pass


class GettingObjectiveCClassError(RpcClientException):
""" failed to create an objc class wrapper for a given object """
pass


class MissingLibraryError(RpcClientException):
""" a required library could not be found """
pass


class PermissionDeniedError(RpcClientException):
""" failed to access a certain something """
pass
8 changes: 5 additions & 3 deletions src/rpcclient/rpcclient/fs.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import posixpath
from typing import Iterator, List

from rpcclient.common import path_to_str
from rpcclient.exceptions import InvalidArgumentError, BadReturnValueError
from rpcclient.allocated import Allocated
from rpcclient.common import path_to_str
from rpcclient.exceptions import BadReturnValueError, ArgumentError
from rpcclient.structs.consts import O_RDONLY, O_WRONLY, O_CREAT, O_TRUNC, S_IFMT, S_IFDIR, O_RDWR, SEEK_CUR, S_IFREG, \
DT_LNK, DT_UNKNOWN, S_IFLNK, DT_REG, DT_DIR

Expand Down Expand Up @@ -153,6 +153,8 @@ def readall(self, chunk_size: int = CHUNK_SIZE) -> bytes:


class Fs:
""" filesystem utils """

def __init__(self, client):
self._client = client

Expand Down Expand Up @@ -210,7 +212,7 @@ def open(self, file: str, mode: str, access: int = 0o777) -> File:
}
mode = available_modes.get(mode)
if mode is None:
raise InvalidArgumentError(f'mode can be only one of: {available_modes.keys()}')
raise ArgumentError(f'mode can be only one of: {available_modes.keys()}')

fd = self._client.symbols.open(file, mode, access).c_int32
if fd < 0:
Expand Down
2 changes: 1 addition & 1 deletion src/rpcclient/rpcclient/linux/fs.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@


class LinuxFs(Fs):
CHUNK_SIZE = 1024
""" Filesystem utils """

def listdir(self, dirname='.') -> List[Struct]:
""" list directory contents(at remote).
Expand Down
1 change: 1 addition & 0 deletions src/rpcclient/rpcclient/macos/bluetooth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@


class Bluetooth:
""" bluetooth utils """

def __init__(self, client):
self._client = client
Expand Down
2 changes: 2 additions & 0 deletions src/rpcclient/rpcclient/symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def _parse(self, stream, context, path):


class Symbol(int):
""" wrapper for a remote symbol object """

PROXY_METHODS = ['peek', 'poke']

@classmethod
Expand Down

0 comments on commit 0538e7b

Please sign in to comment.