77import pickle
88import logging
99import binascii
10+ import traceback
1011
1112from io import BytesIO
1213from 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
410410def 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
416416def 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
497497def 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" )
0 commit comments