IDA Plugin 编写基础

三、IDA文件目录介绍及其扩展功能 一、*IDA文件目录简介* IDA的文件目录一般如下图所示,接下来介绍其几个文件夹的作用 cfg:cfg目录包含各种配置文件,包括基本的IDA配置文件ida.cfg,GUI配置文件idagui.cfg以及文本模式用户界面配置文件idatui.cfg。 dbgsrv: 在linux动态调试 ELF 文件对应的组件。 idc:idc目录包含IDA的内置脚本语言IDC所需的核心文件。 ids:ids目录包含一些符号文件(IDA语法中的IDS文件),这些文件用于描述可被加载到IDA的二进制文件引用的共享库的内容。 阅读详情
 IDA是迄今为止最为强大的反汇编器,它有着众多的功能。但是如果它不具备通过附加的模块来对标准的函数进行扩展的功能(粗俗点说就是plugin)的话,也就有负此盛名了。现在我们就来更为详细地研究一下如何编写这些plugin。

喏,首要的就是要有这个叫做IDA的反汇编器,同时还要有与之匹配的IDA SDK。SDK里主要的部分就是include目录及其下的所有文件,这些文件里包含了编写plugin所用到的所有的宏定义和函数原型,同时用到它们的还有import lib —— ida.lib。我这里使用的编译器是Intel C++,与VC++结合起来用。我选择它的原因就是,在SDK中没有对它进行内嵌的支持(比如在SDK中就有Borland C++和VC++编译器的安装文件),而这能使我们更好地理解。ida.lib文件是ida.wll(位于IDA目录下)的import library。其中所有的函数都是用ordinal导出的,而ordinal与函数名的比较是在ida.lib里进行的。这就是需要使用与IDA版本相匹配的SDK的原因了,因为导出函数的ordinal会因版本的不同而发生变化。喏,好了,万事具备了,我们开始吧。

plugin到底是个什么东东呢?其实它也没什么稀奇的,就像一个通常的DLL,只是导出了下面这个名为PLUGIN的结构体:



 struct plugin_t
 {int version;        // IDA的版本,用于plugin的编写,通常这个域的值为IDP_INTERFACE_VERSION - 表示SDK版本的constant。
                         如果这个域的值与所用IDA的版本不一致,就不会加载此plugin。
  int flags           // 这个好理解,就是些标志。嫌麻烦添0就行了。但这里要讲一下所有可能的取值。
                         
                         PLUGIN_MOD - 置位表示plugin会修改database(坦白讲,没有什么plugin会修改它)。如果此位置位,
                         而进程模块却禁止修改database,则plugin就不会被使用。这个标志我们并不需要,另外的几个也是一样。

                         PLUGIN_DRAW - 置位表示IDA在调用plugin后需要重画(即刷新)所有窗口。

                         PLUGIN_SEG - plugin只在鼠标所放之处的地址属于某个segment时才能使用。这里也不需要。

                         PLUGIN_UNL - 若置位,则plugin在使用后会从内存中卸载。这对于调试器来说当然是好了,但对我们来说
                         就不太合适了。 

                         这些标志可以用逻辑或(我们这里用or,C语言里用“|”)结合起来。但我说过,更为简单的是把所有这些
                         域都填成红色的NULL。

  void (idaapi* init)(void);        //初始化函数加载plugin的时候调用,如果函数返回了什么不好的东西,则plugin就不会被加载。

  void (idaapi* term)(void);        //卸载plugin时调用。一般不使用。

  void (idaapi* run)(int arg);      //也许这是最重要的域了 - working function,每次调用plugin都要运行,包含着plugin的主要
                                      代码。
  char* comment;                    //注释,作提示用的。
  char* help;                       //help自然就是help了.
  char* wanted_name;                //首选的plugin名。
  char* wanted_hotkey;              //首选的热键。一般来说不依赖于plugin作者选用的键,实际的热键值记录在plugin.cfg,这个
                                      文件后面会讲到。
};

一般来说,include里的loader.hpp文件里这个结构体是作为类来声明的,我想对那些不了解类的读者说,其实在C++里类和结构体在本质上都是一样的。喏,好像到了该给出源代码的时候了。我这里给出一个最简单的plugin,这个plugin会将database中的无用指令:
бесполезные группы инструкций:

pusha
popa

push eax
push edx
rdtsc
pop edx
pop eax

push edx
push eax
rdtsc
pop eax
pop edx

