WinObjEx64插件开发实战:从零构建自定义Windows工具

【免费下载链接】WinObjEx64 Windows Object Explorer 64-bit 【免费下载链接】WinObjEx64 项目地址: https://gitcode.com/gh_mirrors/wi/WinObjEx64

WinObjEx64是一款强大的Windows Object Explorer 64-bit工具,通过插件系统可以扩展其功能,满足个性化需求。本文将带您从零开始,掌握WinObjEx64插件开发的完整流程,打造专属于您的Windows系统工具。

准备工作:搭建开发环境

在开始插件开发前,需要准备以下环境和工具:

  1. 获取源码:通过以下命令克隆WinObjEx64项目

    git clone https://gitcode.com/gh_mirrors/wi/WinObjEx64
    
  2. 开发工具:推荐使用Visual Studio 2022(支持v143平台工具集)

  3. 项目结构:插件开发主要涉及以下目录

插件基础:理解核心结构

WinObjEx64插件系统基于C语言开发,所有插件都需要遵循统一的接口规范。核心结构定义在plugin_def.h中,主要包含以下关键部分:

插件类型与状态

WinObjEx64支持两种插件类型:

  • DefaultPlugin:通用插件,显示在主菜单的"Plugins"下
  • ContextPlugin:特定对象类型的上下文插件,在右键菜单中显示

插件有四种状态:PluginInitialization(初始化)、PluginStopped(已停止)、PluginRunning(运行中)和PluginError(错误)。

核心数据结构

typedef struct _WINOBJEX_PLUGIN {
    BOOLEAN NeedAdmin;                  // 是否需要管理员权限
    BOOLEAN NeedDriver;                 // 是否需要驱动支持
    BOOLEAN SupportWine;                // 是否支持Wine环境
    BOOLEAN SupportMultipleInstances;   // 是否支持多实例
    WINOBJEX_PLUGIN_TYPE Type;          // 插件类型
    WINOBJEX_PLUGIN_STATE State;        // 插件状态
    WORD MajorVersion;                  // 主版本号
    WORD MinorVersion;                  // 次版本号
    ULONG RequiredPluginSystemVersion;  // 所需插件系统版本
    WCHAR Name[MAX_PLUGIN_NAME];        // 插件名称
    WCHAR Authors[MAX_AUTHORS_NAME];    // 作者名称
    WCHAR Description[MAX_PLUGIN_DESCRIPTION]; // 插件描述
    pfnStartPlugin StartPlugin;         // 启动插件回调
    pfnStopPlugin StopPlugin;           // 停止插件回调
    // 其他回调函数...
} WINOBJEX_PLUGIN, * PWINOBJEX_PLUGIN;

实战开发:创建第一个插件

下面我们将通过改造ExamplePlugin,创建一个简单的"系统信息查看器"插件。

步骤1:创建项目结构

复制ExamplePlugin目录并命名为SystemInfoPlugin:

cd Source/Plugins
cp -r ExamplePlugin SystemInfoPlugin

修改项目文件名称:

  • ExamplePlugin.vcxproj → SystemInfoPlugin.vcxproj
  • ExamplePlugin.vcxproj.filters → SystemInfoPlugin.vcxproj.filters

步骤2:实现插件初始化函数

插件入口点是PluginInit函数,负责设置插件基本信息和回调函数。修改main.c中的PluginInit函数:

BOOLEAN CALLBACK PluginInit(
    _Inout_ PWINOBJEX_PLUGIN PluginData
)
{
    if (g_Plugin)
        return FALSE;

    __try {
        StringCbCopy(PluginData->Name, sizeof(PluginData->Name), TEXT("System Info Plugin"));
        StringCbCopy(PluginData->Authors, sizeof(PluginData->Authors), TEXT("Your Name"));
        StringCbCopy(PluginData->Description, sizeof(PluginData->Description),
            TEXT("Displays detailed system information"));
        
        PluginData->RequiredPluginSystemVersion = WOBJ_PLUGIN_SYSTEM_VERSION;
        PluginData->StartPlugin = (pfnStartPlugin)&StartPlugin;
        PluginData->StopPlugin = (pfnStopPlugin)&StopPlugin;
        
        PluginData->NeedAdmin = TRUE;  // 需要管理员权限
        PluginData->SupportWine = FALSE;
        PluginData->NeedDriver = FALSE;
        
        PluginData->MajorVersion = 1;
        PluginData->MinorVersion = 0;
        PluginData->Type = DefaultPlugin;

        g_Plugin = PluginData;
        return TRUE;
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
        DbgPrint("PluginInit exception thrown %lx\r\n", GetExceptionCode());
        return FALSE;
    }
}

步骤3:实现功能逻辑

修改StartPlugin函数,实现系统信息收集和显示:

NTSTATUS CALLBACK StartPlugin(
    _In_ PWINOBJEX_PARAM_BLOCK ParamBlock
)
{
    DWORD ThreadId;
    NTSTATUS Status;
    WINOBJEX_PLUGIN_STATE State = PluginInitialization;

    RtlCopyMemory(&g_ParamBlock, ParamBlock, sizeof(WINOBJEX_PARAM_BLOCK));
    InterlockedExchange((PLONG)&m_PluginState, PLUGIN_RUNNING);
    
    // 创建工作线程
    g_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)PluginThread, 
                            (PVOID)NULL, 0, &ThreadId);
    if (g_hThread) {
        Status = STATUS_SUCCESS;
        State = PluginRunning;
    }
    else {
        Status = STATUS_UNSUCCESSFUL;
        State = PluginError;
    }

    if (g_Plugin->StateChangeCallback)
        g_Plugin->StateChangeCallback(g_Plugin, State, NULL);

    return Status;
}

