Skip to content

Instantly share code, notes, and snippets.

@joshwatson
Last active July 6, 2023 08:15
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save joshwatson/f28b7a2d3356a0ed39823aaea66b50d0 to your computer and use it in GitHub Desktop.
Save joshwatson/f28b7a2d3356a0ed39823aaea66b50d0 to your computer and use it in GitHub Desktop.
MLIL Slicing in Binary Ninja
from binaryninja import HighlightStandardColor, PluginCommand
def do_backward_slice(instruction, function):
# switch to SSA form (this does nothing if it's already SSA).
instruction_queue = set([instruction.ssa_form.instr_index])
visited_instructions = set()
variables = set()
while instruction_queue:
visit_index = instruction_queue.pop()
if visit_index is None or visit_index in visited_instructions:
continue
instruction_to_visit = function[visit_index]
if instruction_to_visit is None:
continue
instruction_queue.update(
(
function.get_ssa_var_definition(new_var)
for new_var in instruction_to_visit.vars_read
)
)
variables.update(instruction_to_visit.vars_read)
visited_instructions.add(visit_index)
return visited_instructions
def do_forward_slice(instruction, function):
# if no variables written, return the empty set.
if not instruction.ssa_form.vars_written:
return set()
instruction_queue = {
use for var in instruction.ssa_form.vars_written if var.var.name
for use in function.ssa_form.get_ssa_var_uses(var)
}
visited_instructions = {instruction.ssa_form.instr_index}
while instruction_queue:
visit_index = instruction_queue.pop()
if visit_index is None or visit_index in visited_instructions:
continue
instruction_to_visit = function[visit_index]
if instruction_to_visit is None:
continue
instruction_queue.update(
(
use for var in instruction_to_visit.ssa_form.vars_written
if var.var.name
for use in function.ssa_form.get_ssa_var_uses(var)
)
)
visited_instructions.add(visit_index)
return visited_instructions
def program_slice(instruction, direction, color=None):
function = instruction.function.ssa_form
bv = function.source_function.view
if color is None:
color = HighlightStandardColor.BlueHighlightColor
if direction == 'backward':
visited_instructions = do_backward_slice(instruction, function)
if direction == 'forward':
visited_instructions = do_forward_slice(instruction, function)
bv.begin_undo_actions()
for visited_instruction in visited_instructions:
function.source_function.set_user_instr_highlight(
function[visited_instruction].address,
color
)
bv.commit_undo_actions()
def backward_slice(bv, addr):
function = bv.get_functions_containing(addr)[0]
instruction = function.get_low_level_il_at(addr).medium_level_il
program_slice(instruction, 'backward')
def forward_slice(bv, addr):
function = bv.get_functions_containing(addr)[0]
instruction = function.get_low_level_il_at(addr).medium_level_il
program_slice(instruction, 'forward')
PluginCommand.register_for_address(
'Slice backwards',
'Slice variable backwards from this point',
backward_slice)
PluginCommand.register_for_address(
'Slice forward',
'Slice variable forward from this point',
forward_slice
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment