Repository URL to install this package:
Version:
9.1~250226-1.fc43 ▾
|
"""
summary: add a custom microcode block optimization rule
description:
Installs a custom microcode block optimization rule,
to transform:
goto L1
...
L1:
goto L2
into
goto L2
In other words we fix a goto target if it points to a chain of gotos.
This improves the decompiler output in some cases.
level: advanced
"""
import ida_bytes
import ida_range
import ida_kernwin
import ida_hexrays
import ida_typeinf
import ida_idaapi
class goto_optimizer_t(ida_hexrays.optblock_t):
def func(self, blk):
if self.handle_goto_chain(blk):
return 1
return 0
def handle_goto_chain(self, blk):
mgoto = blk.tail
if not mgoto or mgoto.opcode != ida_hexrays.m_goto:
return False
visited = []
t0 = mgoto.l.b
i = t0
mba = blk.mba
# follow the goto chain
while True:
if i in visited:
return False
visited.append(i)
b = mba.get_mblock(i)
m2 = ida_hexrays.getf_reginsn(b.head)
if not m2 or m2.opcode != ida_hexrays.m_goto:
break
i = m2.l.b
if i == t0:
return False # not a chain
# all ok, found a goto chain
mgoto.l.b = i # jump directly to the end of the chain
# fix the successor/predecessor lists
blk.succset[0] = i
mba.get_mblock(i).predset.add(blk.serial)
mba.get_mblock(t0).predset._del(blk.serial)
# since we changed the control flow graph, invalidate the use/def chains.
# stricly speaking it is not really necessary in our plugin because
# we did not move around any microcode operands.
mba.mark_chains_dirty()
# it is a good idea to verify microcode after each change
# however, it may be time consuming, so comment it out eventually
mba.verify(True);
return True
# --------------------------------------------------------------------------
# a plugin interface, boilerplate code
class my_plugin_t(ida_idaapi.plugin_t):
flags = ida_idaapi.PLUGIN_HIDE
wanted_name = "Optimize goto chains (IDAPython)"
wanted_hotkey = ""
comment = "Sample plugin11 for Hex-Rays decompiler"
help = ""
def init(self):
if ida_hexrays.init_hexrays_plugin():
self.optimizer = goto_optimizer_t()
self.optimizer.install()
return ida_idaapi.PLUGIN_KEEP # keep us in the memory
def term(self):
self.optimizer.remove()
def run(self, arg):
if arg == 1:
return self.optimizer.remove()
elif arg == 2:
return self.optimizer.install()
def PLUGIN_ENTRY():
return my_plugin_t()