Skip to content

Commit

Permalink
Merge pull request #114 from doronz88/feature/call_double
Browse files Browse the repository at this point in the history
Feature/call double
  • Loading branch information
doronz88 authored Mar 17, 2022
2 parents 53e0512 + 0edc54f commit 1df7fec
Show file tree
Hide file tree
Showing 7 changed files with 604 additions and 40 deletions.
34 changes: 23 additions & 11 deletions src/rpcclient/rpcclient/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from socket import socket

import IPython
from construct import Int64sl
from construct import Int64sl, Float64l, Float32l
from traitlets.config import Config

from rpcclient.darwin.structs import pid_t, exitcode_t
Expand All @@ -22,9 +22,10 @@
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, SERVER_MAGIC_VERSION
reply_protocol_message_t, dummy_block_t, SERVER_MAGIC_VERSION, argument_type_t
from rpcclient.symbol import Symbol
from rpcclient.symbols_jar import SymbolsJar
from rpcclient.sysctl import Sysctl

tty_support = False
try:
Expand Down Expand Up @@ -77,6 +78,7 @@ def __init__(self, sock, sysname: str, hostname: str, port: int = None):
self.processes = Processes(self)
self.network = Network(self)
self.lief = Lief(self)
self.sysctl = Sysctl(self)

def info(self):
""" print information about current target """
Expand Down Expand Up @@ -129,7 +131,7 @@ def dlsym(self, lib: int, symbol_name: str):
err = Int64sl.parse(self._recvall(Int64sl.sizeof()))
return err

def call(self, address: int, argv: typing.List[int] = None) -> Symbol:
def call(self, address: int, argv: typing.List[int] = None, return_float64=False, return_float32=False) -> Symbol:
""" call a remote function and retrieve its return value as Symbol object """
fixed_argv = []
free_list = []
Expand All @@ -154,27 +156,37 @@ def call(self, address: int, argv: typing.List[int] = None) -> Symbol:
tmp.poke(arg)
free_list.append(tmp)

elif isinstance(arg, int) or isinstance(arg, Symbol):
pass
if isinstance(tmp, int):
tmp &= 0xffffffffffffffff
fixed_argv.append({'type': argument_type_t.Integer, 'value': tmp})

elif isinstance(tmp, float):
fixed_argv.append({'type': argument_type_t.Double, 'value': tmp})

else:
raise ArgumentError(f'invalid parameter type: {arg}')

tmp &= 0xffffffffffffffff

fixed_argv.append(tmp)

message = protocol_message_t.build({
'cmd_type': cmd_type_t.CMD_CALL,
'data': {'address': address, 'argv': fixed_argv},
})
self._sock.sendall(message)
err = Int64sl.parse(self._recvall(Int64sl.sizeof()))
integer_err = Int64sl.parse(self._recvall(Int64sl.sizeof()))

double_buf = self._recvall(Float64l.sizeof())
float32_err = Float32l.parse(double_buf)
float64_err = Float64l.parse(double_buf)

for f in free_list:
self.symbols.free(f)

return self.symbol(err)
if return_float32:
return float32_err

if return_float64:
return float64_err

return self.symbol(integer_err)

def peek(self, address: int, size: int) -> bytes:
""" peek data at given address """
Expand Down
162 changes: 161 additions & 1 deletion src/rpcclient/rpcclient/darwin/consts.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from enum import Enum
from enum import Enum, auto

kCFAllocatorDefault = 0
MACH_PORT_NULL = 0
Expand Down Expand Up @@ -628,3 +628,163 @@ class NSStringEncoding(Enum):
kSecCodeMagicEmbeddedSignature = 0xfade0cc0 # single-architecture embedded signature
kSecCodeMagicDetachedSignature = 0xfade0cc1 # detached multi-architecture signature
kSecCodeMagicEntitlement = 0xfade7171 # entitlement blob


class IOHIDDigitizerTransducerType(Enum):
kIOHIDDigitizerTransducerTypeStylus = 0
kIOHIDDigitizerTransducerTypePuck = 1
kIOHIDDigitizerTransducerTypeFinger = 2
kIOHIDDigitizerTransducerTypeHand = 3


class IOHIDSwipeMask(Enum):
kIOHIDSwipeNone = 0x00000000
kIOHIDSwipeUp = 0x00000001
kIOHIDSwipeDown = 0x00000002
kIOHIDSwipeLeft = 0x00000004
kIOHIDSwipeRight = 0x00000008
kIOHIDScaleExpand = 0x00000010
kIOHIDScaleContract = 0x00000020
kIOHIDRotateCW = 0x00000040
kIOHIDRotateCCW = 0x00000080


