[笔记]Windows核心编程《二十》DLL的高级操作技术(一)

简介: [笔记]Windows核心编程《二十》DLL的高级操作技术

前言

本章主要讲 与DLL相关的各种操作方法。大多数应用程序不一定需要这些方法,但是它们是非常有用的,所以应该对它们有所了解。

一、DLL模块的显式加载和符号链接

如果线程需要调用D L L模块中的函数,那么D L L的文件映像必须映射到调用线程的进程的。

创造DLL:

1)建立带有输出原型/结构/符号的头文件。

2)建立实现输出函数/变量的 C/C++源文件。

3)编译器为每个 C/C++源文件生成.obj模块。

4)链接程序将生成DLL的 .obj模块链接起来。

5)如果至少输出一个函数/变量,那么链接程序也生成 .lib 文件。

创造EXE:

6)建立带有输入原型/结构/符号的头文件(视情况而定)。

7)建立不引用输入函数/变量的 C/C++源文件。

8)编译器为每个C/C++源文件生成 .obj源文件。

9)链接程序将各个 .obj模块链接起来,生成 .exe文件。

注:DLL的lib文件是不需要的,因为并不直接引用输出符号。.exe 文件不包含输入表。

运行应用程序:

10)加载程序为 .exe创建模块地址空进程的主线程开始执行;应用程序启动运行。

显式加载DLL:

11)一个线程调用LoadLibrary

(Ex)函数,将DLL加载到进程的地址空间这时线程可以调用GetProcAddress以便间接引用DLL的输出符号。

加载DLL方法:

  • 隐式加载:让应用程序的源代码只引用 D L L中包含的符号。这样,当应用程序启动运行时,加载程序就能够隐含加载(和链接)需要的DLL。
  • 显示加载: 在应用程序运行时让应用程序显式加载需要的 D L L并且显式链接到需要的输出符号。换句话说,当应用程序运行时,它里面的线程能够决定它是否要调用 DLL中的函数。该线程可以将D L L显式加载到进程的地址空间,获得 D L L中包含的函数的虚拟内存地址,然后使用该内存地址调用该函数。

显示加载这种方法的优点是一切操作都是在应用程序运行时进行的。

1.1 显式加载DLL模块 LoadLibrary

进程中的线程都可以决定将一个 D L L映射到进程的地址空间,方法是调用下面两个函数中的一个:

HINSTANCE LoadLibrary(PCTSTR pSzDLLPathName);
HINSTANCE LoadLibraryEx(
  PCTSTR pSzDLLPathName,
  HANDLE hF1le,
  DWORD dwF1ags 
);

作用:这两个函数均用于找出用户系统上的文件映像(使用上一章中介绍的搜索算法),并设法将D L L的文件映像映射到调用进程的地址空间中。

pSzDLLPathName:加载的dll文件的路径。

HINSTANCE:用于标识文件映像映射到的虚拟内存地址。如果DLL不能被映射到进程的地址空间,则返回 NULL。若要了解关于错误的详细信息,可以调用GetLastError。

hFile:保留供将来使用,现在必须是 NULL。

dwFlags:必须将它设置为 0 。

或者设置DONT_RESOLVE_DLL_REFERENCES、

LOAD_LIBRARY_AS_DATAFILE 和LOAD_WITH_ALTERED_SEARCH_PATH等标志的一个组合。

DONT_RESOLVE_DLL_REFERENCES

用于告诉系统将D L L映射到调用进程的地址空间中。

通常情况下,当DLL被映射到进程的地址空间中时,系统要调用 DLL中的一个特殊函数,即 DllMain(本章后面介绍)。该函数用于对 D L L进行初始化。

作用:

  1. DONT_RESOLVE_DLL_REFERENCES标志使系统不必调用DllMain函数就能映射文件映像。
  2. 当 DONT_RESOLVE_DLL_REFERENCES标志被设定时,系统并不自动将该DLL依赖的其他的DLL加载到进程的地址空间中。

LOAD_LIBRARY_AS_DATAFILE

系统只是将D L L映射到进程的地址空间中,就像它是数据文件一样。系统并不花费额外的时间来准备执行文件中的任何代码。

当一个 D L L被映射到进程的地址空间中时,系统要查看D L L中的某些信息,以确定应该将哪些页面保护属性赋予文件的不同的节。如果设定了LOAD_LIBRARY_AS_DATAFILE标志,系统将以它要执行文件中的代码时的同样方式来设置页面保护属性。

由于下面几个原因,该标志是非常有用的:

  • 加载只有资源没有函数的DLL时: 首先,如果有一个 D L L(它只包含资源,但不包含函数),那么可以设定这个标志,使 DLL的文件映像能够映射到进程的地址空间中。
  • 调用加载资源的函数: 然后可以在调用加载资源的函数时,使用LoadLibraryEx函数返回的HINSTANCE值。
  • 加载EXE访问其中资源: 通常情况下,加载一个.exe文件,就能够启动一个新进程,但是也可以使用 LoadLibraryEx函数将.exe文件的映像映射到进程的地址空间中。借助映射的 .exe文件的HINSTANCE值,就能够访问文件中的资源。
    由于.exe文件没有DllMain函数,因此,当调用LoadLibraryEx来加载一个.exe文件时,必须设定LOAD_LIBRARY_AS_DATAFILE标志。

LOAD_WITH_ALTERED_SEARCH_PATH

用于改变 LoadLibraryEx用来查找特定的DLL文件时使用的搜索算法。

如果设定了该标志,那么LoadLibraryEx 函数就按照下面的顺序来搜索文件:

  1. pszDLLPathName参数中设定的目录。
  2. 进程的当前目录。
  3. Windows的系统目录。
  4. Windows目录。
  5. PATH环境变量中列出的目录。


相关文章
|
1月前
|
Windows
Windows 命令提示符(CMD)操作(七):扩展命令和功能
Windows 命令提示符(CMD)操作(七):扩展命令和功能
50 0
|
1月前
|
存储 数据安全/隐私保护 Windows
Windows 命令提示符(CMD)操作(五):磁盘和磁盘操作
Windows 命令提示符(CMD)操作(五):磁盘和磁盘操作
127 0
|
1月前
|
数据安全/隐私保护 Windows
Windows 命令提示符(CMD)操作(三):用户管理
Windows 命令提示符(CMD)操作(三):用户管理
54 0
|
1月前
|
存储 缓存 数据安全/隐私保护
Windows 命令提示符(CMD)操作(二):系统信息和管理
Windows 命令提示符(CMD)操作(二):系统信息和管理
45 0
|
20天前
|
人工智能 机器人 C++
【C++/Python】Windows用Swig实现C++调用Python(史上最简单详细,80岁看了都会操作)
【C++/Python】Windows用Swig实现C++调用Python(史上最简单详细,80岁看了都会操作)
|
2天前
|
API C++ Windows
windows编程入门_链接错误的配置
windows编程入门_链接错误的配置
8 0
|
1月前
|
安全 数据安全/隐私保护 Windows
Windows 命令提示符(CDM)操作(六):安全和权限
Windows 命令提示符(CDM)操作(六):安全和权限
30 0
|
1月前
|
缓存 网络协议 Unix
Windows 命令提示符(CMD)操作(四):网络通信
Windows 命令提示符(CMD)操作(四):网络通信
64 0
|
1月前
|
Windows
Windows 命令提示符(CMD)操作(一):文件和目录管理
Windows 命令提示符(CMD)操作(一):文件和目录管理
42 0
|
2月前
|
Windows
火山中文编程 -- 第一个windows程序
火山中文编程 -- 第一个windows程序
12 0