替换为“更为明了”的nop指令。下面是代码:

#pragma comment(linker,"/NODEFAULTLIB")
#pragma comment(linker,"/Entry:Dllmain")    //Runtime库占了40kb字节,却没什么有用的东西,特别是对plugin。
                                              然而,如果切断它,则需要重新标记入口点。

#define __NT__
#define __IDP__    //这个一定要有,否则plugin就罢工。

typedef unsigned char BYTE;    //这里没有包含标准的include文件需要额外定义BYTE类型

#i nclude <ida.hpp>
#i nclude <idp.hpp>
#i nclude <bytes.hpp>
#i nclude <loader.hpp>
#i nclude <kernwin.hpp>    //"绅士的选择" IDA中的头文件

  //重新标记入口点
bool Dllmain(void* hInstDLL, int reason, int reserved)
{return true;}

char comment[] = "Experimental plugin";
char help[] = "Experimental plugin";
char wanted_name[] = "ExpPlugin";
char wanted_hotkey[] = "F11";

BYTE rdtsc1[]={0x52, 0x0F, 0x31, 0x5A, 0x58};
BYTE rdtsc2[]={0x50, 0x0F, 0x31, 0x58, 0x5A};    //就是些opcodes

  //plugin的initialization procedure

根据不同的返回值,IDA可以加载或者不加载plugin。可能返回的值有:

    PLUGIN_SKIP - 不加载返回值。

    PLUGIN_OK - 喏,一个OK自然要加载plugin啦。

    PLUGIN_KEEP - 不但要加载,还要常驻内存。

比如说,要想让plugin只处理PE格式的文件,需要这样写initialization procedure:

if (inf.filetype != f_PE) return PLUGIN_SKIP;
return PLUGIN_OK;

这里就不研究那个inf结构体了,详情请见SDK。我们这里总是要加载plugin的,所以代码如下:

int init(void)
{return PLUGIN_OK;}

    //在unload procedure里也是什么也不用干,空着它。

void term(void)
{return;}

    //最后就是主要的run函数了
在研究主函数之前有兴趣可以研究一下database的读写函数,还有获取当前地址的函数,也即IDA中鼠标所放之处的地址:

 get_byte
 get_word
 get_long - 从database中读取各种长度字节。接受一个参数——listing中的地址。

 patch_byte
 patch_word
 patch_long - 向database中写入各种长度字节。两个参数,第一个——地址,第二个——值。

可以猜到,名字里有byte的函数是用于(即接受或返回)字节的,word——字,而long——双字。

 get_screen_ea - 获取当前地址的函数,当前地址就是它的返回值。

void run(int arg)
{BYTE cb1;
  int i, tmp0;

 ea_t CA = get_screen_ea();
 cb1=get_byte(CA);

    //pusha
    //popa
 if (cb1==0x60 && get_byte(CA+1)==0x61)    // pusha的opcode - 60h,而popa - 61h
   {patch_word(CA, 0x9090);
     return;}

    //rdtsc
 if (cb1==0x50)    //序列的第一个字节 - push eax的opcode
   {tmp0=1;
    for (i=0; i<5; i++)    //数组中的其它字节,使用循环检验
    if (get_byte(CA+i+1)!=rdtsc1[i]) {tmp0=0; break;}

    if (tmp0==1)
      {patch_long(CA, 0x90909090);
        patch_word(CA+4, 0x9090);
        return;}}

 if (cb1==0x52)
   {tmp0=1;
     for (i=0; i<4; i++)
     if (get_byte(CA+i+1)!=rdtsc2[i]) {tmp0=0; break;}

     if (tmp0==1)
       {patch_long(CA, 0x90909090);
         patch_word(CA+4, 0x9090);
         return;}}
};

    //现在放入前面讲过的导出结构体。
    //一定要写上extern "C",使得linker能正确找到导出结构体的名字

extern "C" plugin_t PLUGIN = {
IDP_INTERFACE_VERSION,
0,
init,
term,
run,
comment,
help,
wanted_name,
wanted_hotkey
};

        现在我们来看如何将它编译。以下是bat文件:

icl -Gz /I <SDK的include目录的路径> plugin.cpp ida.lib /link /subsystem:windows /DLL /def:plugin.def /out:exp.plw
del "<IDA目录路径>/plugins/exp.plw"
copy exp.plw "<IDA目录路径>/plugins/"
PAUSE

