fix dbgprint to use hardcoded dict + improve rpc client forge_call + new ndr varying string

This commit is contained in:
Clement Rouault
2017-10-03 17:30:38 +02:00
parent bd5976dce2
commit a183e468ca
9 changed files with 62 additions and 9 deletions
+2 -5
View File
@@ -1,9 +1,7 @@
TODO:
- Documentation
- thread.set_context in a sample
- Better WMI interface
- Bug in VARIANT_TYPE == BOOL (see Win32_OperatingSystem->Debug)
- DBG
- Verif multiple bp at same place..
@@ -11,7 +9,6 @@ TODO:
- Test !! (bp, BP_HX, bp on only on process, bp_hx on only one thread..)
- test breakpoint with specific target
- Rethink/adapt Debugger._explicit_single_step
- Does not handle case where EEFlags.TF was by the debugge before trigering the exception
- Should set the flag explicitly in single_step ? and not just use EEFlags.TF ?
@@ -24,11 +21,11 @@ TODO:
- j'attends a avoir un thread/process mais je fait des check sur TID/PID..
- Ecrire un test et fix..
- windows.alpc | windows.rpc
- Clean + doc + samples
- remotectypes
- pretty sur I can get rid of PointerToStruct64/PointerToStruct32
+4
View File
@@ -924,6 +924,10 @@
#define ALPC_MSGFLG_WAIT_ALERTABLE 0x200000
#define ALPC_MSGFLG_WOW64_CALL 0x80000000
#define ALPC_PORFLG_ALLOW_LPC_REQUESTS 0x20000
#define ALPC_PORFLG_WAITABLE_PORT 0x40000
#define ALPC_PORFLG_SYSTEM_PROCESS 0x100000
#define ALPC_CANCELFLG_TRY_CANCEL 0x1
#define ALPC_CANCELFLG_NO_CONTEXT_CHECK 0x8
#define ALPC_CANCELFLGP_FLUSH 0x10000
+3
View File
@@ -796,6 +796,9 @@ Windef
.. autodata:: ALPC_MSGFLG_WAIT_USER_MODE
.. autodata:: ALPC_MSGFLG_WAIT_ALERTABLE
.. autodata:: ALPC_MSGFLG_WOW64_CALL
.. autodata:: ALPC_PORFLG_ALLOW_LPC_REQUESTS
.. autodata:: ALPC_PORFLG_WAITABLE_PORT
.. autodata:: ALPC_PORFLG_SYSTEM_PROCESS
.. autodata:: ALPC_CANCELFLG_TRY_CANCEL
.. autodata:: ALPC_CANCELFLG_NO_CONTEXT_CHECK
.. autodata:: ALPC_CANCELFLGP_FLUSH
+1
View File
@@ -21,5 +21,6 @@ setup(
'windows.winobject',
'windows.debug',
'windows.crypto',
'windows.rpc',
'windows.test'],
)
+3 -1
View File
@@ -1,3 +1,4 @@
import sys
import pytest
import os.path
@@ -58,7 +59,7 @@ def test_rpc_uac_call():
client = windows.rpc.find_alpc_endpoint_and_connect(UAC_UIID)
iid = client.bind(UAC_UIID)
python_path = 'C:\\Python27\\python.exe'
python_path = sys.executable
python_name = os.path.basename(python_path)
# Marshalling parameters.
@@ -98,5 +99,6 @@ def test_rpc_uac_call():
windows.winproxy.CloseHandle(th) # NoLeak
proc = windows.WinProcess(handle=ph)
assert proc.name == python_name
assert proc.pid == pid
proc.exit(0)
+5
View File
@@ -4,6 +4,7 @@ import logging
import inspect
options = {'active': False, 'cats': None}
# options = {'active': True, 'cats': ["HANDLE"]}
def get_stack_func_name(lvl):
@@ -40,6 +41,10 @@ try:
dbgprint = do_dbgprint
option_str = [opt for opt in sys.argv if opt.startswith("--DBGPRINT")][0]
parse_option(option_str[len('--DBGPRINT'):])
elif options["active"]:
formt = 'DBG|%(name)s|%(message)s'
logging.basicConfig(format=formt, level=logging.DEBUG)
dbgprint = do_dbgprint
else:
dbgprint = do_nothing
except Exception as e:
+3
View File
@@ -847,6 +847,9 @@ ALPC_MSGFLG_SYNC_REQUEST = make_flag("ALPC_MSGFLG_SYNC_REQUEST", 0x20000)
ALPC_MSGFLG_WAIT_USER_MODE = make_flag("ALPC_MSGFLG_WAIT_USER_MODE", 0x100000)
ALPC_MSGFLG_WAIT_ALERTABLE = make_flag("ALPC_MSGFLG_WAIT_ALERTABLE", 0x200000)
ALPC_MSGFLG_WOW64_CALL = make_flag("ALPC_MSGFLG_WOW64_CALL", 0x80000000)
ALPC_PORFLG_ALLOW_LPC_REQUESTS = make_flag("ALPC_PORFLG_ALLOW_LPC_REQUESTS", 0x20000)
ALPC_PORFLG_WAITABLE_PORT = make_flag("ALPC_PORFLG_WAITABLE_PORT", 0x40000)
ALPC_PORFLG_SYSTEM_PROCESS = make_flag("ALPC_PORFLG_SYSTEM_PROCESS", 0x100000)
ALPC_CANCELFLG_TRY_CANCEL = make_flag("ALPC_CANCELFLG_TRY_CANCEL", 0x1)
ALPC_CANCELFLG_NO_CONTEXT_CHECK = make_flag("ALPC_CANCELFLG_NO_CONTEXT_CHECK", 0x8)
ALPC_CANCELFLGP_FLUSH = make_flag("ALPC_CANCELFLGP_FLUSH", 0x10000)
+31 -3
View File
@@ -44,6 +44,26 @@ class ALPC_RPC_BIND(ctypes.Structure):
("UNK9", gdef.DWORD),
]
class ALPC_RPC_CALL(ctypes.Structure):
_pack_ = 1
_fields_ = [
("request_type", gdef.DWORD),
("UNK1", gdef.DWORD),
("flags",gdef.DWORD),
("request_id", gdef.DWORD),
("if_nb", gdef.DWORD),
("method_offset", gdef.DWORD),
("UNK2", gdef.DWORD),
("UNK3", gdef.DWORD),
("UNK4", gdef.DWORD),
("UNK5", gdef.DWORD),
("UNK6", gdef.DWORD),
("UNK7", gdef.DWORD),
("UNK8", gdef.DWORD),
("UNK9", gdef.DWORD),
("UNK10", gdef.DWORD),
("UNK11", gdef.DWORD),
]
class RPCClient(object):
"""A client for RPC-over-ALPC able to bind to interface and perform calls using NDR32 marshalling"""
@@ -99,9 +119,15 @@ class RPCClient(object):
def _forge_call_request(self, interface_nb, method_offset, params):
# TODO: differents REQUEST_IDENTIFIER for each req ?
# TODO: what is this '0' ? (1 is also accepted) (flags ?)
request = struct.pack("<16I", gdef.RPC_REQUEST_TYPE_CALL, NOT_USED, 1, self.REQUEST_IDENTIFIER, interface_nb, method_offset, *[NOT_USED] * 10)
request += params
return request
# request = struct.pack("<16I", gdef.RPC_REQUEST_TYPE_CALL, NOT_USED, 1, self.REQUEST_IDENTIFIER, interface_nb, method_offset, *[NOT_USED] * 10)
req = ALPC_RPC_CALL()
req.request_type = gdef.RPC_REQUEST_TYPE_CALL
req.flags = 0
req.request_id = self.REQUEST_IDENTIFIER
req.if_nb = interface_nb
req.method_offset = method_offset
return buffer(req)[:] + params
def _forge_bind_request(self, uuid, syntaxversion, requested_if_nb):
version_major, version_minor = syntaxversion
@@ -109,8 +135,10 @@ class RPCClient(object):
req.request_type = gdef.RPC_REQUEST_TYPE_BIND
req.target = gdef.RPC_IF_ID(uuid, *syntaxversion)
req.flags = gdef.BIND_IF_SYNTAX_NDR32
# req.flags = gdef.BIND_IF_SYNTAX_NDR64
req.if_nb_ndr32 = requested_if_nb
req.if_nb_ndr64 = 0
req.if_nb_ndr64 = requested_if_nb
req.if_nb_unkn = 0
req.register_multiple_syntax = False
req.some_context_id = 0xB00B00B
+10
View File
@@ -97,6 +97,16 @@ class NdrSID(object):
subcount = NdrLong.unpack(stream)
return stream.read(8 + (subcount * 4))
class NdrVaryingCString(object):
@classmethod
def pack(cls, data):
if data is None:
return None
l = len(data)
result = struct.pack("<2I", 0, l)
result += data
return dword_pad(result)
class NdrWString(object):
@classmethod
def pack(cls, data):