学习编写x64dbg插件
2023-3-5 23:47:18 Author: MicroPest(查看原文) 阅读量:7 收藏

       有时候,缘份是件很奇怪的东西。话说,半月前,在看雪上发现一作者写的《x64dbg插件编写基础》,觉得很好。因为我不写插件,所以也没有想法,当时时只是看了看,但印象很深。

        今天搜索资料时,发现我的硬盘里静静地躺着个x64dbg的插件源码,看文件生成时间是2021年,是不是很巧了?既然碰上了,就顺便打开对照着学习一番吧。

结合作者给出的内容,作简单的笔记,梳理如下:

1、x64dbg提供的sdk包在x64dbg的pluginsdk文件夹中,要将整个pluginsdk文件夹拷贝到工程目录之下

2、配置头文件目录和lib文件的目录以及引入lib文件:

  • 在工程属性->vc++目录->外部包含目录加入pluginsdk路径

  • 在工程属性->vc++目录->库目录加入pluginsdk路径

  • 在工程属性->链接器->输入->附加依赖项中添加 x32bridge.lib和x32dbg.lib,这也是pluginsdk下唯二的两个lib。

3、涉及到的函数:

(1)主函数

BOOL WINAPI DllMain(

    _In_ HINSTANCE hinstDLL,

    _In_ DWORD     fdwReason,

    _In_ LPVOID    lpvReserved

)

{

    return TRUE;

}

(2)pluginit

pluginit函数是x64dbg插件必须导出的一个函数

 在整个函数中,要做的事件就是填充参数initStruct:

PLUG_EXPORT bool pluginit(PLUG_INITSTRUCT* initStruct)

{

    initStruct->pluginVersion = PLUGIN_VERSION;

    initStruct->sdkVersion = PLUG_SDKVERSION;

    strncpy_s(initStruct->pluginName, PLUGIN_NAME, _TRUNCATE);

    pluginHandle = initStruct->pluginHandle;

    return pluginInit(initStruct);

}

(3)plugstop和plugsetup

这两个导出函数不是必须的,但是可以在里面做一些事情:

  • plugstop:插件被移除的时候被调用,可以用来清除注册的回调和命令,清理资源

  • plugsetup:当插件初始化成功的时候调用,可以在这里添加菜单、做其他的界面相关的事情。

本例在plugsetup中添加了两个子菜单,代码如下:

PLUG_EXPORT bool plugstop()

{

    return pluginStop();

}

//Deinitialize your plugin data here (clearing menus optional).

bool pluginStop() //插件卸载时要干的事,一般是卸载回调,也就是x32dbg调用

{

    return true;

}

================

PLUG_EXPORT void plugsetup(PLUG_SETUPSTRUCT* setupStruct)

{

    hwndDlg = setupStruct->hwndDlg;

    hMenu = setupStruct->hMenu;

    hMenuDisasm = setupStruct->hMenuDisasm;

    hMenuDump = setupStruct->hMenuDump;

    hMenuStack = setupStruct->hMenuStack;

int TopHandle=_plugin_menuadd(hMenu, PLUGIN_NAME); 

//一级菜单,就是插件名,没有这句代码无法显示设置的PLUGIN_NAME,返回顶层菜单句柄,二级菜单需要这个句柄

_plugin_menuaddentry(hMenu, 0, "插件菜单中的二级菜单"); 

//插件菜单二级菜单名

int DismTopHandle=_plugin_menuadd(hMenuDisasm, PLUGIN_NAME);

//反汇编窗口的右键菜单,没有这句无法显示PLUGIN_NAME,返回顶层菜单句柄,二级菜单需要这个句柄

_plugin_menuaddentry(hMenuDisasm, 1, "反汇编窗口中的二级菜单");

//反汇编窗口右键二级菜单名

//_plugin_registercallback(pluginHandle, PLUG_CB_MENUENTRY, MyEntry) 注册事件的回调,第二个参数是类型,当出现第二个参数的类型事件的时候就调用MyEntry函数

    pluginSetup();

}

//Do GUI/Menu related things here.

void pluginSetup() 

//初始化完成以后要干的事,一般是注册插件菜单以及二级菜单

{

}

===========

void MyEntry(CBTYPE CbType, void* callbackInfo) 

//我自己的注册事件的回调

{

}

PLUG_EXPORT void CBMENUENTRY(CBTYPE cbType, PLUG_CB_MENUENTRY* info)  

//插件回调函数,就是你点了插件上面的哪个二级菜单就会调用此处,info是菜单号,由_plugin_menuaddentry的第二个参数控制

{

    //比如上面我注册的插件号是1,那么info为1的话就说明我点击了反汇编窗口的二级菜单这个功能

    int eip = Script::Register::GetEIP(); 

    //获得EIP

    int esp = Script::Register::GetESP();

    //获得ESP

    if (eip!=0 && esp!=0 )

    {

    }

}

(4)事件回调函数

当我们添加了插件的子菜单之后,要如何响应菜单的点击呢?

 导出以CB开头的函数就可以去接收到对应的事件,比如

PLUG_EXPORT void CBINITDEBUG(CBTYPE cbType, PLUG_CB_INITDEBUG* info)

{

}

PLUG_EXPORT void CBTRACEEXECUTE(CBTYPE cbType, PLUG_CB_TRACEEXECUTE* info)

{

}

参数中所用到的结构体可以在这里找到:https://help.x64dbg.com/en/latest/developers/plugins/Callbacks/index.html,只要是满足CB*的导出函数,且属于这里面的类型https://help.x64dbg.com/en/latest/developers/plugins/API/registercallback.html,应该都可以注册成功,注意函数名中不要有下划线。

4、以上举例的代码,放在如下:

链接:https://pan.baidu.com/s/1zl6JUW2eK0YNN1c7k388Ag

提取码:z6k4

5、给一个github上非常好的插件源码例子

链接:https://pan.baidu.com/s/1nP7myiOPWhnRZGUGA-H6rA

提取码:9yhp


文章来源: http://mp.weixin.qq.com/s?__biz=MjM5NDcxMDQzNA==&mid=2247487679&idx=1&sn=abee7a8b69b637a80412899fb8fe7fd6&chksm=a682c67291f54f6453fb786a507ccb7075015a8d483d85469cc920c715ad7f6fc786e21cb02a#rd
如有侵权请联系:admin#unsafe.sh