Latest available version: IDA and decompilers v8.4.240527sp2 see all releases
Hex-Rays logo State-of-the-art binary code analysis tools
email icon
* Hex-Rays Decompiler project
* Copyright (c) 2007-2024 by Hex-Rays,
* Sample plugin for Hex-Rays Decompiler.
* It installs a custom block optimization rule:
* goto L1 => goto L2
* ...
* L1:
* 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.
#include <hexrays.hpp>
struct goto_optimizer_t : public optblock_t
virtual int idaapi func(mblock_t *blk) override
if ( handle_goto_chain(blk) )
return 1;
return 0;
//lint -e{818} ins could be made const
bool handle_goto_chain(mblock_t *blk) const
minsn_t *mgoto = blk->tail;
if ( mgoto == nullptr || mgoto->opcode != m_goto )
return false;
intvec_t visited;
int t0 = mgoto->l.b;
int i = t0;
mba_t *mba = blk->mba;
// follow the goto chain
while ( true )
if ( !visited.add_unique(i) )
return false; // an endless loop, prefer to keep things as is
mblock_t *b = mba->get_mblock(i);
// skip assertion instructions and find first regular instruction
if ( m2 == nullptr || m2->opcode != m_goto )
break; // not a goto
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;
// 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.
// it is a good idea to verify microcode after each change
// however, it may be time consuming, so comment it out eventually
return true;
struct plugin_ctx_t : public plugmod_t
goto_optimizer_t goto_optimizer;
virtual bool idaapi run(size_t) override;
static plugmod_t *idaapi init()
return nullptr; // no decompiler
const char *hxver = get_hexrays_version();
msg("Hex-rays version %s has been detected, %s ready to use\n",
hxver, PLUGIN.wanted_name);
return new plugin_ctx_t;
bool idaapi plugin_ctx_t::run(size_t arg)
if ( arg == 1 )
msg("%s disabled\n", PLUGIN.wanted_name);
else if ( arg == 2 )
msg("%s enabled\n", PLUGIN.wanted_name);
msg("The %d arg is unknown (1 disable, 2 enable)\n", int(arg));
return false;
static const char comment[] = "Sample11 plugin for Hex-Rays decompiler";
plugin_t PLUGIN =
PLUGIN_MULTI, // The plugin can work with multiple idbs in parallel
init, // initialize
comment, // long comment about the plugin
nullptr, // multiline help about the plugin
"Optimize goto chains", // the preferred short name of the plugin
nullptr, // the preferred hotkey to run the plugin
Micro block array (internal representation of the decompiled code).
Definition: hexrays.dox:59
void mark_chains_dirty()
Mark the microcode use-def chains dirty.
Definition: hexrays.hpp:11339
void verify(bool always) const
Verify microcode consistency.
Definition: hexrays.hpp:11333
const mblock_t * get_mblock(int n) const
Get basic block by its serial number.
Definition: hexrays.hpp:4856
Microcode of one basic block.
Definition: hexrays.hpp:3805
minsn_t * head
pointer to the first instruction of the block
Definition: hexrays.hpp:3840
minsn_t * tail
pointer to the last instruction of the block
Definition: hexrays.hpp:3841
int serial
block number
Definition: hexrays.hpp:3843
intvec_t succset
control flow graph: list of our successors use nsucc() and succ() to access it
Definition: hexrays.hpp:3861
intvec_t predset
control flow graph: list of our predecessors use npred() and pred() to access it
Definition: hexrays.hpp:3859
mba_t * mba
the parent micro block array
Definition: hexrays.hpp:3842
Microinstruction class #insn.
Definition: hexrays.hpp:3465
mop_t l
left operand
Definition: hexrays.hpp:3474
mcode_t opcode
instruction opcode
Definition: hexrays.hpp:3469
HexRays SDK header file.
bool init_hexrays_plugin(int flags=0)
Check that your plugin is compatible with hex-rays decompiler.
Definition: hexrays.hpp:8601
const minsn_t * getf_reginsn(const minsn_t *ins)
Skip assertions forward.
Definition: hexrays.hpp:11047
bool remove_optblock_handler(optblock_t *opt)
Remove a block level custom optimizer.
Definition: hexrays.hpp:10496
void install_optblock_handler(optblock_t *opt)
Install a block level custom optimizer.
Definition: hexrays.hpp:10490
void term_hexrays_plugin()
Stop working with hex-rays decompiler.
Definition: hexrays.hpp:8609
const char * get_hexrays_version()
Get decompiler version.
Definition: hexrays.hpp:11511
User defined callback to optimize microcode blocks.
Definition: hexrays.hpp:2140
virtual int func(mblock_t *blk)=0
Optimize a block.