FRC(Fast Rename from Clipboard)

前言

​ 在分析某款固件过程中,由于去了符号表,但是好多的函数名还是能够根据其调用链分析出来的,例如:

image-20241222163523951

我们不难猜测出这个一个注册函数的功能,只需要逐个复制字符串然后再到后面的sub_xxxx上重命名黏贴就能手动恢复函数名了。这一过程就十分繁琐了(选中字符串->复制->再选中未命名函数->n(rename global item)->黏贴->回车),为了能够节约这么一步骤,我就突发奇想是不是能够开发一个插件来减少其中的步骤,快速进行函数重命名操作呢?FRC的设计初衷就是这了。

需求分析

​ 作为一个半吊子的ida插件设计者,大致整理了一下插件需要实现的功能:

  1. 通过快捷键实现字符串的复制
  2. 通过快捷键实现函数的重命名操作

接着就对这两个方向进行分析。

相关资料

我本人也不是特别抗拒使用GPT来进行开发,但是会觉得GPT加快了获取结果的进度,而过程的处理变得有些不动🧠了,所以在插件实现的过程中多查阅相关资料还是很有必要的。

idc_apiIDC API 参考 |Hex-Rays 文档 (作者能力比较弱,都是通过调用idc内置接口来实现该插件)

pyperclip库pyperclip 剪贴板 — python3Go latest 文档

idapython脚本入门IDA从入门到乞讨之IDAPython Script 与 plugin-软件逆向-看雪-安全社区|安全招聘|kanxue.com

ida9.0官方手册IDAPython: Welcome to IDAPython API Reference 9.0sp1

内容实现

通过快捷键实现字符串的复制

很幸运的是,当我们点击某一字符串后会直接将该字符串给选中,对该功能的实现来说无疑是极其匹配的(懒狗😋)

image-20241222165746222

那么便敲定了,用户选中字符串后使用ctrl+c复制的内容将作为某一函数将要被命名的值。

这里我们需要引入pyperclip库来进行复制黏贴操作:

选中字符串后命令行导入pyperclip库查看黏贴结果

image-20241222171831355

成功打印选中的字符!

image-20241222171912699

重命名字符串的获取也就敲定了。而快捷键也就默认设置为系统的Ctrl+c复制字符串。

通过快捷键实现函数的重命名操作

ida9.0 python api删除了许多老版本的api,这对开发者来说无疑是痛苦的(还好我没搞过),那么就要从这一系列可用的python接口里调用。

模板

一个简单的模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import idaapi
import idc

class MyPlugin(idaapi.plugin_t): # 继承自 idaapi.plugin_t 这个类将定义插件的行为
flags = 0
comment = "插件注释"
help = "插件帮助"
wanted_name = "插件名称"
wanted_hotkey = "热键"

def init(self): # init 方法在插件被加载时调用
idaapi.msg("加载时输出窗口打印")
return idaapi.PLUGIN_OK

def run(self, arg): # run 方法在插件被执行时调用
idaapi.msg("运行时输出窗口打印")

def term(self): # term 方法在插件被卸载时调用
idaapi.msg("卸载时输出窗口打印")

def PLUGIN_ENTRY(): # PLUGIN_ENTRY 函数是插件的入口点 返回一个插件对象的实例
return MyPlugin()

想实现类似于ctrl+v的操作,为了不冲突设置为shift+v 热键绑定get√

函数重命名操作实现

如何实现函数重命名操作?翻翻api接口看看🤔

get_func_name(ea)–通过函数所在地址返回函数名字符串

1
2
3
4
5
6
retrieve function name
ea - any address belonging to the function
returns: 0 - function doesn't exist
otherwise returns function name

string get_func_name(long ea);

image-20241222175010099

这里可以看到get_func_name()是基于逻辑地址来向上获取到对应的函数名

image-20241222175519259

从这我们又可以发散一下思想,我们可以基于函数地址(0x41AE88)或者是基于操作数(0x409A54)实现函数的定位操作,随后进行重命名。

set_name(ea, name)–线性地址重命名操作

使用set_name(ea)来对函数进行重命名操作

image-20241222185006026

基于逻辑地址的函数重命名操作

这种方法就是利用上面的get_func_name()来获取到对应的逻辑地址,再利用set_name(逻辑地址)实现对逻辑地址的重命名

优点:实现简单

只需要获取到对应的逻辑地址后再进行重命名操作即可

缺点:操作复杂

当我们鼠标选中sub_4333A8时,我们是通过idc.get_screen_ea()来获取到当前光标所在地址,此时get_func_name(ea)中传入的是0x41AEE0(也就是ea),而不是0x4333A8,这也就会导致get_func_name(ea)得到的值为空而不是我们想要修改的sub_4333A8,这时我们执行set_name(ea, new_name)将修改0x41AEE0地址的函数值

image-20241222185504321

image-20241222185658831

image-20241222190837067

此时若我们想要修改sub_4333A8的函数名,就需要点击进入到sub_4333A8中,将光标点在该函数中才能控制ea的值从而实现函数重命名。也就意味着这种方法重命名函数需要我们跟进到函数里面才能快捷重命名。简单了,但是简单了一点。🧐

image-20241222191020706

初版demo:选中字符串->复制->再选中未命名函数->enter->重命名(热键)

相较一开始的步骤:选中字符串->复制->再选中未命名函数->n(rename global item)->黏贴->回车 减少了一步

image-20241222191428874

get_operand_value(ea,n)–获取操作数中使用的数字,n为操作数编号

在介绍下面这种方法前先看看该api定义

image-20241222191643597

基于操作数定位的函数重命名操作

通过获取操作数中的立即值,从而实现函数的定位

image-20241222192104866

实现:选中字符串->复制->再选中未命名函数->重命名(热键)

缩小成了四个步骤

image-20241222192511165

完整版

最后也没有舍弃掉基于逻辑地址的重命名操作,全部整合在一起了。

见github项目:https://github.com/tw11ty/FRC-Fast_Rename_from_Clipboard.git

需求拓展

  1. 对重命名的美化操作:例如.cgi .htm .asp .php等等后缀操作进行大写突出,方便识别
  2. 不局限于函数名重命名,还能重命名标签
  3. 批量自动化
  4. . . . . . .

针对1其实也就是对字符串的操作了

针对2有个get_name获取对应标签名,set_name设置标签名

针对3有些不会了。。。

. . . . . .

字符串操作

增加字符串自定义操作

image-20241222204742676

标签名重命名

删除get_func_name(ea)校验函数名操作

image-20241222194930450

函数指针重命名

像是netgear的许多cgi方法都是和对应的常数数据放在一起,只需要获取到对应地址里的四字节地址然后再重命名即可。可以看另一个批量修复函数名的插件:https://github.com/tw11ty/DCD-Recovery.git

image-20241222204947736

批量自动化?🫣

暂时还没什么想法来搞自动化分析

不过有一些思路:列出所有调用注册函数的地址,凡是符合调用规则的一律打死(重命名)

一些思考

这个插件想想其实没什么创新点,只是把复制、黏贴、重命名这几步压缩,到底还是离不开手动重命名操作。看到网上有很多IDA_GPT插件,想来也是比该插件更好。;🤩

关于批量自动化分析程序应该也会慢慢向人工智能分析靠拢,调用对应的api算是自制插件最简单的方法了吧。😉