Created
July 13, 2019 21:16
-
-
Save zznop/4fbdd86529d144d7df5955c7cb10f5b8 to your computer and use it in GitHub Desktop.
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
import ida_segment | |
import ida_bytes | |
import idautils | |
import idaapi | |
import idc | |
import re | |
__author__ = 'zznop' | |
__copyright__ = 'Copyright 2019, zznop' | |
__email__ = '[email protected]' | |
def get_call_table_instrs(): | |
'''Return all jsr instructions with pc in the operand | |
''' | |
instrs = [] | |
# Iterate instructions in functions | |
for funcea in idautils.Functions(): | |
for (startea, endea) in idautils.Chunks(funcea): | |
for head in idautils.Heads(startea, endea): | |
instr = idc.GetDisasm(head).split() | |
if instr[0] == 'jsr' or instr[0] == 'jmp': | |
if 'pc' in instr[1]: | |
instrs.append(instr) | |
# Iterate instructions not in a function | |
addr = idaapi.find_not_func(0, 1) | |
while addr != idc.BADADDR: | |
instr = idc.GetDisasm(addr).split() | |
if instr[0] == 'jsr' or instr[0] == 'jmp': | |
if 'pc' in instr[1]: | |
instrs.append(instr) | |
addr = idaapi.find_not_func(addr, 1) | |
return instrs | |
def get_call_table_addrs_from_instrs(instrs): | |
'''Get the base addr of the call tables from the instrs | |
''' | |
call_table_addrs = [] | |
for mnem, opnd in instrs: | |
print(opnd) | |
match = re.match(r"^.*_(.*)\(pc,.*\)$", opnd) | |
if match: | |
addr = int(match.group(1), 16) | |
call_table_addrs.append(addr) | |
return call_table_addrs | |
def disas_call_tables(base_table_addrs): | |
for base_addr in base_table_addrs: | |
i = base_addr | |
while True: | |
instr_dword = ida_bytes.get_32bit(i) | |
if not ((instr_dword >> 24) == 0x60): | |
break | |
idc.MakeCode(i) | |
i += 4 | |
def main(): | |
''' | |
''' | |
call_table_instrs = get_call_table_instrs() | |
if call_table_instrs is []: | |
print("Failed to find JSR instructions that modify PC") | |
return | |
call_table_addrs = get_call_table_addrs_from_instrs(call_table_instrs) | |
if call_table_addrs is []: | |
print("Failed to enumerate call table base addresses from instructions") | |
return | |
disas_call_tables(call_table_addrs) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment