Skip to content

Commit 9bf2e61

Browse files
committed
Improved test for NDR + added timeout for debugger test (if pytest-timeout present)
1 parent 01a59a9 commit 9bf2e61

4 files changed

Lines changed: 139 additions & 83 deletions

File tree

samples/event_log/wevtutil.py

Lines changed: 74 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import pickle
88
import logging
99
import binascii
10+
import traceback
1011

1112
from io import BytesIO
1213
from collections import namedtuple
@@ -73,21 +74,21 @@ def setup_trace(self):
7374
self.any_keywords |= keyword
7475

7576
logging.debug("events KeywordsAny : 0x%x" % self.any_keywords)
76-
77+
7778

7879
# Create a custom realtime ETW trace for printing out events
7980
self.etw_trace = windows.system.etw.open_trace(self.etw_trace_name)
8081

8182

8283
def start_trace(self):
83-
84+
self.etw_trace.stop(soft=True)
8485
self.etw_trace.start()
8586

8687
# We can't configure etw trace if it's not started previously
8788
self.etw_trace.enable_ex(
88-
self.publisher_guid.to_string(),
89-
flags=0,
90-
level=0xff,
89+
self.publisher_guid.to_string(),
90+
flags=0,
91+
level=0xff,
9192
any_keyword=self.any_keywords
9293
)
9394

@@ -113,7 +114,7 @@ def process_event(self, event):
113114

114115
# Deserialize event.user_data based on the event_metadata xml template
115116
message_data = event.user_data
116-
message_params = self.parse_user_data(event_metadata.template, message_data)
117+
message_params = self.parse_user_data(event_metadata, message_data)
117118
logging.debug("message params : %s" % message_params)
118119

119120

@@ -125,13 +126,27 @@ def process_event(self, event):
125126
raise
126127
return
127128

129+
# import pdb;pdb.set_trace()
130+
xx = tuple(event_log.ImprovedEVT_VARIANT.from_value(x.value) for x in message_params)
131+
# xx = tuple(event_log.ImprovedEVT_VARIANT.from_value(x.value) for x in message_params)
132+
res = ctypes.c_buffer(0x1000)
133+
res_size = gdef.DWORD()
134+
yolo_ptr = (gdef.EVT_VARIANT * len(xx))(*xx)
135+
# import pdb;pdb.set_trace()
136+
windows.winproxy.EvtFormatMessage(self.publisher.metadata, None, event_metadata.message_id, len(message_params), yolo_ptr, gdef.EvtFormatMessageId, 0x1000, ctypes.cast(res, gdef.LPCWSTR), res_size)
137+
str = res[:res_size.value * 2].decode("utf-16-le")
138+
print("=== MINE ===")
139+
print(str)
140+
141+
print("=== REAL ===")
128142
# "sprintf" the message using the event format message as well as the deserialized elements
129143
event_message = self.format_event_log_message(template_message, message_params)
130-
131144
print(event_message)
145+
import pdb;pdb.set_trace()
132146

133147
except Exception as unke:
134148
print("Unhandled exception in Evtlogger.process_event : %s" % unke)
149+
traceback.print_tb(sys.exc_info()[2])
135150
sys.exit(0) # Exiting on unknown error, since this is the only way to have some control
136151
finally:
137152
pass
@@ -181,10 +196,10 @@ def parse_element(self, in_type, stream, length = None):
181196
elif in_type == "win:Binary":
182197
if not length:
183198
raise ValueError(" param_in_type (%s) cannot be used with a null length value" % in_type)
184-
185-
# TODO : we should return the raw bytes buffer, since get_param_str_format is too crude
199+
200+
# TODO : we should return the raw bytes buffer, since get_param_str_format is too crude
186201
# to properly display win:SocketAddress parameters
187-
value = binascii.hexlify(stream.read(length))
202+
value = binascii.hexlify(stream.read(length))
188203

189204
elif in_type == "win:GUID":
190205
guid_data = struct.unpack("IHHBBBBBBBB", stream.read(16))
@@ -214,66 +229,51 @@ def get_param_str_format(self, param_out_type):
214229

215230
return PYTHON_FORMAT_DICT[param_out_type]
216231

