Tiny microcode optimizer 【微码优化器 】

注:ida pro7.4及以后版本才有这功能。

It is not a surprise to hear the IDA and Decompiler cannot handle all possible cases and eventually fail to recognize a construct, optimize an expression and represent it in its simplest form. It is perfectly understandable — nobody has resources to handle everything. This is why we publish a rich API that can be used to enhance the analysis and add your own optimization rules.

听到IDA和Decompiler无法处理所有可能的情况并最终无法识别构造,优化表达式并以最简单的形式表示它,这不足为奇。 完全可以理解-没有人有能力处理所有事情。 因此,我们发布了丰富的API,可用于增强分析并添加您自己的优化规则。

Let us consider the decompiler. Currently, we focus on the compiler-generated code because hand-crafted code can use literally infinite number of tricks to confuse an automatic tool, not to mention seasoned reverses. Nevertheless, some users still want our decompiler to handle some assembler constructs that are usually not used by a compiler. To be concrete, let us take the following example:

让我们考虑反编译器。 当前,我们专注于编译器生成的代码,因为手工编写的代码可以使用字面上无数的技巧来混淆自动工具,更不用说经验丰富的反向技巧了。 尽管如此,一些用户仍然希望我们的反编译器处理一些编译器通常不使用的汇编器结构。 具体来说,让我们以以下示例为例:

x | ~x

This expression always evaluates to -1 (all bits set) but the decompiler does not know about this fact and does not have a dedicated optimization rule for it. However, it is pretty easy to implement a very short plugin for that. The core of the plugin will take just a few lines to carry out the optimization:

该表达式的计算结果始终为-1(所有位均已设置),但是反编译器不知道这一事实,也没有专用的优化规则。 但是,为此实现一个非常短的插件非常容易。 插件的核心仅需几行即可进行优化:

if ins.opcode == m_or and ins.r.is_insn(m_bnot) and ins.l == ins.r.d.l:
   if not ins.l.has_side_effects(): # avoid destroying side effects
       ins.opcode = m_mov
       ins.l.make_number(-1, ins.r.size)
       ins.r = mop_t()
       self.cnt = self.cnt + 1 # number of changes we made

We check if the current instruction is an OR of an operand with its binary negation. If so, we check for the side effects because we do not want to remove function calls, for example. If everything is fine, we replace x|~x with -1 and increment the number of changes that we made to the microcode. 

我们检查当前指令是否为操作数or与它的二进制取反。 如果是这样,我们将检查副作用,因为例如,我们不想删除函数调用。 如果一切正常,则将x |〜x替换为-1,并增加对微码所做的更改次数。

The rest is just boilerplate code. The full text of the plugin and a sample database are available below.

剩下的只是样板代码。 插件的全文和示例数据库在下面提供。

We hope this very short post and the tiny plugin will inspire you to write more complex optimization rules.

我们希望这篇简短的文章和这个小插件能激发您编写更复杂的优化规则。

be_ornot_be.py

#
#      Hex-Rays Decompiler project
#      Copyright (c) 2007-2020 by Hex-Rays, [email protected]
#      ALL RIGHTS RESERVED.
#
#      Sample plugin for Hex-Rays Decompiler.
#      It installs a custom microcode optimization rule:
#        x | ~x => -1
#
#      To see this plugin in action please use be_ornot_be.idb
#

from ida_hexrays import *
import ida_idaapi

# recognize "x | ~x" and replace by -1
class subinsn_optimizer_t(minsn_visitor_t):
    cnt = 0
    def __init__(self):
        minsn_visitor_t.__init__(self)
    def visit_minsn(self):      # for each instruction...
        ins = self.curins       # take a reference to the current instruction

        # THE CORE OF THE PLUGIN IS HERE:
        # check the pattern "x | ~x"
        if ins.opcode == m_or and ins.r.is_insn(m_bnot) and ins.l == ins.r.d.l:
            if not ins.l.has_side_effects(): # avoid destroying side effects
                # pattern matched, convert to "mov -1, ..."
                ins.opcode = m_mov
                ins.l.make_number(-1, ins.r.size)
                ins.r = mop_t()
                self.cnt = self.cnt + 1 # number of changes we made
        return 0 # continue traversal

# a custom instruction optimizer, boilerplate code
class sample_optimizer_t(optinsn_t):
    def __init__(self):
        optinsn_t.__init__(self)
    def func(self, blk, ins, optflags):
        opt = subinsn_optimizer_t()
        ins.for_all_insns(opt)
        if opt.cnt != 0:                # if we modified microcode,
            blk.mba.verify(True)        # run the verifier
        return opt.cnt                  # report the number of changes

# a plugin interface, boilerplate code
class my_plugin_t(ida_idaapi.plugin_t):
    flags = ida_idaapi.PLUGIN_HIDE
    wanted_name = "optimize x|~x"
    wanted_hotkey = ""
    comment = ""
    help = ""
    def init(self):
        if init_hexrays_plugin():
            self.optimizer = sample_optimizer_t()
            self.optimizer.install()
            print("Installed sample optimizer for 'x | ~x'")
            return ida_idaapi.PLUGIN_KEEP # keep us in the memory
    def term(self):
            self.optimizer.remove()
    def run(self):
            pass

def PLUGIN_ENTRY():
    return my_plugin_t()

idb 地址:

https://www.hex-rays.com/wp-content/uploads/2020/04/be_ornot_be.idb

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章