mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
102 lines
2.7 KiB
Python
102 lines
2.7 KiB
Python
"""
|
|
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()
|
|
|