217-
def parse_user_data(self, template, data):
218-
"""
232+
def parse_user_data(self, event_metadata, data):
233+
"""
219234
Deserialize event.user_data based on the associated publisher's template.
220235
Return a list of ParsedElement(Name:string, Value:py_object, Type:py_type).
221236
"""
222-
223-
# xml.dom.minidom.parseString raise an error on parseString() if the xml template is empty
224-
if not len(template):
225-
return []
226-
227237
stream = BytesIO(data)
228-
xmltemplate = xml.dom.minidom.parseString(template)
229-
238+
event_items = event_metadata.event_data
230239
params = []
231-
context = {} # saving parsed items for "count" elements
232-
233-
# xmltemplate.getElementsByTagName("data") return data node within <struct> decl, so we can't use it
234-
direct_data_nodes = filter(lambda n: n.nodeType == 1 and n.tagName == "data", xmltemplate.childNodes[0].childNodes)
235-
236-
for (i,param_data) in enumerate(direct_data_nodes):
237-
238-
param_name = param_data.attributes["name"].value
239-
param_in_type = param_data.attributes["inType"].value
240-
param_out_type = param_data.attributes["outType"].value
240+
if not event_items:
241+
return []
241242

243+
context = {} # saving parsed items for "count" elements
244+
for (i, param_data) in enumerate(event_items):
242245
# Some param are repeating, and "count" refers to the variable holding the number of repetitions
243-
param_count = param_data.attributes.get("count", None)
244-
if param_count != None:
245-
param_count = context[param_count.value] # must be already set
246+
param_in_type = param_data["inType"]
247+
param_out_type = param_data["outType"]
248+
param_name = param_data["name"]
249+
param_count = param_data.get("count", None)
250+
if param_count:
251+
param_count = context[param_count] # must be already set
252+
if param_count == 0:
253+
continue
246254

247255
# Some param (win:Binary) have a length attribute
248-
param_length = param_data.attributes.get("length", None)
249-
if param_length != None:
250-
param_length = context[param_length.value] # must be already set
251-
256+
param_length = param_data.get("length", None)
257+
if param_length:
258+
param_length = context[param_length] # must be already set
252259

253260
# Parse element
254-
if param_count != None:
255-
256-
# ignoring element with value count of 0
257-
if param_count == 0:
258-
continue
259-
260-
value = [ self.parse_element(param_in_type, stream, param_length) for c in range(param_count) ]
261+
if param_count:
262+
value = [self.parse_element(param_in_type, stream, param_length) for c in range(param_count)]
261263
else:
262264
value = self.parse_element(param_in_type, stream, param_length)
263265

264-
# Get python string formating
265-
format_type = self.get_param_str_format(param_out_type)
266-
267266
context[param_name] = value
267+
format_type = self.get_param_str_format(param_out_type)
268268

269-
logging.debug(ParsedElement(i, param_name,value, format_type))
270-
params.append(ParsedElement(i, param_name,value, format_type))
269+
logging.debug(ParsedElement(i, param_name, value, format_type))
270+
params.append(ParsedElement(i, param_name, value, format_type)) # Yield ?
271271

272272
return params
273273

274274
def lookup_event_metadata(self, publisher, event_id):
275275
matching_events_metadata = list(filter(lambda event_meta: event_meta.id == event_id, publisher.metadata.events_metadata))
276-
276+
277277
if not len(matching_events_metadata):
278278
return None
279279

@@ -283,28 +283,28 @@ def lookup_event_metadata(self, publisher, event_id):
283283
return matching_events_metadata[0]
284284

285285
def format_event_log_message(self, template, event_args):
286-
286+
287287
py_template = ""
288288
last_span = (0,0)
289-
289+
290290
# Convert message template to python string formating
291291
# e.g. : "ParseError: HResult: %1, Error: %2." into "ParseError: HResult: {arg0:x}, Error: {arg1:d}."
292292
pattern = re.compile(r"%(\d)")
293293
for match in re.finditer(pattern, template):
294-
294+
295295
arg_id = int(match.groups()[0]) - 1 # event's template message index params from 1 to N, wtf
296296
span = match.span()
297297
str_format = ""
298-
298+
299299
str_format = "{a%d:%s}" % (arg_id, event_args[arg_id].format)
300-
300+
301301
py_template += template[last_span[1]:span[0]] + str_format
302302
last_span = span
303-
303+
304304
py_template += template[last_span[1]:]
305-
305+
306306
logging.debug(py_template)
307-
307+
308308
# string formating using Python .format()
309309
events_kwargs = {"a%d" % (x.index) : x.value for x in event_args}
310310
logging.debug(events_kwargs)
@@ -335,7 +335,7 @@ def format_channel_metadata(publisher_metadata, channel_metadata, args):
335335
" flags: {channel.flags:d}",
336336
" message: {channel_message:s}",
337337
]).format(
338-
channel=channel_metadata,
338+
channel=channel_metadata,
339339
channel_message=get_message(publisher_metadata, channel_metadata.message_id, args.gm)
340340
)
341341

@@ -345,9 +345,9 @@ def format_level_metadata(publisher_metadata, level_metadata, args):
345345
" level:",
346346
" name: {level.name:s}",
347347
" value: {level.value:d}",
348-
" message: {level_message:s}",
348+
" message: {level_message:s}",
349349
]).format(
350-
level=level_metadata,
350+
level=level_metadata,
351351
level_message=get_message(publisher_metadata, level_metadata.message_id, args.gm)
352352
)
353353

@@ -359,9 +359,9 @@ def format_opcode_metadata(publisher_metadata, opcode_metadata, args):
359359
" value: {opcode.value:d}",
360360
#" task: {opcode.task:d}", # TODO
361361
#" opcode: {opcode.task_value:d}", # TODO
362-
" message: {opcode_message:s}",
362+
" message: {opcode_message:s}",
363363
]).format(
364-
opcode=opcode_metadata,
364+
opcode=opcode_metadata,
365365
opcode_message=get_message(publisher_metadata, opcode_metadata.message_id, args.gm)
366366
)
367367

@@ -371,10 +371,10 @@ def format_task_metadata(publisher_metadata, task_metadata, args):
371371
" task:",
372372
" name: {task.name:s}",
373373
" value: {task.value:d}",
374-
" eventGUID: {task.event_guid:s}",
375-
" message: {task_message:s}",
374+
" eventGUID: {task.event_guid:s}",
375+
" message: {task_message:s}",
376376
]).format(
377-
task=task_metadata,
377+
task=task_metadata,
378378
task_message=get_message(publisher_metadata, task_metadata.message_id, args.gm)
379379
)
380380

@@ -384,9 +384,9 @@ def format_keyword_metadata(publisher_metadata, keyword_metadata, args):
384384
" keyword:",
385385
" name: {keyword.name:s}",
386386
" mask: {keyword.value:x}",
387-
" message: {keyword_message:s}",
387+
" message: {keyword_message:s}",
388388
]).format(
389-
keyword=keyword_metadata,
389+
keyword=keyword_metadata,
390390
keyword_message=get_message(publisher_metadata, keyword_metadata.message_id, args.gm)
391391
)
392392

@@ -401,21 +401,21 @@ def format_event_metadata(publisher_metadata, event_metadata, args):
401401
" level: {event.level:d}",
402402
" task: {event.task:d}",
403403
" keywords: 0x{event.keyword:016x}",
404-
" message: {event_message:s}"
404+
" message: {event_message:s}"
405405
]).format(
406-
event=event_metadata,
406+
event=event_metadata,
407407
event_message=get_message(publisher_metadata, event_metadata.message_id, args.gm)
408408
)
409409

410410
def enum_publishers(args):
411411
""" enum-publishers verb implementation """
412412
manager = event_log.EvtlogManager()
413-
for publisher in sorted(list(manager.publishers), key=lambda pub:pub.name.lower()):
414-
print(publisher.name)
413+
for publisher in sorted(list(manager.publishers), key=lambda pub:pub.name.lower()):
414+
print(publisher.name)
415415

416416
def get_publisher(args):
417417
""" get-publisher verb implementation """
418-
418+
419419
manager = event_log.EvtlogManager()
420420
publisher = manager.open_publisher(args.publisher_name)
421421

@@ -492,7 +492,7 @@ def get_publisher(args):
492492

493493
publisher_infos += "\n"
494494
print(publisher_infos)
495-
495+
496496

497497
def main(args):
498498

@@ -519,7 +519,7 @@ def main(args):
519519

520520
# we can't express shorthands easily like ep for enum-publishers since only Python3's argparse surpport parser "aliases"
521521
enum_publishers_parser = action_parsers.add_parser("enum-publishers", help="enum-publishers verb")
522-
522+
523523
get_publisher_parser = action_parsers.add_parser("get-publisher", help="get-publisher verb")
524524
get_publisher_parser.add_argument("publisher_name", type=str, help="registered publisher name")
525525
get_publisher_parser.add_argument("--ge", action="store_true", help="get event metadata")

samples/service/service_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
print(" * {0}".format(service))
77
print("")
88

9-
TARGET_SERVICE = "TapiSrv"
9+
TARGET_SERVICE = b"TapiSrv"
1010
print("Retriving service <{0}>".format(TARGET_SERVICE))
1111
service = windows.system.services[TARGET_SERVICE]
1212
print("{0}".format(service))

0 commit comments

Comments
 (0)