Last active
July 6, 2023 08:15
-
-
Save joshwatson/f28b7a2d3356a0ed39823aaea66b50d0 to your computer and use it in GitHub Desktop.
MLIL Slicing in Binary Ninja
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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