From 16a07a7b7a5fe7acf172c8f5eedd5d9898645e22 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Wed, 1 Jun 2016 04:51:14 -0400 Subject: stylized svg and start of tooltips --- python/examples/export-svg.py | 108 ++++++++++++++++++++++++++++++------------ 1 file changed, 78 insertions(+), 30 deletions(-) (limited to 'python/examples') diff --git a/python/examples/export-svg.py b/python/examples/export-svg.py index e00b651f..ad3a3dd7 100755 --- a/python/examples/export-svg.py +++ b/python/examples/export-svg.py @@ -1,16 +1,34 @@ from binaryninja import * -import os +import os,sys + +escape_table = { + "&": "&", + "'": "'", + ">": ">", + "<": "<", + '"': """, + ' ': " ", +} + +def escape(string): + return ''.join(escape_table.get(i,i) for i in string) def save_svg(bv,function): filename = bv.file.filename.split(os.sep)[-1] - outputfile = os.environ['HOME'] + os.sep + 'binaryninja-{filename}-{function}.svg'.format(filename=filename,function=function.symbol.name) - try: - output = open(outputfile,'w') - output.write(render_svg(function)) - output.close() - except: - print "Unexpected error:", sys.exc_info()[0] - raise + outputfile = os.path.join(os.path.expanduser('~'), 'binaryninja-{filename}-{function}.html'.format(filename=filename,function=function.symbol.name)) + content = render_svg(function) + output = open(outputfile,'w') + output.write(content) + output.close() + #os.system('open %s' % outputfile) + +def instruction_data_flow(function,address): + ''' TODO: Extract data flow information ''' + length = function.view.get_instruction_length(function.arch,address) + bytes = function.view.read(address, length) + hex = bytes.encode('hex') + padded = ' '.join([hex[i:i+2] for i in range(0, len(hex), 2)]) + return 'Opcode: {bytes}'.format(bytes=padded) def render_svg(function): graph = function.create_graph() @@ -19,44 +37,71 @@ def render_svg(function): ratio = 0.54 widthconst = int(heightconst*ratio) - output = ''' - - + output = ''' - + - + - + @@ -74,9 +119,9 @@ def render_svg(function): height = int((block.height) * heightconst) #Render block - output += ' \n' - output += ' Basic Block {i}\n' - output += ' \n'.format(i=i,x=x,y=y,width=width,height=height) + output += ' \n'.format(i=i) + output += ' Basic Block {i}\n'.format(i=i) + output += ' \n'.format(x=x,y=y,width=width,height=height) #Render instructions, unfortunately tspans don't allow copying/pasting more #than one line at a time, need SVG 1.2 textarea tags for that it looks like @@ -84,9 +129,12 @@ def render_svg(function): output += ' \n'.format(x=x,y=y + (i + 1) * heightconst) for i,line in enumerate(block.lines): output += ' '.format(x=x,y=y + (i + 0.7) * heightconst,address=hex(line.address)[:-1]) + hover = instruction_data_flow(function, line.address) + output += '{hover}'.format(hover=hover) for token in line.tokens: - output+='{text}'.format(text=token.text,tokentype=token.type) - output += ' \n' + # TODO: add hover for hex, function, and reg tokens + output+='{text}'.format(text=escape(token.text),tokentype=token.type) + output += '\n' output += ' \n' output += ' \n' @@ -100,7 +148,7 @@ def render_svg(function): edges += ' \n'.format(type=edge.type,points=points) output += ' ' + edges + '\n' output += ' \n' - output += '' + output += '' return output -PluginCommand.register_for_function("Export to SVG", "Exports an SVG to your home folder for the given function", save_svg) +PluginCommand.register_for_function("Export to SVG", "Exports an SVG of the current function to your home folder.", save_svg) -- cgit v1.3.1 From d77bcec46af3b1e08ec1bf26899bef8dae46a528 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Wed, 1 Jun 2016 05:09:05 -0400 Subject: missed a few colors --- python/examples/export-svg.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'python/examples') diff --git a/python/examples/export-svg.py b/python/examples/export-svg.py index ad3a3dd7..5826a546 100755 --- a/python/examples/export-svg.py +++ b/python/examples/export-svg.py @@ -76,24 +76,27 @@ def render_svg(function): .CodeSymbolToken {{ fill: rgb(128, 198, 223); }} - .TextToken {{ + .DataSymbolToken {{ + fill: rgb(142, 230, 237); + }} + .TextToken, .InstructionToken, .BeginMemoryOperandToken, .EndMemoryOperandToken {{ fill: rgb(224, 224, 224); }} - .PossibleAddressToken {{ + .PossibleAddressToken, .IntegerToken {{ fill: rgb(162, 217, 175); }} .RegisterToken {{ fill: rgb(237, 223, 179); }} - .InstructionToken {{ - fill: rgb(224, 224, 224); - }} .AnnotationToken {{ fill: rgb(218, 196, 209); }} .ImportToken {{ fill: rgb(237, 189, 129); }} + .StackVariableToken {{ + fill: rgb(193, 220, 199); + }} ]]> -- cgit v1.3.1 From e397c1c03ddca833bf39cf0bbdb6ce859bb16c7a Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Thu, 2 Jun 2016 00:09:18 -0400 Subject: properly escape higher unicode, use address instead of function in filename, add indirect branch style, split style --- python/examples/export-svg.py | 145 ++++++++++++++++++++++-------------------- 1 file changed, 77 insertions(+), 68 deletions(-) (limited to 'python/examples') diff --git a/python/examples/export-svg.py b/python/examples/export-svg.py index 5826a546..c169337c 100755 --- a/python/examples/export-svg.py +++ b/python/examples/export-svg.py @@ -2,20 +2,21 @@ from binaryninja import * import os,sys escape_table = { - "&": "&", "'": "'", ">": ">", "<": "<", '"': """, - ' ': " ", + ' ': " " } def escape(string): - return ''.join(escape_table.get(i,i) for i in string) + string=string.decode('utf-8').encode('ascii','xmlcharrefreplace') #handle extended unicode + return ''.join(escape_table.get(i,i) for i in string) #still escape the basics def save_svg(bv,function): filename = bv.file.filename.split(os.sep)[-1] - outputfile = os.path.join(os.path.expanduser('~'), 'binaryninja-{filename}-{function}.html'.format(filename=filename,function=function.symbol.name)) + address = hex(function.start).replace('L','') + outputfile = os.path.join(os.path.expanduser('~'), 'binaryninja-{filename}-{function}.html'.format(filename=filename,function=address)) content = render_svg(function) output = open(outputfile,'w') output.write(content) @@ -37,74 +38,82 @@ def render_svg(function): ratio = 0.54 widthconst = int(heightconst*ratio) - output = ''' + output = ''' + + + + +''' + output += ''' - - + - + - + + + + @@ -131,7 +140,7 @@ def render_svg(function): output += ' \n'.format(x=x,y=y + (i + 1) * heightconst) for i,line in enumerate(block.lines): - output += ' '.format(x=x,y=y + (i + 0.7) * heightconst,address=hex(line.address)[:-1]) + output += ' '.format(x=x,y=y + (i + 0.7) * heightconst,address=hex(line.address)[:-1]) hover = instruction_data_flow(function, line.address) output += '{hover}'.format(hover=hover) for token in line.tokens: -- cgit v1.3.1 From 5236ac0f8855e37f905e953254266c95b11d5617 Mon Sep 17 00:00:00 2001 From: plafosse Date: Thu, 2 Jun 2016 17:18:22 -0400 Subject: SVG export fixes for border --- python/examples/export-svg.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'python/examples') diff --git a/python/examples/export-svg.py b/python/examples/export-svg.py index c169337c..1e5e3ca0 100755 --- a/python/examples/export-svg.py +++ b/python/examples/export-svg.py @@ -34,9 +34,9 @@ def instruction_data_flow(function,address): def render_svg(function): graph = function.create_graph() graph.layout_and_wait() - heightconst = 15 - ratio = 0.54 - widthconst = int(heightconst*ratio) + heightconst = 17 + ratio = 0.44 + widthconst = heightconst*ratio output = ''' @@ -117,7 +117,7 @@ def render_svg(function): - '''.format(width=graph.width*widthconst, height=graph.height*heightconst) + '''.format(width=int(graph.width * widthconst + 0.5), height=graph.height * heightconst) output += ''' Function Graph 0 ''' @@ -125,10 +125,10 @@ def render_svg(function): for i,block in enumerate(graph.blocks): #Calculate basic block location and coordinates - x = int((block.x) * widthconst) + x = int(block.x * widthconst + 0.5) y = int((block.y) * heightconst) - width = int((block.width) * widthconst) - height = int((block.height) * heightconst) + width = int(block.width * widthconst + 0.5) + height = block.height * heightconst #Render block output += ' \n'.format(i=i) @@ -138,9 +138,9 @@ def render_svg(function): #Render instructions, unfortunately tspans don't allow copying/pasting more #than one line at a time, need SVG 1.2 textarea tags for that it looks like - output += ' \n'.format(x=x,y=y + (i + 1) * heightconst) + output += ' \n'.format(x=x+3,y=y+5 + (i + 1) * (heightconst - 2)) for i,line in enumerate(block.lines): - output += ' '.format(x=x,y=y + (i + 0.7) * heightconst,address=hex(line.address)[:-1]) + output += ' '.format(x=x+3,y=y + 5 + (i + 0.7) * (heightconst - 2),address=hex(line.address)[:-1]) hover = instruction_data_flow(function, line.address) output += '{hover}'.format(hover=hover) for token in line.tokens: -- cgit v1.3.1 From 01d331415a6db0728c0045d2f77649f73e20d097 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Thu, 2 Jun 2016 19:31:43 -0400 Subject: fix padding bugs, no padding anywhere now but at least its consistent --- python/examples/export-svg.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'python/examples') diff --git a/python/examples/export-svg.py b/python/examples/export-svg.py index 1e5e3ca0..3800edf7 100755 --- a/python/examples/export-svg.py +++ b/python/examples/export-svg.py @@ -34,8 +34,8 @@ def instruction_data_flow(function,address): def render_svg(function): graph = function.create_graph() graph.layout_and_wait() - heightconst = 17 - ratio = 0.44 + heightconst = 15 + ratio = 0.48 widthconst = heightconst*ratio output = ''' @@ -117,7 +117,7 @@ def render_svg(function): - '''.format(width=int(graph.width * widthconst + 0.5), height=graph.height * heightconst) + '''.format(width=graph.width*widthconst, height=graph.height*heightconst) output += ''' Function Graph 0 ''' @@ -125,10 +125,10 @@ def render_svg(function): for i,block in enumerate(graph.blocks): #Calculate basic block location and coordinates - x = int(block.x * widthconst + 0.5) - y = int((block.y) * heightconst) - width = int(block.width * widthconst + 0.5) - height = block.height * heightconst + x = ((block.x) * widthconst) + y = ((block.y) * heightconst) + width = ((block.width) * widthconst) + height = ((block.height) * heightconst) #Render block output += ' \n'.format(i=i) @@ -138,9 +138,9 @@ def render_svg(function): #Render instructions, unfortunately tspans don't allow copying/pasting more #than one line at a time, need SVG 1.2 textarea tags for that it looks like - output += ' \n'.format(x=x+3,y=y+5 + (i + 1) * (heightconst - 2)) + output += ' \n'.format(x=x,y=y + (i + 1) * heightconst) for i,line in enumerate(block.lines): - output += ' '.format(x=x+3,y=y + 5 + (i + 0.7) * (heightconst - 2),address=hex(line.address)[:-1]) + output += ' '.format(x=x,y=y + (i + 0.7) * heightconst,address=hex(line.address)[:-1]) hover = instruction_data_flow(function, line.address) output += '{hover}'.format(hover=hover) for token in line.tokens: -- cgit v1.3.1 From 32153536526753edc3e80ea43512ad7ab65a3271 Mon Sep 17 00:00:00 2001 From: Jordan Wiens Date: Thu, 30 Jun 2016 13:51:07 -0400 Subject: remove sleep from sample plugins --- python/examples/arm-syscall.py | 5 +---- python/examples/bin-info.py | 5 +---- python/examples/instruction-iterator.py | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) (limited to 'python/examples') diff --git a/python/examples/arm-syscall.py b/python/examples/arm-syscall.py index cbd8f4bf..f94b8531 100644 --- a/python/examples/arm-syscall.py +++ b/python/examples/arm-syscall.py @@ -10,10 +10,7 @@ else: raise ValueError("Missing argument to binary.") bv = binaryninja.BinaryViewType["Mach-O"].open(target) -bv.update_analysis() - -"""Until update_analysis_and_wait is complete, sleep is necessary as the analysis is multi-threaded.""" -time.sleep(5) +bv.update_analysis_and_wait() for func in bv.functions: for il in func.low_level_il: diff --git a/python/examples/bin-info.py b/python/examples/bin-info.py index 6ec00bce..48073894 100644 --- a/python/examples/bin-info.py +++ b/python/examples/bin-info.py @@ -13,10 +13,7 @@ else: target = "/bin/ls" bv = binaryninja.BinaryViewType[bintype].open(target) -bv.update_analysis() - -"""Until update_analysis_and_wait is complete, sleep is necessary as the analysis is multi-threaded.""" -time.sleep(1) +bv.update_analysis_and_wait() print "-------- %s --------" % target print "START: 0x%x" % bv.start diff --git a/python/examples/instruction-iterator.py b/python/examples/instruction-iterator.py index 7b03b095..43bc000e 100644 --- a/python/examples/instruction-iterator.py +++ b/python/examples/instruction-iterator.py @@ -21,10 +21,7 @@ else: target = "/bin/ls" bv = binaryninja.BinaryViewType[bintype].open(target) -bv.update_analysis() - -"""Until update_analysis_and_wait is complete, sleep is necessary as the analysis is multi-threaded.""" -time.sleep(1) +bv.update_analysis_and_wait() print "-------- %s --------" % target print "START: 0x%x" % bv.start -- cgit v1.3.1