protobuf-c 自动逆向脚本开发小记...

Loader

编写脚本的时候发现ida根本没有热重载脚本的功能,每次修改完脚本想看看效果,都要把ida大退然后重启

于是自己写了一个方便的loader,按下Ctrl+Shift+H就可以请求一个路径,按下Ctrl+H快速热重载脚本。

import ida_idaapi
import ida_kernwin
import idaapi
import importlib.util
import sys
import os

class PluginLoadHelper(idaapi.plugin_t):
    flags = idaapi.PLUGIN_KEEP
    wanted_hotkey = "Ctrl-Shift-H"
    wanted_name = "PluginLoadHelper"
    comment = "Load a plugin"
    help = "Press Ctrl-Shift-H to load your plugin"
    plugin_full_path = None

    def flush(self):
        if not self.plugin_full_path:
            return
        if not os.path.exists(self.plugin_full_path):
            ida_kernwin.warning(f"File {self.plugin_full_path} not found!")
            return
        plugin_name = os.path.basename(self.plugin_full_path)
        spec = importlib.util.spec_from_file_location(plugin_name, self.plugin_full_path)
        if not spec:
            ida_kernwin.warning("Parsing spec failed")
            return
        plugin = importlib.util.module_from_spec(spec)
        sys.modules[plugin_name] = plugin
        spec.loader.exec_module(plugin) # type: ignore
        module = plugin.PLUGIN_ENTRY()
        print(f"Plugin {plugin_name} Load success!")
        module.run(b"")

    def init(self): 
        ida_kernwin.add_hotkey("Ctrl-H", self.flush)
        return idaapi.PLUGIN_KEEP

    def run(self, arg):
        self.plugin_full_path = ida_kernwin.ask_str("", ida_kernwin.HIST_FILE, "Load Plugin:")
        self.flush()

    def term(self):
        pass

def PLUGIN_ENTRY():
    return PluginLoadHelper() # type: ignore

参考了官方文档:https://docs.python.org/zh-cn/3/library/importlib.html
学会了怎么动态导入python脚本...

核心实现

其实就是识别魔数,导入结构体,修改地址类型。

然后从结构体中把每个字段的nameidtypelabel都拿出来,再写回.proto文件就可以了

当然,还有更复杂的跨包引用问题,全局引用等问题。考虑构建一棵节点树,每个message下面记录子message,最后把公有的且没有fields的部分提取出来作为package即可。

脚本在下面,好用记得star✨

https://github.com/little-daimi/ProtoCMiner

posted @ 2026-03-18 12:16  imiab  阅读(8)  评论(0)    收藏  举报