20.1 DLL模块的显式加载和符号链接--《Windows核心编程》
一、显式加载DLL模块使用函数 LoadLibrary/LoadLibraryEx
HINSTANCE LoadLibrary(PCTSTR pSzDLLPathName);
HINSTANCE LoadLibraryEx(
PCTSTR pSzDLLPathName,
HANDLE hF1le,
DWORD dwF1ags
);
pSzDLLPathName:加载的dll文件的路径。
hFile:保留供将来使用,现在是 NULL。
dwFlags:必须将它设置为 0 。或者设置 DONT_RESOLVE_DLL_REFERENCES、 LOAD_LIBRARY_AS_DATAFILE 和 LOAD_WITH_ALTERED_SEARCH_PATH 等标志的一个组合。
(1)DONT_RESOLVE_DLL_REFERENCES:标志使系统只需将 DLL 映射到调用进程的地址空间,而不用调用 DllMain(通常会调用)。
(2)LOAD_LIBRARY_AS_DATAFILE:系统只是将 DLL 映射到进程的地址空间中,就像它是数据文件一样。系统并不花费额外的时间来准备执行文件中的任何代码。如果不指定 LOAD_LIBRARY_AS_DATAFILE 标志,系统会认为需要执行文件中的代码,并用相应的方式来设置页面保护属性。例如使用此标志载入DLL,当对这个 DLL 调用 GetProcAddress 的时候,返回值会是 NULL,而 GetLastError 将会返回 ERROR_MOD_NOT_FOUND。
由于下面几个原因,该标志是非常有用的:
- 加载只有资源没有函数的DLL时: 首先,如果有一个DLL(它只包含资源,但不包含函数),那么可以设定这个标志,使 DLL的文件映像能够映射到进程的地址空间中。
- 调用加载资源的函数: 然后可以在调用加载资源的函数时,使用LoadLibraryEx函数返回的HINSTANCE值。
- 加载EXE访问其中资源: 通常情况下,加载一个.exe文件,就能够启动一个新进程,但是也可以使用 LoadLibraryEx函数将.exe文件的映像映射到进程的地址空间中。借助映射的 .exe文件的HINSTANCE值,就能够访问文件中的资源。由于.exe文件没有DllMain函数,因此,当调用LoadLibraryEx来加载一个.exe文件时,必须设定 LOAD_LIBRARY_AS_DATAFILE 标志。
(3)LOAD_WITH_ALTERED_SEARCH_PATH:用于改变 LoadLibraryEx用来查找特定的DLL文件时使用的搜索算法。如果设定了该标志,那么LoadLibraryEx 函数就按照下面的顺序来搜索文件:
- pszDLLPathName参数中设定的目录。
- 进程的当前目录。
- Windows的系统目录。
- Windows目录。
- PATH环境变量中列出的目录。
(4)LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE:与 LOAD_LIBRARY_AS_DATAFILE 相似,但是是以独占方式打开 DLL 文件,禁止任何其他程序在当前程序使用该 DLL 文件的时候对其修改。
(5)LOAD_LIBRARY_AS_IMAGE_RESOURCE:与 LOAD_LIBRARY_AS_DATAFILE 相似,但是载入 DLL 的时候,会对 RVA 进行修复(变成 RAW)。这样 RVA 可以直接使用,不必再根据 DLL 载入到的内存地址来对它们进行转换了。当需要对 DLL 进行解析来遍历 PE 段时,这个标志特别有用。
二、显式卸载DLL模块 FreeLibrary
BOOL FreeLibrary(HINSTANCE hinstD11);
也可以通过调用下面的函数从进程的地址空间中卸载 DLL,该函数是在Kernel32.dll中实现的:
VOID FreeLibraryAndExitThread(HINSTANCE hinstDll, DWORD dwExitCode);
微软创建 FreeLibraryAndExitThread 原因:
假定你要编写一个 DLL,当它被初次映射到进程的地址空间中时,该 D L L就创建一个线程。当该线程完成它的操作时,它通过调用FreeLibrary函数,从进程的地址空间中卸载该 DLL,并且终止运行,然后立即调用ExitThread。但是,如果线程分开调用 FreeLibrary和ExitThread,就会出现一个严重的问题。这个问题是调用FreeLibrary会立即从进程的地址空间中卸载 DLL。当调用的FreeLibrary返回时,包含对ExitThread调用的代码就不再可以使用(指DLL中函数的代码),因此线程将无法执行任何代码。这将导致访问违规,同时整个进程终止运行。
而使用此函数,FreeLibrary 返回时,下一条要执行的指令在 Kernel32.dll 中,可以继续调用 ExitThread。
关于 DLL 使用计数:只有使用计数递减至0,DLL才会从进程空间中撤销映像。
LoadLibrary和LoadLibraryEx 这两个函数用于对与特定的库相关的进程使用计数进行递增;
FreeLibrary和FreeLibraryAndExitThread这两个函数则用于对库的每个进程的使用计数进行递减。
其他函数
GetModuleHandle 函数可以根据名称返回加载的DLL的句柄(地址),当然也可以检查一个DLL是否被映射到进程的地址空间中。
GetModuleFileName 函数可以根据DLL句柄返回DLL完整路径。
20.1 DLL模块的显式加载和符号链接--《Windows核心编程》的更多相关文章
- dll显式加载与隐式加载
使用动态DLL有两种方法,一种是隐式链接,一种是显式链接,如果用loadlibrary就是显示链接,用lib就属于隐式链接. 两种方法对于你的程序调用动态库时没有任何区别,只是你在编程时,步骤是不一样 ...
- DLL动态库的创建,隐式加载和显式加载
动态库的创建 打开VS,创建如下控制台工程,工程命名为DllTest: 在弹出的对话框中选择"DLL"后单击"完成"按钮: 在工程中新建DllTest.h和Dl ...
- 《Entity Framework 6 Recipes》中文翻译系列 (28) ------ 第五章 加载实体和导航属性之测试实体是否加载与显式加载关联实体
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-11 测试实体引用或实体集合是否加载 问题 你想测试关联实体或实体集合是否已经 ...
- 【EF学习笔记08】----------加载关联表的数据 显式加载
显式加载 讲解之前,先来看一下我们的数据库结构:班级表 学生表 加载从表集合类型 //显示加载 Console.WriteLine("=========查询集合===========&quo ...
- 【DLL】动态库的创建,隐式加载和显式加载(转)
原文转自:https://blog.csdn.net/dcrmg/article/details/53437913
- Windows核心编程 第二十章 DLL的高级操作技术
第2 0章 D L L的高级操作技术 看了下这章的内容,谈不上高级,都是些常用相关,但是还是有一些细节需要注意. 20.1 DLL模块的显式加载和符号链接 如果线程需要调用D L L模块中的函数,那么 ...
- 【windows核心编程】DLL相关(1)
DLL相关的东西 1.DLL的加载方式 隐式: #pragma comment(lib, "XX.lib"); 编译器去查找名为XX.dll的DLL,除了名字相同,该DLL和该LI ...
- 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。
windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...
- RequireJS 模块的定义与加载
模块不同于传统的脚本文件,它良好地定义了一个作用域来避免全局名称空间污染.它可以显式地列出其依赖关系,并以函数(定义此模块的那个函数)参数的形式将这些依赖进行注入,而无需引用全局变量.RequireJ ...
- laravel 嵌套的渴求式加载
今天在通过需求表A查询场地类型表B,然后通过表B的场地类型id去查询表C场地类型名的时候遇到了一个小的问题. 需求表A的字段:id.user_id .name等等: 中间表B的字段:id.appeal ...
随机推荐
- linux服务器之间免密登录
目标 192.168.0.10 免密登录 192.168.0.11.192.168.0.12两台服务器 1.登录192.168.0.10 生成ssh密钥 ssh-keygen -t r ...
- 嵌入式Linux必读经典书籍(含下载方式)
最近,在知乎看到一个问题,"嵌入式Linux有哪些好书推荐".我读研期间也喜欢收藏一些书籍,每次看到京东有活动,总是忍不住想买一些书籍回来. 随着时间越来越久,我买的书越来越多,但 ...
- 【译】 双向流传输和ASP.NET Core 3.0上的gRPC简介
原文相关 原文作者:Eduard Los 原文地址:https://medium.com/@eddyf1xxxer/bi-directional-streaming-and-introduction- ...
- 文件上传accept参数可接受的类型汇总
https://www.cnblogs.com/huihuihero/p/17012817.html 1 // 文件上传accept接受的文件类型 2 3 export const fileTypes ...
- 2023第十四届极客大挑战 — CRYPTO(WP全)
浅谈: 本次大挑战我们队伍也是取得了第一名的成绩,首先要感谢同伴的陪伴和帮助.在共同的努力下终不负期望! 但遗憾的是我们没有在某个方向全通关的,呜呜呜~ 继续努力吧!要学的还很多.明年有机会再战!!加 ...
- 媒体查询常用 - 移动端和PC端尺寸
/* 移动端 */ @media all and (max-width: 768px) { } /* PC端 */ @media all and (min-width: 769px) { }
- WebApi使用Swagger
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API ...
- Qt5.9 UI设计(四)——布局设计及自定义界面
前言 前面我们已经创建了mainwindow ControlTabWidget ControlTreeWidget maintitlebar 4个UI几面,我们需要将其他三个UI放置到mainwind ...
- 达梦数据库varchar和nvarchar的验证
达梦数据库varchar和nvarchar的验证 测试SQL create tablespace zhaobsh datafile '/opt/dmdbms/data/DAMENG/zhaobsh.d ...
- [转帖]金仓数据库KingbaseES V8R6索引坏块故障处理
案例说明: 在执行表数据查询时,出现下图所示错误,索引故障导致表无法访问,后重建索引问题解决.本案例复现了此类故障解决过程. 适用版本: KingbaseES V8R3/R6 一.创建测试环境 # 表 ...