diff --git a/gdb-port/gui.py b/gdb-port/gui.py new file mode 100644 index 0000000000000000000000000000000000000000..e680e9c3b436b6434b0a8552d61545140750ad46 --- /dev/null +++ b/gdb-port/gui.py @@ -0,0 +1,55 @@ +from tkinter import * +from tkinter import ttk + +class PresentationLayer(): + def __init__(self, parser, name_var, address_var, input_chunk_var): + self.top_parser = parser + self.top_parser_name = name_var + self.top_parser_address = address_var + self.input_chunk = input_chunk_var + + def set_top_parser(self,parser): + self.top_parser = parser + self.top_parser_name.set(self.top_parser.name) + self.top_parser_address.set(hex(self.top_parser.address)) + + def set_input_chunk(self, input_chunk): + self.input_chunk.set(input_chunk) + +def step(*args): + gdb.execute("hammer-parse-step 1") + presentation_layer.set_top_parser(top_level_parse.peek_parser()) + presentation_layer.set_input_chunk(top_level_parse.get_input_chunk()) + +if top_level_parse is None: + print("Please import parser name script") +else: + root = Tk() + root.title("Parser visualization") + + frame = ttk.Frame(root, padding="12 12 12 12") + frame.grid(column=0, row=0, sticky=(N, W, E, S)) + root.columnconfigure(0, weight=1) + root.rowconfigure(0, weight=1) + + parser = StringVar() + parser_addr = StringVar() + input_chunk = StringVar() + presentation_layer = PresentationLayer(top_level_parse.peek_parser(), parser, parser_addr, input_chunk) + presentation_layer.set_top_parser(top_level_parse.peek_parser()) + presentation_layer.set_input_chunk(top_level_parse.get_input_chunk()) + #presentation_layer.top_parser_name = parser + #presentation_layer.top_parser_addr = parser_addr + #presentation_layer.top_parser = top_level_parse.peek_parser() + #presentation_layer.set_top_parser(top_level_parse.peek_parser()) + + #presentation_layer.top_parser = top_level_parse.peek_parser() + ttk.Label(frame, textvariable=presentation_layer.top_parser_name).grid(column=1, row=1) + #ttk.Label(frame, text="Placeholder name").grid(column=1, row=1) + ttk.Label(frame, textvariable=presentation_layer.top_parser_address).grid(column=1, row=2) + #ttk.Label(frame, text="Placeholder address").grid(column=1, row=2) + ttk.Label(frame, textvariable=presentation_layer.input_chunk).grid(column=2, row=1) + ttk.Button(frame, text="Step", command=step).grid(column=1, row=3) + + root.mainloop() + diff --git a/gdb-port/parser-name-instrumentation-gdb.py b/gdb-port/parser-name-instrumentation-gdb.py index 782b4da5ccd414377c36b43fa8b0a5c01fa3373b..999a6da6a96366b90cbf785f29eb163572245349 100644 --- a/gdb-port/parser-name-instrumentation-gdb.py +++ b/gdb-port/parser-name-instrumentation-gdb.py @@ -112,6 +112,8 @@ class TopLevelParse: self.parser_stacks = [] self.parser_objs = {} self.unclaimed_mem_use = 0 + # Holds 32 characters starting at state->input_stream[index], used by the GUI + self.current_input_chunk = '' # Called from h_packrat_parse()'s handler, where the parse state and arena get initialized def enter_h_packrat_parse(self, parser): @@ -207,6 +209,12 @@ class TopLevelParse: else: return None + def set_input_chunk(self, chunk): + self.input_chunk = chunk + + def get_input_chunk(self): + return self.input_chunk + top_level_parse = TopLevelParse() # Approach 1: load the application, set breakpoints, execute stack commands on breakpoint hit, continue @@ -239,13 +247,19 @@ class HDoParseBreakpoint(gdb.Breakpoint): if val.name == 'state': #TODO: rename these variables to make it clear they're pointers state = int(val.value(frame)) + state_obj = val.value(frame) index = val.value(frame).dereference()['input_stream']['index'] + input_ptr = val.value(frame).dereference()['input_stream']['input'] # If you want to printf debug the parse state #print(val.value(frame).dereference()) if val.name == 'arena': arena = int(val.value(frame)) top_level_parse.enter_h_do_parse(state, None, parser) + input_chunk = input_ptr + index + top_level_parse.set_input_chunk(input_chunk.string('UTF-8','replace',32)) + #print(input_chunk.string('ascii','backslashreplace',10)) + # Check if we need to stop after a number of steps step_counter = gdb.convenience_variable("hammer_step_counter")