第十九章 DLL基础
来源:互联网 发布:全面战争mac 编辑:程序博客网 时间:2024/04/29 02:57
一、目的
在应用程序调用DLL中的函数之前、必须把该DLL映射到进程的地址空间中。分两种方式:隐式链接和显示运行时链接。
二、隐式链接
1、DLL模块显式声明需要导出的函数和变量(dllexport)
2、DLL模块根据导出的内容生成导出段
rodinal(函数编号:GetProcAddress可以用此得到函数地址)
hint(索引:便于查找提高性能)
RVA(相对地址:DLL基地址确定后,加上此地址就是函数or变量进程地址空间中的地址了)
name(函数名称:GetProcAddress可以用此得到函数地址)
3、DLL同时在链接阶段生成.lib文件,里面仅仅包含dll导出的符号,用于链接可执行文件时确定导入符号源自哪个DLL
(注:DLL在导出函数时会对函数进行重命名,如果不想改编函数名,有两个办法
1、创建.def文件,包含导出函数名即可;
2、利用如#pragma comment(linker,"/export:MyFunc=_MyFunc@8") 导出函数名
)
4、可执行文件或者其他DLL包含DLL头文件(此时头文件被声明为dllimport),引用导出函数或者变量(可显式声明extern 或者dllimport,略微提升性能)
5、可执行文件或者DLL根据引用的外部符号创建导入段;导入段包含dll名称,以及从此dll导入的符号的名称和地址。
6、启动可执行文件时 :
首先为进程创建虚拟地址空间,将可执行文件映射到地址空间;
然后扫描导入段,将其他DLL映射到地址空间;(可预生成基地址,减少DLL基地址重定位,在程序安装阶段)
最后根据DLL基地址和DLL导出段导出符号相对地址相加得到最终符号地址,修复可执行文件导入段导入符号地址。线程最终使用的就是导入符号地址;(可使用DLL绑定技术,预生成导入符号地址,在程序安装阶段)
三、显式链接
1、LoadLibrary 显式将DLL映射到地址空间中(GetModuleHandle只是获取已映射的DLL)。
2、FreeLibrary 显式卸载DLL(有时候某DLL创建了一个线程,如果该线程Free此DLL后,则FreeLibrary后面的代码就不存在了,因此有FreeLibraryAndExitThread函数)。
3、GetProcAddress 获取某DLL的一个导出函数(通过函数编号,或者是名字)。
4、DLL入口点DllMain(映射DLL时,卸载DLL时,创建线程时和销毁线程时都会进入,如果调用了DisableThreadLibraryCalls则在创建线程时和销毁线程时不会进入) 。
四、延迟载入DLL技术
1、使用/Lib:DelayImp.lib 将_delayLoadHelper2嵌入到代码中(此函数调用LoadLibrary 和GetProcAddress )。
2、使用/DelayLoad:MyDll.dll 将MyDll.dll从导入段中去掉,增加一个延迟段,对延迟载入DLL的函数的调用实际上调用的就是_delayLoadHelper2。
3、使用/Delay:unload 则可以使用_FUnloadDelayLoadedDLL2 来卸载延迟载入DLL,这样它会清空延迟段的函数地址。
4、_delayLoadHelper2 可以调用挂钩函数
五、其他
1、函数转发器:#pragma comment(linker,"/export:MyFunc=OtherDLL._MyFunc") 导出名为MyFunc的函数,但是此函数的入口点在OtherDLL中的_MyFunc
2、已知的DLL:LoadLibrary(L"SomeLib") 会通过正常规则搜索,LoadLibrary(L"SomeLib.dll") 会去掉后缀,然后在KnownDLLs 注册表项查找相同键值得到真正的DLL名称,然后在DllDirectory路径下搜索DLL,如果找不到则返回失败。
3、DLL重定位:为了强制系统优先从应用程序目录开始查找,可以在应用程序目录创建一个名为xx.exe.load的文件来告诉LoadLibrary 从此应用程序目录开始搜索。
- 第十九章:DLL基础
- 第十九章 DLL基础
- Windows核心编程 第十九章 DLL基础
- 第十九章
- 孙鑫MFC第十九讲DLL
- Windows核心编程——》第十九章 DLL的一些基本概念 (DLL Basics)
- F#入门-第二章 F#基础-第十九节 option类型
- java语言程序设计基础篇--第十九章--练习题19.1
- Java基础笔记-第十九记
- Java基础部分第十九节
- 孙鑫 第十九课 动态链接库DLL
- 第十九章 映射
- 第十九章 将来时态
- 梦里人第十九章
- 第十九章 JDBC
- 第十九章--进程通信
- 第十九章立体视觉
- 第二章第十九题
- zookeeper学习网址
- OpenGL部分知识汇总
- Workspace, notbook and DocBook
- 一个习惯的开始
- MYSQL中如何导出数据库
- 第十九章 DLL基础
- Ajax与SpringMvc交互
- OPENCV&QT之opencv编译安装
- 工作中40个最基本的规矩
- OpNET 常见操作
- 二维数组的列排序
- OC学习篇之---内存管理介绍和使用
- linux常用的一些命令(ubuntu)
- Windows不能用鼠标双击运行jar文件怎么办?