实现线程函数,收集并显示系统信息:

DWORD WINAPI PluginThread(_In_ PVOID Parameter)
{
    UNREFERENCED_PARAMETER(Parameter);
    WCHAR infoBuffer[1024];
    RTL_OSVERSIONINFOW* osInfo = &g_ParamBlock.Version;

    StringCbPrintf(infoBuffer, sizeof(infoBuffer), 
        TEXT("Windows Version: %u.%u.%u\nBuild Number: %u\nSystem Range Start: 0x%p"),
        osInfo->dwMajorVersion, osInfo->dwMinorVersion, osInfo->dwBuildNumber,
        osInfo->dwBuildNumber, (PVOID)g_ParamBlock.SystemRangeStart);

    MessageBox(g_ParamBlock.ParentWindow, infoBuffer, TEXT("System Information"), MB_ICONINFORMATION);
    InterlockedExchange((PLONG)&m_PluginState, PLUGIN_STOP);

    if (g_Plugin->StateChangeCallback)
        g_Plugin->StateChangeCallback(g_Plugin, PluginStopped, NULL);

    ExitThread(0);
}

步骤4:配置导出文件

确保export.def文件正确导出PluginInit函数:

EXPORTS
PluginInit

步骤5:修改项目配置

编辑SystemInfoPlugin.vcxproj文件,更新项目GUID和名称:

<ProjectGuid>{新的GUID}</ProjectGuid>
<RootNamespace>SystemInfoPlugin</RootNamespace>
<ProjectName>SystemInfoPlugin</ProjectName>

编译与测试插件

编译插件

  1. 打开解决方案:WinObjEx64_Plugins.sln
  2. 选择"Release|x64"配置
  3. 右键点击SystemInfoPlugin项目,选择"生成"

编译成功后,插件DLL将输出到:Source/Plugins/SystemInfoPlugin/output/x64/Release/bin/SystemInfoPlugin.dll

部署插件

将编译好的DLL复制到WinObjEx64的插件目录:

cp Source/Plugins/SystemInfoPlugin/output/x64/Release/bin/SystemInfoPlugin.dll Compiled/plugins/

测试插件

启动WinObjEx64主程序:Compiled/WinObjEx64.exe

WinObjEx64主界面 WinObjEx64主界面,显示已安装的插件

在菜单栏中选择"Plugins" → "System Info Plugin",您将看到系统信息对话框:

系统信息插件运行效果 系统信息插件显示Windows版本和系统范围起始地址

高级开发:插件类型与交互

上下文插件开发

上下文插件与特定对象类型关联,在用户右键点击该类型对象时显示。要创建上下文插件,需修改插件类型和支持的对象ID:

PluginData->Type = ContextPlugin;
// 支持进程和线程对象
PluginData->SupportedObjectsIds[0] = ObjectTypeProcess;  // 26
PluginData->SupportedObjectsIds[1] = ObjectTypeThread;   // 30

与主程序交互

插件可以通过WINOBJEX_PARAM_BLOCK结构与主程序交互,获取系统信息或调用核心功能:

// 读取系统内存
g_ParamBlock.ReadSystemMemoryEx(Address, Buffer, BufferSize, &BytesRead);

// 获取指令长度
UCHAR length = g_ParamBlock.GetInstructionLength(ptrCode, &flags);

// 打开命名对象
NTSTATUS status = g_ParamBlock.OpenNamedObjectByType(&hObj, TypeIndex, &dir, &name, access);

调试与部署

调试插件

  1. 在Visual Studio中,右键点击项目 → "属性" → "调试"
  2. 设置"命令"为WinObjEx64.exe路径:$(SolutionDir)..\Compiled\WinObjEx64.exe
  3. 设置"工作目录"为:$(SolutionDir)..\Compiled
  4. 按F5启动调试

发布插件

发布插件时,建议提供:

  • 插件DLL文件
  • 插件说明文档
  • 版本信息和更新日志

将插件放置到Compiled/plugins/目录下,WinObjEx64会自动识别并加载。

总结与扩展

通过本文的学习,您已经掌握了WinObjEx64插件开发的基础知识和流程。以下是一些扩展方向:

  1. 硬件信息插件:利用WMI或直接读取硬件寄存器,显示CPU、内存等硬件信息
  2. 进程分析插件:分析进程句柄、模块和线程信息,辅助系统调试
  3. 注册表监控插件:监控注册表关键路径的修改,记录变更历史

WinObjEx64提供了丰富的系统信息访问接口,结合您的创意,可以开发出各种实用的系统工具。查看现有插件如Source/Plugins/ApiSetView/Source/Plugins/Sonar/,获取更多高级功能实现灵感。

WinObjEx64插件架构 WinObjEx64插件系统架构示意图

现在就开始您的插件开发之旅,打造属于自己的Windows系统工具吧!

【免费下载链接】WinObjEx64 Windows Object Explorer 64-bit 【免费下载链接】WinObjEx64 项目地址: https://gitcode.com/gh_mirrors/wi/WinObjEx64

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