Skip to content

Commit

Permalink
server: add double serialization for call function
Browse files Browse the repository at this point in the history
  • Loading branch information
doronz88 committed Mar 17, 2022
1 parent d73443f commit 1d7a675
Show file tree
Hide file tree
Showing 4 changed files with 299 additions and 38 deletions.
32 changes: 21 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,7 +22,7 @@
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
Expand Down Expand Up @@ -131,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 @@ -156,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
13 changes: 11 additions & 2 deletions src/rpcclient/rpcclient/protocol.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from construct import Struct, Int32ul, PrefixedArray, Const, Enum, this, PascalString, Switch, PaddedString, Bytes, \
Int64ul, Int8ul
Int64ul, Int8ul, IfThenElse, Float64l

cmd_type_t = Enum(Int32ul,
CMD_EXEC=0,
Expand Down Expand Up @@ -41,9 +41,18 @@
'symbol_name' / PaddedString(MAX_PATH_LEN, 'utf8'),
)

argument_type_t = Enum(Int64ul,
Integer=0,
Double=1)

argument_t = Struct(
'type' / argument_type_t,
'value' / IfThenElse(this.type == argument_type_t.Integer, Int64ul, Float64l),
)

cmd_call_t = Struct(
'address' / Int64ul,
'argv' / PrefixedArray(Int64ul, Int64ul),
'argv' / PrefixedArray(Int64ul, argument_t),
)

cmd_peek_t = Struct(
Expand Down
2 changes: 1 addition & 1 deletion src/rpcclient/rpcclient/symbol.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,4 +196,4 @@ def __str__(self):
return hex(self)

def __call__(self, *args, **kwargs):
return self._client.call(self, args)
return self._client.call(self, args, **kwargs)
Loading

0 comments on commit 1d7a675

Please sign in to comment.