← 返回文章归档
FIELD NOTES / Reverse2 MIN READ

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

Loader

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
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脚本…

核心实现

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

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

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

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

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

FROM THE ARCHIVE

这篇文章迁移自我的博客园,保留最初的记录。

阅读原文 ↗
/ END✳∷ — 00
SEARCH / 00

搜索文章

输入关键词,搜索全部文章。

标题 / 标签 / 全文ESC 关闭