我已经说过,此处是以Intel C++为例的,如果用VC++的话,源代码不用改,而编译用的命令行则需要修改(不过就是把icl换成cl)。现在来详细讲一下。

-Gz告诉intel complier,默认使用stdcall规则向函数传递参数。
/I - IDA SDK的include目录的路径
plugin.cpp - plungin源代码。
ida.lib - SDK的import library,应该和源代码放入一个目录。
/link参数的后面是liner options,就不用多说了。除了def文件。因为这里已经有源代码和bat文件了,就需要生成def文件。

LIBRARY exp
EXPORTS PLUGIN

def文件指明需要导出PLUGIN结构体。一般来说,到这里就都完成了,plugin已经可以使用了,剩下的只是把它加到IDA里了。可以把它拷贝到IDA的plugins目录里。但这还不够,还需要配置一下。所有plugins的配置都保存在plugins目录下plugins.cfg文件里。通常文件的起始处是注释,后面就是plugin的配置了。为了将我们的exp.plw(Windows下的plugin的扩展名都是plw)加入进去,需要在文件末尾加入四个参数,顺序 如下:

    plugin名  文件名  热键  参数。

这里的参数就是传给run函数的,我个人觉得没什么用,所以就设为0。热键嘛,可以设为F11,好像IDA用不到这个键。这样,我们所添加的这一行就是下面这个样子的:

        expplugin    exp    F11    0

不主张在前面写一个句点加一个逗号,因为那样就成了注释。喏,一般来说可以认为,mission accomplished。剩下的就是启动IDA,打开某个文件,那个文件里要有我们前面给出的指令(比如,可以自己立马用ASM写一个),然后进行检查。如果没有问题,就按下F11键或从菜单里选择我们的plugin,这时那些指令就应该都被替换成nop了。当然,鼠标应该放在这些scrambled的指令(如果可以这样说的话)的前面,当然这些都是些垃圾指令了。到这里就真的都完成了。
        
[C] dragon
www.wasm.ru/article.php?article=idaplugin

鄙人拙译
http://greatdong.blog.edu.cn
IDA c++分析c++类结构辅助插件ida_medigate使用记录 插件使用 设置继承方面有时候会导致IDA崩溃 没法恢复成跟作者demo一模一样的情况。 阅读详情

相关推荐

IDA Pro MCP安装与配置(window10)

本文介绍了IDA Pro 9.0与Python 3.11.9环境配置及MCP服务端安装流程。主要内容包括:1)安装Python 3.11.9并配置环境变量;2)使用idapyswitch切换IDA Pro的Python路径;3)通过pip安装ida-pro-mcp插件,解决安装过程中可能出现的配置文件解析错误;4)在VS Code中配置CLine Chinese插件连接IDA MCP服务;5)演示通过CLine进行IDA分析的问答交互,如查询当前文件、分析函数等。整个过程涉及多个组件的版本匹配和环境配置,最

lywuzaijun的专栏 5420

IDA的SDK

IDA 的 SDK

qq_29947615的博客 2526

从零开始为IDA 9.x编写Python插件:新API最佳实践详解

本文详细介绍了如何从零开始为IDA 9.x编写Python插件,重点解析了新API的设计哲学与最佳实践。内容涵盖开发环境配置、基础插件框架、核心API模块解析以及高级功能实现技巧,帮助开发者快速适应IDA 9.x的模块化API设计,提升插件开发效率与稳定性。特别适合需要进行IDAPython插件迁移或开发的逆向工程师。

weixin_29092579的博客 235

[IDA Plugin] IDA插件收集

英语好的,看这里:https://github.com/onethawt/idaplugins-list随着时间的推移,我将组织插件。如果您有任何其他优秀的插件,请提交PR。我想用相应的IDA版本标记每个插件,但是我需要很长时间才能测试。如果你能帮到那里,请做。如果一个插件只是一个没有描述或文档的源代码,我不会添加它。去做 添加更多插件 分类插件 插件 3DSX Loader:用于3DSX文...

志伟入归未有时(兴业和家) 1万+

ida-plugins:我的IDA插件集

