MCPcopy Create free account
hub / github.com/Vector35/binaryninja-api / find_jump_table

Function find_jump_table

python/examples/jump_table.py:28–83  ·  view source on GitHub ↗
(bv, addr)

Source from the content-addressed store, hash-verified

26
27
28def find_jump_table(bv, addr):
29 for block in bv.get_basic_blocks_at(addr):
30 func = block.function
31 arch = func.arch
32 addrsize = arch.address_size
33
34 # Grab the instruction tokens so that we can look for the table's starting address
35 tokens, length = arch.get_instruction_text(bv.read(addr, 16), addr)
36
37 # Look for the next jump instruction, which may be the current instruction. Some jump tables will
38 # compute the address first then jump to the computed address as a separate instruction.
39 jump_addr = addr
40 while jump_addr < block.end:
41 info = arch.get_instruction_info(bv.read(jump_addr, 16), jump_addr)
42 if len(info.branches) != 0:
43 break
44 jump_addr += info.length
45 if jump_addr >= block.end:
46 print("Unable to find jump after instruction 0x%x" % addr)
47 continue
48 print("Jump at 0x%x" % jump_addr)
49
50 # Collect the branch targets for any tables referenced by the clicked instruction
51 branches = []
52 for token in tokens:
53 if InstructionTextTokenType(
54 token.type
55 ) == InstructionTextTokenType.PossibleAddressToken: # Table addresses will be a "possible address" token
56 tbl = token.value
57 print("Found possible table at 0x%x" % tbl)
58 i = 0
59 while True:
60 # Read the next pointer from the table
61 data = bv.read(tbl + (i*addrsize), addrsize)
62 if len(data) == addrsize:
63 if addrsize == 4:
64 ptr = struct.unpack("<I", data)[0]
65 else:
66 ptr = struct.unpack("<Q", data)[0]
67
68 # If the pointer is within the binary, add it as a destination and continue
69 # to the next entry
70 if (ptr >= bv.start) and (ptr < bv.end):
71 print("Found destination 0x%x" % ptr)
72 branches.append((arch, ptr))
73 else:
74 # Once a value that is not a pointer is encountered, the jump table is ended
75 break
76 else:
77 # Reading invalid memory
78 break
79
80 i += 1
81
82 # Set the indirect branch targets on the jump instruction to be the list of targets discovered
83 func.set_user_indirect_branches(jump_addr, branches)
84
85

Callers

nothing calls this directly

Calls 6

get_basic_blocks_atMethod · 0.80
get_instruction_textMethod · 0.45
readMethod · 0.45
get_instruction_infoMethod · 0.45
appendMethod · 0.45

Tested by

no test coverage detected