def IOHIDEventTypeMask(type_):
return 1 << type_


def IOHIDEventFieldBase(type_):
return type_ << 16


def IOHIDEventFieldOffsetOf(field):
return field & 0xffff


class IOHIDEventType(Enum):
kIOHIDEventTypeNULL = 0
kIOHIDEventTypeVendorDefined = 1
kIOHIDEventTypeButton = 2
kIOHIDEventTypeKeyboard = 3
kIOHIDEventTypeTranslation = 4
kIOHIDEventTypeRotation = 5
kIOHIDEventTypeScroll = 6
kIOHIDEventTypeScale = 7
kIOHIDEventTypeZoom = 8
kIOHIDEventTypeVelocity = 9
kIOHIDEventTypeOrientation = 10
kIOHIDEventTypeDigitizer = 11
kIOHIDEventTypeAmbientLightSensor = 12
kIOHIDEventTypeAccelerometer = 13
kIOHIDEventTypeProximity = 14
kIOHIDEventTypeTemperature = 15
kIOHIDEventTypeNavigationSwipe = 16
kIOHIDEventTypePointer = 17
kIOHIDEventTypeProgress = 18
kIOHIDEventTypeMultiAxisPointer = 19
kIOHIDEventTypeGyro = 20
kIOHIDEventTypeCompass = 21
kIOHIDEventTypeZoomToggle = 22
kIOHIDEventTypeDockSwipe = 23 # just like kIOHIDEventTypeNavigationSwipe, but intended for consumption by Dock
kIOHIDEventTypeSymbolicHotKey = 24
kIOHIDEventTypePower = 25
kIOHIDEventTypeLED = 26
kIOHIDEventTypeFluidTouchGesture = 27 # This will eventually superseed Navagation and Dock swipes
kIOHIDEventTypeBoundaryScroll = 28
kIOHIDEventTypeBiometric = 29
kIOHIDEventTypeUnicode = 30
kIOHIDEventTypeAtmosphericPressure = 31
kIOHIDEventTypeForce = 32
kIOHIDEventTypeMotionActivity = 33
kIOHIDEventTypeMotionGesture = 34
kIOHIDEventTypeGameController = 35
kIOHIDEventTypeHumidity = 36
kIOHIDEventTypeCollection = 37
kIOHIDEventTypeBrightness = 38
kIOHIDEventTypeCount = 39 # This should always be last

# DEPRECATED:
kIOHIDEventTypeSwipe = 16
kIOHIDEventTypeMouse = 17


class IOHIDDigitizerEventMask(Enum):
kIOHIDDigitizerEventRange = 1 << 0
kIOHIDDigitizerEventTouch = 1 << 1
kIOHIDDigitizerEventPosition = 1 << 2
kIOHIDDigitizerEventStop = 1 << 3
kIOHIDDigitizerEventPeak = 1 << 4
kIOHIDDigitizerEventIdentity = 1 << 5
kIOHIDDigitizerEventAttribute = 1 << 6
kIOHIDDigitizerEventCancel = 1 << 7
kIOHIDDigitizerEventStart = 1 << 8
kIOHIDDigitizerEventResting = 1 << 9
kIOHIDDigitizerEventFromEdgeFlat = 1 << 10
kIOHIDDigitizerEventFromEdgeTip = 1 << 11
kIOHIDDigitizerEventFromCorner = 1 << 12
kIOHIDDigitizerEventSwipePending = 1 << 13
kIOHIDDigitizerEventFromEdgeForcePending = 1 << 14
kIOHIDDigitizerEventFromEdgeForceActive = 1 << 15
kIOHIDDigitizerEventForcePopped = 1 << 16
kIOHIDDigitizerEventSwipeUp = 1 << 24
kIOHIDDigitizerEventSwipeDown = 1 << 25
kIOHIDDigitizerEventSwipeLeft = 1 << 26
kIOHIDDigitizerEventSwipeRight = 1 << 27
kIOHIDDigitizerEventEstimatedAltitude = 1 << 28
kIOHIDDigitizerEventEstimatedAzimuth = 1 << 29
kIOHIDDigitizerEventEstimatedPressure = 1 << 30
kIOHIDDigitizerEventSwipeMask = 0xF << 24


class IOHIDEventField(Enum):
kIOHIDEventFieldIsRelative = IOHIDEventFieldBase(IOHIDEventType.kIOHIDEventTypeNULL.value)
kIOHIDEventFieldIsCollection = auto()
kIOHIDEventFieldIsPixelUnits = auto()
kIOHIDEventFieldIsCenterOrigin = auto()
kIOHIDEventFieldIsBuiltIn = auto()