IDA插件 我的IDA Pro插件集。 安装插件 安装 。 您可以将脚本简单地放在%idafolder%\ plugins目录中,但是我建议您使用插件加载器: 以插件加载器插件为例: 它允许您通过编辑plugins.list文件来管理插件。 将plugin_loader.py放在IDA的“插件”目录中。 以管理员身份打开IDA并关闭它(因此plugins.list文件将在%idafolder%\ cfg中创建) 在此文件中添加所需插件的路径(例如c:\ ... \ reg_xref.py) 注册交叉引用 在查看反汇编时,查找寄存器的用法很有用-这就是为什么我创建了 。 只需安装插件并使用Shift-Z即可获得如下视图: 值得注意的是 ,但主要区别在于Oregami尝试分析并查找使用相同值的位置,并仅显示这些引用。 例如,在要将寄存器标记为指向结构的指针的情况下,这很有用。 我

深度学习之Pytorch---本人踩过的坑(报错总结)第十篇

深度学习之Pytorch安装时遇到的问题—本人踩过的坑(报错总结) 报错一:pip install torchvision 出现“由于目标计算机积极拒绝,无法连接”的问题 解决方案:找到自己浏览器的工具或选项,我的是火狐,具体解决方案如下图 然后找到桌面左下角,点击搜索internet,然后点击internet选项 最后回到Anaconda Prompt命令行输入pip install...

qq_41570307的博客 1914

ida 插件编写

今天搜索中无意间看到ida可以用python/idc编写插件,好奇之下就试了试。    先看一个例子:    import idaapi class myplugin_t(idaapi.plugin_t): flags = idaapi.PLUGIN_UNL comment = "This is a comment" help = "This is help"

lacoucou的专栏 4710

5分钟搞懂语义通信:如何用深度学习让AI理解你的真实意图?

本文深入解析了语义通信如何利用深度学习技术,实现从传统‘比特保真’到‘语义保真’的范式转移。通过介绍基于神经网络的端到端系统架构、编解码技术及实战案例,阐明AI如何理解并高效传递信息核心意图,为6G时代的人机交互奠定基础。

weixin_29191669的博客 266

FLARE-IDA 开发者进阶指南:如何编写自定义IDA插件的完整教程

FLARE-IDA是由FLARE团队开发的IDA Pro实用工具集,提供了丰富的插件和脚本,帮助逆向工程师更高效地进行恶意软件分析和漏洞研究。本教程将带您从零开始掌握自定义IDA插件的开发方法,通过实用示例和最佳实践,让您快速成为插件开发高手。 ## 插件开发基础:了解IDA插件结构 IDA Pro插件通常使用Python编写,遵循特定的结构规范。一个基础的IDA插件包含初始化、运行和终止三个

gitblog_00282的博客 771

开源处理器Rocket的分支预测机制研究与性能评估(二)

Rocket是基于RISC-V指令集架构的开源处理器,具有分支预测功能,其实现了GShare分支预测机制,在分析Rocket处理器分支预测处理过程、分支预测实现原理的基础上,利用模拟器进行了性能测试,并依据测试结果,对Rocket处理器分支预测参数配置给出建议。

leishangwen的专栏 5691

从OpenClaw到Hermes Agent:AI Agent实战部署与自动化工作流构建

AI Agent(智能体)作为大语言模型(LLM)的能力延伸,其核心原理在于通过工具调用(Tool Calling)与环境交互,使模型从“对话”走向“执行”。这一技术价值在于将自然语言指令转化为具体操作,实现业务流程自动化,从而提升开发与运维效率。在应用场景上,AI Agent广泛适用于自动化运维、智能客服、数据报告生成等重复性任务处理。本文聚焦于两大热门开源框架OpenClaw与Hermes Agent,深入探讨其部署配置、技能扩展及实战联调。通过结合OpenClaw的模块化扩展能力与Hermes Age

weixin_34122810的博客 506

python编写脚本实例_用python编写第一个IDA插件的实例

IDA插件是经过编译的、功能更强大的IDC脚本,与仅仅使用脚本相比,插件能够执行更加复杂的任务。与编写IDC脚本相比,python显得更为轻巧和强大,IDAPython作为IDA的一个插件,具有IDA SDK的大部分功能,能够帮助我们编写实现IDC脚本语言所有功能的python脚本。本文将以一个简单的例子开始展示如何使用python编写并安装一个IDA插件。1、编写插件文件ms...

weixin_39983554的博客 176

stm32f103c8t6的中文字库

stm32的成熟中文字库,上手即用,操作简单

nbbskk的博客 3654

python脚本编写实例-用python编写第一个IDA插件的实例

