Skip to content

Commit

Permalink
client: add lief
Browse files Browse the repository at this point in the history
  • Loading branch information
doronz88 committed Mar 14, 2022
1 parent f074726 commit a3a14c9
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/rpcclient/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ dataclasses; python_version<"3.7"
pygments
objc_types_decoder
pycrashreport>=0.0.8
lief
2 changes: 2 additions & 0 deletions src/rpcclient/rpcclient/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from rpcclient.exceptions import ArgumentError, SymbolAbsentError, SpawnError, ServerDiedError, \
InvalidServerVersionMagicError
from rpcclient.fs import Fs
from rpcclient.lief import Lief
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, \
Expand Down Expand Up @@ -75,6 +76,7 @@ def __init__(self, sock, sysname: str, hostname: str, port: int = None):
self.fs = Fs(self)
self.processes = Processes(self)
self.network = Network(self)
self.lief = Lief(self)

def info(self):
""" print information about current target """
Expand Down
4 changes: 4 additions & 0 deletions src/rpcclient/rpcclient/darwin/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from rpcclient.client import Client
from rpcclient.darwin import objective_c_class
from rpcclient.darwin.consts import kCFNumberSInt64Type, kCFNumberDoubleType, CFStringEncoding, kCFAllocatorDefault
from rpcclient.darwin.darwin_lief import DarwinLief
from rpcclient.darwin.fs import DarwinFs
from rpcclient.darwin.hid import Hid
from rpcclient.darwin.ioregistry import IORegistry
Expand All @@ -24,6 +25,7 @@
from rpcclient.darwin.time import Time
from rpcclient.darwin.xpc import Xpc
from rpcclient.exceptions import RpcClientException, MissingLibraryError
from rpcclient.macos.bluetooth import Bluetooth
from rpcclient.structs.consts import RTLD_NOW

IsaMagic = namedtuple('IsaMagic', 'mask value')
Expand Down Expand Up @@ -71,6 +73,8 @@ def __init__(self, sock, sysname: str, hostname: str, port: int = None):
self.syslog = Syslog(self)
self.time = Time(self)
self.hid = Hid(self)
self.lief = DarwinLief(self)
self.bluetooth = Bluetooth(self)

@property
def modules(self) -> typing.List[str]:
Expand Down
7 changes: 7 additions & 0 deletions src/rpcclient/rpcclient/darwin/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -621,3 +621,10 @@ class NSStringEncoding(Enum):
kHIDUsage_Csmr_ACFormat = 0x23C # Selector
# 0x23D - 0xFFFF Reserved
kHIDUsage_Csmr_Reserved = 0xFFFF

kSecCodeMagicRequirement = 0xfade0c00 # single requirement
kSecCodeMagicRequirementSet = 0xfade0c01 # requirement set
kSecCodeMagicCodeDirectory = 0xfade0c02 # CodeDirectory
kSecCodeMagicEmbeddedSignature = 0xfade0cc0 # single-architecture embedded signature
kSecCodeMagicDetachedSignature = 0xfade0cc1 # detached multi-architecture signature
kSecCodeMagicEntitlement = 0xfade7171 # entitlement blob
31 changes: 31 additions & 0 deletions src/rpcclient/rpcclient/darwin/darwin_lief.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import plistlib
import struct
from typing import Mapping

import lief

from rpcclient.common import path_to_str
from rpcclient.darwin.consts import kSecCodeMagicEntitlement
from rpcclient.exceptions import NoEntitlementsError
from rpcclient.lief import Lief


class DarwinLief(Lief):
@path_to_str('path')
def get_entitlements(self, path: str) -> Mapping:
with self._client.fs.open(path, 'r') as f:
buf = f.readall()
parsed = lief.parse(buf)
code_signature = buf[parsed.code_signature.data_offset:
parsed.code_signature.data_offset + parsed.code_signature.data_size]

ent_magic = struct.pack('>I', kSecCodeMagicEntitlement)
ent_magic_offset = code_signature.find(ent_magic)

if ent_magic_offset == -1:
raise NoEntitlementsError()

ent_buf = code_signature[ent_magic_offset + len(ent_magic) + 4:]
end_plist_magic = b'</plist>'
ent_buf = ent_buf[:ent_buf.find(end_plist_magic) + len(end_plist_magic)]
return plistlib.loads(ent_buf)
5 changes: 5 additions & 0 deletions src/rpcclient/rpcclient/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,8 @@ class MissingLibraryError(RpcClientException):
class PermissionDeniedError(RpcClientException):
""" failed to access a certain something """
pass


class NoEntitlementsError(RpcClientException):
""" binary contains no entitlements """
pass
28 changes: 28 additions & 0 deletions src/rpcclient/rpcclient/lief.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from collections import namedtuple
from typing import Mapping

import lief

from rpcclient.common import path_to_str

Symbol = namedtuple('Symbol', 'origin value')


class Lief:
"""" parse and patch executable files """

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

@path_to_str('path')
def parse(self, path: str):
with self._client.fs.open(path, 'r') as f:
return lief.parse(f.readall())

@path_to_str('path')
def get_symbols(self, path: str) -> Mapping[str, Symbol]:
result = {}
parsed = self.parse(path)
for s in parsed.symbols:
result[s.name] = Symbol(origin=s.origin, value=s.value)
return result

0 comments on commit a3a14c9

Please sign in to comment.