class IOHIDEventOptionBits(Enum):
kIOHIDEventOptionNone = 0
kIOHIDEventOptionIsAbsolute = 1 << 0
kIOHIDEventOptionIsCollection = 1 << 1
kIOHIDEventOptionIsPixelUnits = 1 << 2
kIOHIDEventOptionIsCenterOrigin = 1 << 3
kIOHIDEventOptionIsBuiltIn = 1 << 4

# misspellings
kIOHIDEventOptionPixelUnits = kIOHIDEventOptionIsPixelUnits


class IOHIDEventFieldDigitizer(Enum):
kIOHIDEventFieldDigitizerX = IOHIDEventFieldBase(IOHIDEventType.kIOHIDEventTypeDigitizer.value)
kIOHIDEventFieldDigitizerY = auto()
kIOHIDEventFieldDigitizerZ = auto()
kIOHIDEventFieldDigitizerButtonMask = auto()
kIOHIDEventFieldDigitizerType = auto()
kIOHIDEventFieldDigitizerIndex = auto()
kIOHIDEventFieldDigitizerIdentity = auto()
kIOHIDEventFieldDigitizerEventMask = auto()
kIOHIDEventFieldDigitizerRange = auto()
kIOHIDEventFieldDigitizerTouch = auto()
kIOHIDEventFieldDigitizerPressure = auto()
kIOHIDEventFieldDigitizerAuxiliaryPressure = auto() # BarrelPressure
kIOHIDEventFieldDigitizerTwist = auto()
kIOHIDEventFieldDigitizerTiltX = auto()
kIOHIDEventFieldDigitizerTiltY = auto()
kIOHIDEventFieldDigitizerAltitude = auto()
kIOHIDEventFieldDigitizerAzimuth = auto()
kIOHIDEventFieldDigitizerQuality = auto()
kIOHIDEventFieldDigitizerDensity = auto()
kIOHIDEventFieldDigitizerIrregularity = auto()
kIOHIDEventFieldDigitizerMajorRadius = auto()
kIOHIDEventFieldDigitizerMinorRadius = auto()
kIOHIDEventFieldDigitizerCollection = auto()
kIOHIDEventFieldDigitizerCollectionChord = auto()
kIOHIDEventFieldDigitizerChildEventMask = auto()
kIOHIDEventFieldDigitizerIsDisplayIntegrated = auto()
kIOHIDEventFieldDigitizerQualityRadiiAccuracy = auto()
kIOHIDEventFieldDigitizerGenerationCount = auto()
kIOHIDEventFieldDigitizerWillUpdateMask = auto()
kIOHIDEventFieldDigitizerDidUpdateMask = auto()
kIOHIDEventFieldDigitizerEstimatedMask = auto()
102 changes: 101 additions & 1 deletion src/rpcclient/rpcclient/darwin/hid.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
import contextlib
import time
from enum import Enum
from typing import Union

from rpcclient.darwin.consts import kCFAllocatorDefault, kHIDUsage_Csmr_Menu, kHIDUsage_Csmr_Power, \
kHIDUsage_Csmr_VolumeDecrement, kHIDUsage_Csmr_VolumeIncrement, kHIDPage_Consumer, kHIDUsage_Csmr_Mute, \
kHIDUsage_Csmr_ACSearch, kHIDUsage_Csmr_PlayOrPause, kHIDUsage_Csmr_Play, kHIDUsage_Csmr_Pause, \
kHIDUsage_Csmr_Rewind, kHIDUsage_Csmr_RandomPlay, kHIDUsage_Csmr_Repeat, kHIDUsage_Csmr_FastForward
kHIDUsage_Csmr_Rewind, kHIDUsage_Csmr_RandomPlay, kHIDUsage_Csmr_Repeat, kHIDUsage_Csmr_FastForward, \
IOHIDEventField, IOHIDDigitizerEventMask, IOHIDDigitizerTransducerType, IOHIDEventFieldDigitizer
from rpcclient.exceptions import BadReturnValueError


class TouchEventType(Enum):
TOUCH_DOWN = 0
TOUCH_UP = 1
TOUCH_MOVE = 2


