C++如何获取当前运行程序的DLL/SO加载基址

落墨小哥_8147

落墨小哥_8147

2026-06-11

441人浏览

原创

getmodulehandle(null)在dll内部返回的是主模块(exe)基址,而非当前dll基址;正确方法是使用dllmain入参hinstdll或getmodulehandleex(get_module_handle_ex_flag_from_address, &some_func_in_dll, &hmod)。

c++如何获取当前运行程序的dll/so加载基址

Windows下用GetModuleHandle获取DLL基址

在DLL内部想知道自己被加载到哪个地址,最直接的方式是调用 GetModuleHandle(NULL) ——但这返回的是主模块(EXE)基址,不是当前DLL的。正确做法是传入 NULL 以外的参数:对DLL自身,用 GetModuleHandle(L"your.dll");更稳妥的是在DLL入口点(DllMain)里用入参 hinstDLL,它就是该DLL的加载基址。

常见错误是硬编码DLL名或依赖当前目录——路径无关,只认模块名(不含路径,不区分大小写),且必须确保该DLL已由系统加载(比如通过 LoadLibrary 显式加载,或作为依赖被自动解析)。若模块名拼错或尚未加载,GetModuleHandle 返回 NULL。

  • GetModuleHandle 不增加引用计数,安全但不可用于后续 FreeLibrary
  • 若需跨线程稳定使用,建议在 DllMain 中保存 hinstDLL 到全局变量
  • 调试时可用 GetModuleInformation 配合 GetModuleHandle 查看实际大小和入口点

Linux下用dladdr获取SO基址

Linux没有“模块句柄”概念,但 dladdr 能根据任意函数地址反查所在共享库信息。典型用法:在SO内定义一个导出函数(如 void get_self_base() {}),然后调用 dladdr((void*)&get_self_base, &info),info.dli_fbase 就是该SO的加载基址。

注意:dladdr 依赖glibc的符号表和动态链接器元数据,若SO被 strip 过且无调试段,可能失效;另外,它查的是包含该地址的“第一个”映射区域,对同一SO多个加载实例(如 RTLD_LOCAL 多次加载)不保证唯一性。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载
  • 必须链接 -ldl,且运行时不能禁用动态链接器(如 LD_PRELOAD 干扰可能导致 dladdr 返回错误基址)
  • info.dli_fname 是绝对路径,可用于验证是否为预期SO
  • 避免传入栈地址或全局变量地址——它们可能落在其他映射段(如 .data 或 .bss),导致查到主程序而非SO

跨平台方案:编译期确定相对偏移

如果只是需要计算模块内某符号相对于基址的偏移(比如实现重定位或patch),比运行时查基址更可靠的做法是:在编译时把目标符号地址减去模块起始地址(即 &symbol - (uintptr_t)&__executable_start),但 __executable_start 在SO中不可用。可行替代是定义一个节(section)起始符号:

#ifdef _WIN32
#pragma section(".mybase", read)
__declspec(allocate(".mybase")) char mybase_marker;
#else
__attribute__((section(".mybase"))) char mybase_marker;
#endif

然后用 (uintptr_t)&mybase_marker 当作模块逻辑基址——它实际是该节在内存中的地址,对DLL/SO都有效,且无需API调用。

  • 该方式不依赖运行时环境,但要求链接器保留该节(MSVC默认保留,GCC需加 -Wl,--no-as-needed 防优化掉)
  • 不同构建配置(PIE/非PIE、ASLR开启与否)下,该地址仍是有效偏移基准
  • 不能直接当“加载基址”用于外部重定位,仅适用于模块内部符号寻址

容易忽略的ASLR与重定位影响

现代系统默认启用ASLR,意味着每次加载基址都不同。单纯获取基址没意义,除非你打算做运行时patch或手动解析重定位表。而真正需要基址的场景(如HOOK、插桩、自修改代码),往往还要处理重定位:Windows DLL有重定位表(.reloc),Linux SO若为PIE则也有类似机制。直接硬编码偏移会失败。

例如,用 GetModuleHandle 拿到基址后,若想 patch 某个函数,必须先确认该函数所在页是否可写(VirtualProtect)、是否已被重定位过(否则跳转地址还是原始值);Linux下还需检查 /proc/self/maps 确认该SO映射权限(r-xp 表示不可写)。

  • ASLR开启时,GetModuleHandle 和 dladdr 返回的确实是随机基址,但模块内所有符号偏移固定
  • 调试器附加时可能禁用ASLR,导致基址看似“固定”,上线后行为突变
  • 64位下指针宽度变化、符号可见性(__attribute__((visibility("hidden"))))也会影响 dladdr 查找结果

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++和c语言的区别有哪些
c++和c语言的区别有哪些

c++和c语言的区别:1、面向对象编程(OOP)支持不同;2、新增特性不同;3、标准库不同;4、编译方式不同;5、命名空间不同等等。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.14

2248

9

c++和python学习顺序推荐
c++和python学习顺序推荐

一般建议先学习C++,再学习Python,因为这样可以逐步从较为底层的编程语言向更高级的语言过渡。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

1019

6

python和c++学习性价比分析
python和c++学习性价比分析

Python易于学习,广泛应用于Web开发、数据科学和人工智能等领域,但性能较低。C语言性能高,适用于对性能要求较高的场景,如游戏开发和系统编程,但学习曲线陡峭,错误处理复杂。想了解更多python的相关内容,可以阅读本专题下面的文章。

2024.03.14

427

5

c语言和c++一样吗
c语言和c++一样吗

c语言和c++是两种不同的编程语言,虽然有相似之处,但存在显著差异。c语言专注于过程式编程和系统级开发,以简洁、高效著称。c++作为c语言的超集,引入了面向对象编程,增强了代码组织和管理能力,但学习曲线也更陡峭。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

327

5

c语言和c++先学哪个好
c语言和c++先学哪个好

初学者选择学习c语言还是c++语言,需要根据个人学习目标、背景以及编程兴趣和预期应用方向来决定。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

406

5

c语言和c++的区别和联系
c语言和c++的区别和联系

c语言和c++是计算机科学领域应用广泛的编程语言。虽然它们有着相似的基础,但它们在语言类型、语法功能和内存管理方面存在着显著差异。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.03.14

580

5

c++软件中文更改教程
c++软件中文更改教程

对于 ide,可通过打开设置,找到语言设置,选择中文,并保存更改。对于非 ide 应用程序,可查找设置或选项,选择语言设置,更改为中文,并保存更改。想了解更多c++的相关内容,可以阅读本专题下面的文章。

2024.03.21

1409

9

python和java和c++学习性价比分析
python和java和c++学习性价比分析

Python以其易学性、丰富的库和活跃的社区而著称,适合数据科学、人工智能和Web开发。Java以其跨平台性、企业级应用开发和Android应用开发而闻名。C++以其底层控制能力、高效性能和游戏开发而著称。选择哪种语言取决于个人兴趣、职业方向和特定需求。想了解更多python和java和c++的相关内容,可以阅读本专题下面的文章。

2024.03.22

1217

7

c++和c语言学习顺序推荐
c++和c语言学习顺序推荐

对于初学者,建议先学习C语言,掌握编程基础后再转入C++,便于理解面向对象编程概念。有编程经验者可直接学习C++,快速接触高级编程技术。想了解更多c++和c语言的相关内容,可以阅读本专题下面的文章。

2024.03.25

1325

9

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习