IDA插件是经过编译的、功能更强大的IDC脚本,与仅仅使用脚本相比,插件能够执行更加复杂的任务。与编写IDC脚本相比,python显得更为轻巧和强大,IDAPython作为IDA的一个插件,具有IDA SDK的大部分功能,能够帮助我们编写实现IDC脚本语言所有功能的python脚本。本文将以一个简单的例子开始展示如何使用python编写并安装一个IDA插件。1、编写插件文件msg.pyfrom i...

weixin_37988176的博客 356

C#部署YOLO三种方案深度实测:OpenCV DNN vs ONNX Runtime vs TensorRT

在工业视觉项目落地阶段,C#生态下部署YOLO模型主要有三条技术路线。很多开发者仅凭经验选型,往往在部署后期踩中性能瓶颈、兼容故障、维护成本超标的坑。本文基于工控机常见硬件配置,针对YOLOv8系列模型做控制变量实测,从推理性能、部署难度、工业稳定性、综合成本等多个维度做横向对比,给出可直接落地的选型结论。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 470

华为OD机试双机位C卷:日志排序 (Py/C/C++/Java/Js/Go)

华为OD机试双机C卷真题【日志排序】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试-日志排序。

qq_45776114的博客 1754

python编写脚本应用实例-用python编写第一个IDA插件的实例

IDA插件是经过编译的、功能更强大的IDC脚本,与仅仅使用脚本相比,插件能够执行更加复杂的任务。与编写IDC脚本相比,python显得更为轻巧和强大,IDAPython作为IDA的一个插件,具有IDA SDK的大部分功能,能够帮助我们编写实现IDC脚本语言所有功能的python脚本。本文将以一个简单的例子开始展示如何使用python编写并安装一个IDA插件。1、编写插件文件msg.pyfrom i...

weixin_39875842的博客 143

视觉媒体通信作业记录(六)端到端的视频传输系统

将采集、编码、传输、显示各模块连接起来,形成一个端到端的视频通信系统,开发一个特色模块,将其加入系统;

weixin_45774698的博客 1967

VS2010 + IDA SDK 搭建IDA Plugin开发环境

http://www.h4ck.org.cn/2011/11/vs2010-idasdk6-2-ida-plugin-development/   1. 执行菜单的File-&gt;New-&gt;Project… (Ctrl-Shift-N)打开新建工程窗口。  2. 展开左侧的Visual C++项目模板分支,然后选择右侧的Win32 Project条目,输入工程名称,然后点击确定。 ...

weixin_34228387的博客 939

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

deepseek_ai_ida_plugin开源插件,用于使用 DeepSeekAI 将函数反编译并重命名为人类可读的视图。该插件仅在 ida9 上进行了测试

deepseek_ai_ida_plugin开源插件,用于使用 DeepSeekAI 将函数反编译并重命名为人类可读的视图。该插件仅在 ida9 上进行了测试。FunctionRenamerDeepseekAI.cpp 此文件包含 Hex-Rays 反编译器的主要插件实现。它反编译当前函数,使用 DeepSeekAI 重命名变量和函数,并输出结果。

struggle2025的博客 1128

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

use IdaRub write Ida Plugin

转眼又是快半年没“耕耘”这个blog了……今天来介绍下IdaRub和rublibIdaRub : http://www.metasploit.com/users/spoonm/idarub/ rublib : http://www.the-interweb.com/serendipity/index.php?/archives/91-RubLib-0.04.html有了这两个excellent的工

Binjo's stuff 902

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

python第一个例程_用python编写第一个IDA插件的实例

IDA插件是经过编译的、功能更强大的IDC脚本,与仅仅使用脚本相比,插件能够执行更加复杂的任务。与编写IDC脚本相比,python显得更为轻巧和强大,IDAPython作为IDA的一个插件,具有IDA SDK的大部分功能,能够帮助我们编写实现IDC脚本语言所有功能的python脚本。本文将以一个简单的例子开始展示如何使用python编写并安装一个IDA插件。1、编写插件文件msg.pyfrom i...

weixin_39727336的博客 278

ida python 插件编写

一.第一步 这个是抄的 天下代码一般抄,自己从零开始写并不会 源代码是这样(pyhexraysdeob.py),一个反混淆插件 import os import ida_idaapi import ida_loader import ida_kernwin import ida_hexrays my_dirname, _ = os.path.split(__file__) setattr(ida_hexrays, "MMAT_DEOB_MAP", getattr(ida_hexrays,

JackBoy的博客 1686
上一篇: MFC的逆向工程
下一篇: 教材性质的病毒代码(ASM)
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值