WinObjEx64插件开发实战:从零构建自定义Windows工具
WinObjEx64插件开发实战:从零构建自定义Windows工具
【免费下载链接】WinObjEx64 Windows Object Explorer 64-bit 项目地址: https://gitcode.com/gh_mirrors/wi/WinObjEx64
WinObjEx64是一款强大的Windows Object Explorer 64-bit工具,通过插件系统可以扩展其功能,满足个性化需求。本文将带您从零开始,掌握WinObjEx64插件开发的完整流程,打造专属于您的Windows系统工具。
准备工作:搭建开发环境
在开始插件开发前,需要准备以下环境和工具:
-
获取源码:通过以下命令克隆WinObjEx64项目
git clone https://gitcode.com/gh_mirrors/wi/WinObjEx64 -
开发工具:推荐使用Visual Studio 2022(支持v143平台工具集)
-
项目结构:插件开发主要涉及以下目录
- 插件定义头文件:Source/Plugins/plugin_def.h
- 示例插件:Source/Plugins/ExamplePlugin/
- 编译输出目录:Compiled/plugins/
插件基础:理解核心结构
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>
编译与测试插件
编译插件
- 打开解决方案:WinObjEx64_Plugins.sln
- 选择"Release|x64"配置
- 右键点击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
在菜单栏中选择"Plugins" → "System Info Plugin",您将看到系统信息对话框:
高级开发:插件类型与交互
上下文插件开发
上下文插件与特定对象类型关联,在用户右键点击该类型对象时显示。要创建上下文插件,需修改插件类型和支持的对象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);
调试与部署
调试插件
- 在Visual Studio中,右键点击项目 → "属性" → "调试"
- 设置"命令"为WinObjEx64.exe路径:
$(SolutionDir)..\Compiled\WinObjEx64.exe - 设置"工作目录"为:
$(SolutionDir)..\Compiled - 按F5启动调试
发布插件
发布插件时,建议提供:
- 插件DLL文件
- 插件说明文档
- 版本信息和更新日志
将插件放置到Compiled/plugins/目录下,WinObjEx64会自动识别并加载。
总结与扩展
通过本文的学习,您已经掌握了WinObjEx64插件开发的基础知识和流程。以下是一些扩展方向:
- 硬件信息插件:利用WMI或直接读取硬件寄存器,显示CPU、内存等硬件信息
- 进程分析插件:分析进程句柄、模块和线程信息,辅助系统调试
- 注册表监控插件:监控注册表关键路径的修改,记录变更历史
WinObjEx64提供了丰富的系统信息访问接口,结合您的创意,可以开发出各种实用的系统工具。查看现有插件如Source/Plugins/ApiSetView/和Source/Plugins/Sonar/,获取更多高级功能实现灵感。
现在就开始您的插件开发之旅,打造属于自己的Windows系统工具吧!
【免费下载链接】WinObjEx64 Windows Object Explorer 64-bit 项目地址: https://gitcode.com/gh_mirrors/wi/WinObjEx64
更多推荐






所有评论(0)