:重定向 DLL 与 minject 注入工具实战指南)
mimalloc 在 Windows 平台的动态覆盖Override重定向 DLL 与 minject 注入工具实战指南【免费下载链接】mimallocmimalloc is a compact general purpose allocator with excellent performance.项目地址: https://gitcode.com/GitHub_Trending/mi/mimallocmimalloc 是一款紧凑、通用的高性能内存分配器。本指南以仓库内 bin/readme.md 为核心系统讲解在 Windows 平台上通过mimalloc-redirect.dll动态覆盖Dynamic OverrideC 运行时分配器的完整方案从四项必备前提、运行时架构、不同 CPU 架构x64/x86/arm64/arm64ec的差异到无需重新编译即可用minject工具修补可执行文件导入表的实操方法。读完本文你将能够在大型 Windows 程序含第三方组件中可靠地把所有malloc/free调用无缝切换到 mimalloc并掌握验证与排错手段。一、为什么 Windows 上需要单独的“重定向 DLL”在 Linux/BSD 上动态覆盖通常借助LD_PRELOAD预加载共享库即可完成参见 doc/mimalloc-doc.h 中的env LD_PRELOAD/usr/lib/libmimalloc.so myprogram。但 Windows 的加载机制与 ELF 平台不同mimalloc 采用独立的mimalloc-redirect.dll重定向 DLL来实现动态覆盖它拦截所有经由动态C 运行时分配器发出的malloc/free调用包括来自其他 DLL 或第三方库的调用由于是在底层对所有分配调用进行拦截因此可以安全地用于包含大量第三方组件的大型程序核心分配逻辑仍集中在mimalloc.dll中重定向 DLL 只负责“转发”。从源码看这一行为由构建选项控制在 CMakeLists.txt 中定义了MI_WIN_REDIRECTUse redirection module (mimalloc-redirect) on Windows if compiling mimalloc as a DLL默认ON并且在 Windows 上编译 DLL 时会自动链接并拷贝对应架构的重定向 DLL见 CMakeLists.txt。因此若自行编译 mimalloc务必保持这两个选项开启MI_OVERRIDEON覆盖标准 malloc 接口默认开启见 CMakeLists.txt与MI_WIN_REDIRECTON。二、动态覆盖生效的四项必备前提要让覆盖可靠工作需同时满足以下四个要求bin/readme.md1. 使用 DLL 形式的 C 运行时库编译程序时使用/MDRelease或/MDdDebug开关即动态链接ucrtbase.dll等 CRT 运行库。只有分配调用经由动态 CRT重定向 DLL 才能拦截。2. 显式链接mimalloc.lib导出库并确保 DLL 在运行时被加载程序需要与mimalloc.dll对应的导入库mimalloc.lib显式链接其中包含 mimalloc 的全部功能。为了让mimalloc.dll在运行时确实被加载最简单的方式是在main函数中插入一次对 mimalloc API 的调用例如mi_version()也可以在链接器上使用/include:mi_version开关或在某个源文件中写#pragma comment(linker, /include:mi_version)具体可参考mimalloc-test-override工程对应 test/CMakeLists.txt 中的mimalloc-test-override测试目标的用法。3. 将mimalloc-redirect.dll放在与主mimalloc.dll相同的目录重定向 DLL 是mimalloc.dll的依赖项运行时必须与主 DLL 同目录。它保证所有对 CRTmallocAPI 的调用都被重定向到mimalloc.dll中的 mimalloc 函数。4. 尽量让mimalloc.dll出现在最终可执行文件导入表的靠前位置导入表越靠前越能尽早拦截潜在的分配调用。可用minject -l exe检查导入表顺序。仓库中已预置了各架构的重定向 DLL 及其导入库位于 bin/ 目录mimalloc-redirect.dll、mimalloc-redirect32.dll、mimalloc-redirect-arm64.dll、mimalloc-redirect-arm64ec.dll以及对应的.lib文件。架构流程图┌──────────────┐ │ Your Program │ └────┬─────────┘ │ │ mi_version() ┌───────────────┐ ┌───────────────────────┐ ├──────────────►│ mimalloc.dll ├────►│ mimalloc-redirect.dll │ │ └──────┬────────┘ └───────────────────────┘ │ ▼ │ malloc() etc. ┌──────────────┐ ├──────────────►│ ucrtbase.dll │ │ └──────────────┘ │ │ └──────────────► ...图中Your Program通过显式调用mi_version()等 API 触发并确保mimalloc.dll加载mimalloc-redirect.dll与mimalloc.dll协同工作同时程序原有的malloc()调用经由ucrtbase.dll的 CRT 分配器也会被重定向到 mimalloc从而实现全量接管。三、C 项目的补充建议同时覆盖 new/delete为了在 Windows 上的 C 程序中获得最佳性能文档还建议一并覆盖new/delete操作符在项目中仅一个源文件里包含 include/mimalloc-new-delete.h 即可注意“只在一个源文件包含一次”这个约束避免重复定义。该头文件会把全局operator new/operator delete重定向到 mimalloc 实现。如果需要以头文件宏替换的方式做静态重定向适用于所有源码都在你控制之下的项目仓库还提供了 include/mimalloc-override.h它将malloc、calloc、realloc、free、strdup、aligned_alloc、posix_memalign以及大量 Windows/MSVC 扩展如_expand、_msize、_aligned_malloc系列统一映射到mi_*函数。四、运行时验证与开关MIMALLOC_VERBOSE 与 MIMALLOC_DISABLE_REDIRECT动态覆盖是否生效可以借助环境变量确认bin/readme.mdMIMALLOC_VERBOSE1程序启动时输出 verbose 信息含统计用于确认 mimalloc 是否被成功重定向。这也是 doc/mimalloc-doc.h 中列出的标准验证手段对应MIMALLOC_SHOW_STATS1可显示详细的分配统计报表。MIMALLOC_DISABLE_REDIRECT1在运行时禁用动态覆盖可用来做 A/B 对比或排查问题。在测试工程中也能看到相关用法test/main-override.cpp通过_dupenv_s读取MIMALLOC_VERBOSE环境变量来辅助验证覆盖是否生效见 test/main-override.cpp。五、不同 CPU 架构下的重定向 DLL 选择程序总是链接mimalloc.dll但不同平台需要选用对应的重定向 DLLbin/readme.md架构使用的重定向 DLL适用场景x64mimalloc-redirect.dll常规 64 位 Windows 程序x86mimalloc-redirect32.dll较旧的 32 位 Windows 程序arm64mimalloc-redirect-arm64.dll原生 Windows arm64 程序arm64ecmimalloc-redirect-arm64ec.dllWindows arm64 上的“模拟兼容”emulation compatible模式关于 arm64ec 的特殊处理[arm64ec] ABI 是 Windows arm64 上的模拟兼容模式。由于 C 运行时始终使用arm64ec因此无法直接在 Windows arm64 上用 x64 的 mimalloc 覆盖来模拟运行 x64 代码。正确做法分三步按正常方式将程序编译为 x64并照常与 x64 的mimalloc.lib导出库链接单独以arm64ec模式编译mimalloc.dll然后覆盖之前x64 的mimalloc.dll——Windows 加载器能够混用 arm64ec 与 x64 代码使用mimalloc-redirect-arm64ec.dll以匹配新的 arm64ecmimalloc.dll。主程序本身保持不变可以是纯 x64也可以包含更多 arm64ec 模块。运行时arm64ec 版mimalloc.dll以原生 arm64 指令执行而程序其余部分以模拟的 x64 方式运行。六、minject免重编译修补可执行文件现实场景中我们往往无法重新链接可执行文件也无法保证mimalloc.dll排在导入表首位。但许多情况下只要程序动态链接了 C 运行时ucrtbase.dll就可以不打补丁重编译直接修补现有可执行文件把mimalloc.dll加入导入表并将mimalloc-redirect.dll放在同一目录。除了用 CFF Explorer 之类的图形工具手工修补外仓库在 bin/ 目录下提供了命令行工具minject完成同样的事情。minject 命令参考运行minject --help查看全部选项bin/readme.md minject --help minject: Injects the mimalloc dll into the import table of a 64-bit executable, and/or ensures that it comes first in het import table. usage: minject [options] exe options: -h --help show this help -v --verbose be verbose -l --list only list imported modules -i --inplace update the exe in-place (make sure there is a backup!) -f --force always overwrite without prompting --postfixp use p as a postfix to the mimalloc dll. e.g. use --postfixdebug to link with mimalloc-debug.dll notes: Without --inplace an injected exe is generated with the same name ending in -mi. Ensure mimalloc-redirect.dll is in the same folder as the mimalloc dll. examples: minject --list myprogram.exe minject --force --inplace myprogram.exe要点说明不带--inplace时注入后的可执行文件会以原名加-mi后缀生成新文件原文件保持不变带--inplace则直接原地更新务必先备份-l/--list只列出导入模块即前文提到的“检查mimalloc.dll在导入表位置”的方法--postfixp可为 mimalloc DLL 指定后缀例如--postfixdebug对应链接mimalloc-debug.dll注入后仍需确保mimalloc-redirect.dll与 mimalloc DLL 同目录。对于 32 位 x86 二进制文件使用minject32arm64 二进制文件使用minject-arm64bin/readme.md它们已随仓库预编译在 bin/ 目录中minject.exe、minject32.exe、minject-arm64.exe。七、Windows 发布包与二进制分发仓库提供了发布打包脚本 bin/bundle.bat以及配套的 bin/bundle.sh它会针对 x64、x86、arm64、arm64ec 四种架构分别构建 debug/release/secure 三种配置通过-A x64、-A Win32、-A ARM64、-A Arm64EC等 CMake 参数与MI_SECUREON、MI_OPT_ARCHON选项运行测试后安装到统一的前缀目录并把对应架构的minject*.exe复制进bin/目录后打 tar 包。这也解释了为什么 bin/ 中会同时存在四个架构的重定向 DLL 与三个 minject 可执行文件——它们正是各架构 Windows 发布版的组成部分。若需为 arm64ec 构建还需参考 CMakeLists.txt 中的说明配合mimalloc-redirect-arm64ec.dll使用。八、总结与排错速查Windows 动态覆盖的整体流程可归纳为程序使用/MD或/MDd动态 CRT 编译显式链接mimalloc.lib并通过mi_version()或/include:mi_version确保mimalloc.dll被加载将对应架构的mimalloc-redirect*.dll与mimalloc.dll放同目录用minject -l exe检查导入表位置必要时用minject或 CFF Explorer 修补运行前设置MIMALLOC_VERBOSE1验证重定向是否成功。常见问题定位覆盖未生效时优先检查是否满足上述四项前提、mimalloc-redirect*.dll架构是否匹配、是否设置了MIMALLOC_DISABLE_REDIRECT1意外禁用了重定向确认无误后通过MIMALLOC_VERBOSE1观察启动输出即可判断 mimalloc 是否接管了分配。对于无法重链接的既有程序minject 系列工具提供了一条无需重新编译即可接入 mimalloc 的便捷路径。【免费下载链接】mimallocmimalloc is a compact general purpose allocator with excellent performance.项目地址: https://gitcode.com/GitHub_Trending/mi/mimalloc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考