EVENT_TYPE_PARAMS = {
TouchEventType.TOUCH_DOWN: {
'event_flags': (IOHIDDigitizerEventMask.kIOHIDDigitizerEventAttribute.value |
IOHIDDigitizerEventMask.kIOHIDDigitizerEventTouch.value |
IOHIDDigitizerEventMask.kIOHIDDigitizerEventIdentity.value),
'button_mask': 1,
'touch': True,
},
TouchEventType.TOUCH_MOVE: {
'event_flags': (IOHIDDigitizerEventMask.kIOHIDDigitizerEventPosition.value |
IOHIDDigitizerEventMask.kIOHIDDigitizerEventAttribute.value),
'button_mask': 1,
'touch': True,
},
TouchEventType.TOUCH_UP: {
'event_flags': (IOHIDDigitizerEventMask.kIOHIDDigitizerEventAttribute.value |
IOHIDDigitizerEventMask.kIOHIDDigitizerEventTouch.value |
IOHIDDigitizerEventMask.kIOHIDDigitizerEventIdentity.value),
'button_mask': 0,
'touch': False,
},
}


class Hid:
""" Control HID devices and simulate events """

Expand Down Expand Up @@ -69,6 +102,73 @@ def send_keyboard_event(self, page: int, key_code: int, down: bool):
page, key_code, down, 0)
self.dispatch(event)

def send_swipe_right(self):
self.send_swipe(0.5, 0.5, 1.0, 0.5)

def send_swipe_left(self):
self.send_swipe(0.5, 0.5, 0.0, 0.5)

def send_swipe_up(self):
self.send_swipe(0.5, 1.5, 0.5, 0.5)

def send_swipe_down(self):
self.send_swipe(0.5, 0.5, 0.5, 1.5)

def send_swipe(self, from_x: float, from_y: float, to_x: float, to_y: float):
self.send_touch_event(TouchEventType.TOUCH_DOWN, from_x, from_y)
self.send_touch_event(TouchEventType.TOUCH_MOVE, to_x, to_y)
self.send_touch_event(TouchEventType.TOUCH_UP, to_x, to_y)

def send_touch_event(self, event_type: TouchEventType, x: float, y: float, pressure: float = 0.4):
params = EVENT_TYPE_PARAMS[event_type]

timestamp = self._client.symbols.mach_absolute_time()

event_flags = params['event_flags']
touch = params['touch']
button_mask = params['button_mask']

parent = self.create_digitizer_event(IOHIDDigitizerTransducerType.kIOHIDDigitizerTransducerTypeHand,
0, 0, event_flags, 0, x, y, 0.0, 0.0, 0.0, touch, touch, 0,
timestamp=timestamp)

child = self.create_digitizer_finger_event(2, 2, event_flags, button_mask, x, y, 0.0, pressure, 0.0,
touch, touch, 0, timestamp=timestamp)

self._client.symbols.IOHIDEventAppendEvent(parent, child)
self.dispatch(parent)

def create_digitizer_event(self, type_: Union[IOHIDDigitizerTransducerType, int], index: int, identity: int,
event_mask: int, button_mask: int, x: float, y: float, z: float, tip_pressure: float,
barrel_pressure: float, range_: bool, touch: bool, options: int, timestamp=None):
if timestamp is None:
timestamp = self._client.symbols.mach_absolute_time()

event = self._client.symbols.IOHIDEventCreateDigitizerEvent(
kCFAllocatorDefault, timestamp, type_, index, identity, event_mask,
button_mask, x, y, z, tip_pressure, barrel_pressure, range_, touch, options)

self._client.symbols.IOHIDEventSetIntegerValue(event, IOHIDEventField.kIOHIDEventFieldIsBuiltIn, 0)
self._client.symbols.IOHIDEventSetIntegerValue(
event, IOHIDEventFieldDigitizer.kIOHIDEventFieldDigitizerIsDisplayIntegrated, 1)
self._client.symbols.IOHIDEventSetSenderID(event, 0x8000000817319375)

return event

def create_digitizer_finger_event(self, index: int, identity: int, event_mask: int,
button_mask: int, x: float, y: float, z: float, tip_pressure: float,
twist: float, range_: bool, touch: bool, options: int, timestamp=None):
if timestamp is None:
timestamp = self._client.symbols.mach_absolute_time()

event = self._client.symbols.IOHIDEventCreateDigitizerFingerEvent(
kCFAllocatorDefault, timestamp, index, identity, event_mask,
button_mask, x, y, z, tip_pressure, twist, range_, touch, options)

self._client.symbols.IOHIDEventSetFloatValue(
event, IOHIDEventFieldDigitizer.kIOHIDEventFieldDigitizerMajorRadius, 0.5)
return event

@contextlib.contextmanager
def create_hid_client(self):
client = self._client.symbols.IOHIDEventSystemClientCreate(0)
Expand Down
Loading

0 comments on commit 1df7fec

Please sign in to comment.