summaryrefslogtreecommitdiff
path: root/python/examples
diff options
context:
space:
mode:
Diffstat (limited to 'python/examples')
-rwxr-xr-xpython/examples/export_svg.py78
1 files changed, 56 insertions, 22 deletions
diff --git a/python/examples/export_svg.py b/python/examples/export_svg.py
index ce5122ae..7ce804ea 100755
--- a/python/examples/export_svg.py
+++ b/python/examples/export_svg.py
@@ -3,14 +3,14 @@ import os
import webbrowser
import time
import sys
-try:
- from urllib import pathname2url # Python 2.x
-except:
- from urllib.request import pathname2url # Python 3.x
+from pathlib import Path
+from urllib.request import pathname2url
-from binaryninja.interaction import get_save_filename_input, show_message_box
+from binaryninja.interaction import get_save_filename_input, show_message_box, TextLineField, ChoiceField, SaveFileNameField, get_form_input
+from binaryninja.settings import Settings
from binaryninja.enums import MessageBoxButtonSet, MessageBoxIcon, MessageBoxButtonResult, InstructionTextTokenType, BranchType
from binaryninja.plugin import PluginCommand
+from binaryninja.log import log_error
colors = {'green': [162, 217, 175], 'red': [222, 143, 151], 'blue': [128, 198, 233], 'cyan': [142, 230, 237], 'lightCyan': [
176, 221, 228], 'orange': [237, 189, 129], 'yellow': [237, 223, 179], 'magenta': [218, 196, 209], 'none': [74, 74, 74]}
@@ -35,30 +35,49 @@ def escape(toescape):
def save_svg(bv, function):
- address = hex(function.start).replace('L', '')
- path = os.path.dirname(bv.file.filename)
+ sym = bv.get_symbol_at(function.start)
+ if sym:
+ offset = sym.name
+ else:
+ offset = "%x" % function.start
+ path = Path(os.path.dirname(bv.file.filename))
origname = os.path.basename(bv.file.filename)
- filename = os.path.join(
- path, 'binaryninja-{filename}-{function}.html'.format(filename=origname, function=address))
- outputfile = get_save_filename_input(
- 'File name for export_svg', 'HTML files (*.html)', filename)
- if sys.platform == "win32":
- outputfile = outputfile.replace('/', '\\')
- if outputfile is None:
+ filename = path / f'binaryninja-{origname}-{offset}.html'
+
+ functionChoice = TextLineField("Blank to accept default")
+ # TODO: implement linear disassembly settings and output
+ modeChoices = ["Graph"]
+ modeChoiceField = ChoiceField("Mode", modeChoices)
+ if Settings().get_bool('ui.debugMode'):
+ formChoices = ["Assembly", "LLIL", "LLIL SSA", "MLIL", "MLIL SSA", "HLIL", "HLIL SSA"]
+ formChoiceField = ChoiceField("Form", formChoices)
+ else:
+ formChoices = ["Assembly", "LLIL", "MLIL", "HLIL"]
+ formChoiceField = ChoiceField("Form", formChoices)
+
+ saveFileChoices = SaveFileNameField("Output file", 'HTML files (*.html)', str(filename))
+ if not get_form_input([f'Current Function: {offset}', functionChoice, formChoiceField, modeChoiceField, saveFileChoices], "SVG Export") or saveFileChoices.result is None:
return
- content = render_svg(function, origname)
+ if saveFileChoices.result == '':
+ outputfile = filename
+ else:
+ outputfile = saveFileChoices.result
+ content = render_svg(function, offset, modeChoices[modeChoiceField.result], formChoices[formChoiceField.result], origname)
output = open(outputfile, 'w')
output.write(content)
output.close()
result = show_message_box("Open SVG", "Would you like to view the exported SVG?",
buttons=MessageBoxButtonSet.YesNoButtonSet, icon=MessageBoxIcon.QuestionIcon)
if result == MessageBoxButtonResult.YesButton:
- url = 'file:{}'.format(pathname2url(bytes(outputfile)))
- webbrowser.open(url)
+ # might need more testing, latest py3 on windows seems.... broken with these APIs relative to other platforms
+ if sys.platform == 'win32':
+ webbrowser.open(outputfile)
+ else:
+ webbrowser.open('file://' + str(outputfile))
def instruction_data_flow(function, address):
- ''' TODO: Extract data flow information '''
+ # TODO: Extract data flow information
length = function.view.get_instruction_length(address)
func_bytes = function.view.read(address, length)
if sys.version_info[0] == 3:
@@ -69,8 +88,23 @@ def instruction_data_flow(function, address):
return 'Opcode: {bytes}'.format(bytes=padded)
-def render_svg(function, origname):
- graph = function.create_graph()
+def render_svg(function, offset, mode, form, origname):
+ if form == "Assembly":
+ graph = function.create_graph()
+ elif form == "LLIL":
+ graph = function.llil.create_graph()
+ elif form == "LLIL SSA":
+ graph = function.llil.ssa_form.create_graph()
+ elif form == "MLIL":
+ graph = function.mlil.create_graph()
+ elif form == "MLIL SSA":
+ graph = function.mlil.ssa_form.create_graph()
+ elif form == "HLIL":
+ graph = function.hlil.create_graph()
+ elif form == "HLIL SSA":
+ graph = function.hlil.ssa_form.create_graph()
+ else:
+ log_error(f"Invalid form selection: {form}")
graph.layout_and_wait()
heightconst = 15
ratio = 0.48
@@ -242,8 +276,8 @@ def render_svg(function, origname):
output += ' </g>\n'
output += '</svg>'
- output += '<p>This CFG generated by <a href="https://binary.ninja/">Binary Ninja</a> from {filename} on {timestring}.</p>'.format(
- filename=origname, timestring=time.strftime("%c"))
+ output += '<p>This CFG generated by <a href="https://binary.ninja/">Binary Ninja</a> from {filename} on {timestring} showing {function} as {form}.</p>'.format(
+ filename=origname, timestring=time.strftime("%c"), function=offset, form=form)
output += '</html>'
return output