一、显式加载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核心编程》的更多相关文章

  1. dll显式加载与隐式加载

    使用动态DLL有两种方法,一种是隐式链接,一种是显式链接,如果用loadlibrary就是显示链接,用lib就属于隐式链接. 两种方法对于你的程序调用动态库时没有任何区别,只是你在编程时,步骤是不一样 ...

  2. DLL动态库的创建,隐式加载和显式加载

    动态库的创建 打开VS,创建如下控制台工程,工程命名为DllTest: 在弹出的对话框中选择"DLL"后单击"完成"按钮: 在工程中新建DllTest.h和Dl ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (28) ------ 第五章 加载实体和导航属性之测试实体是否加载与显式加载关联实体

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 5-11  测试实体引用或实体集合是否加载 问题 你想测试关联实体或实体集合是否已经 ...

  4. 【EF学习笔记08】----------加载关联表的数据 显式加载

    显式加载 讲解之前,先来看一下我们的数据库结构:班级表 学生表 加载从表集合类型 //显示加载 Console.WriteLine("=========查询集合===========&quo ...

  5. 【DLL】动态库的创建,隐式加载和显式加载(转)

    原文转自:https://blog.csdn.net/dcrmg/article/details/53437913

  6. Windows核心编程 第二十章 DLL的高级操作技术

    第2 0章 D L L的高级操作技术 看了下这章的内容,谈不上高级,都是些常用相关,但是还是有一些细节需要注意. 20.1 DLL模块的显式加载和符号链接 如果线程需要调用D L L模块中的函数,那么 ...

  7. 【windows核心编程】DLL相关(1)

    DLL相关的东西 1.DLL的加载方式 隐式: #pragma comment(lib, "XX.lib"); 编译器去查找名为XX.dll的DLL,除了名字相同,该DLL和该LI ...

  8. 《windows核心编程系列》十九谈谈使用远程线程来注入DLL。

    windows内的各个进程有各自的地址空间.它们相互独立互不干扰保证了系统的安全性.但是windows也为调试器或是其他工具设计了一些函数,这些函数可以让一个进程对另一个进程进行操作.虽然他们是为调试 ...

  9. RequireJS 模块的定义与加载

    模块不同于传统的脚本文件,它良好地定义了一个作用域来避免全局名称空间污染.它可以显式地列出其依赖关系,并以函数(定义此模块的那个函数)参数的形式将这些依赖进行注入,而无需引用全局变量.RequireJ ...

  10. laravel 嵌套的渴求式加载

    今天在通过需求表A查询场地类型表B,然后通过表B的场地类型id去查询表C场地类型名的时候遇到了一个小的问题. 需求表A的字段:id.user_id .name等等: 中间表B的字段:id.appeal ...

随机推荐

  1. 二、java发送https的各类请求

    导航 一.java发送http的各类请求 二.java发送https的各类请求 java开发中需要调用其他服务的对外提供的https请求,上一篇写的是调用http,处理方式不太一样,可以参考如下代码: ...

  2. 《深入理解计算机系统》(CSAPP)实验四 —— Attack Lab

    这是CSAPP的第四个实验,这个实验比较有意思,也比较难.通过这个实验我们可以更加熟悉GDB的使用和机器代码的栈和参数传递机制. @ 目录 实验目的 准备工作 内容简介 代码注入攻击 Level 1 ...

  3. SetFitABSA: 基于 SetFit 的少样本、方面级情感分析

    SetFitABSA 是一种可以有效从文本中检测方面级情感的技术. 方面级情感分析 (Aspect-Based Sentiment Analysis,ABSA) 是一种检测文本中特定方面的情感的任务. ...

  4. yakit的web fuzzer功能的使用

    问题 yakit没有Burp 的 Intruder 爆破模块,那么yakit该怎么进行参数爆破?yakit参数爆破的方式与burp有什么区别? 前言 手工测试场景中需要渗透人员对报文进行反复的发送畸形 ...

  5. Proxifier 2023年11月时最新版 激活教程

    前言 Proxifier 是一款功能非常强大的socks5客户端,可以让不支持通过代理服务器工作的网络程序能通过HTTPS或SOCKS代理或代理链.支持64位系统支持Xp,Vista,Win7,支持s ...

  6. Spring Cloud 系列:Seata 中TCC模式具体实现

    概述 https://seata.io/zh-cn/docs/dev/mode/tcc-mode https://seata.io/zh-cn/docs/user/mode/tcc TCC模式与AT模 ...

  7. SV 数据类型-3

    联合数组 在内存中分配的空间可以是不连续的 联合数组方法 数组的方法 数组使用推荐 结构体 枚举类型 字符串变量类型String 操作符

  8. STM32CubeMX教程22 FSMC - 8080并行接口TFT-LCD驱动

    1.准备材料 开发板(正点原子stm32f407探索者开发板V2.4) STM32CubeMX软件(Version 6.10.0) 野火DAP仿真器 keil µVision5 IDE(MDK-Arm ...

  9. [转帖]mysql 里 CST 时区的坑

    mysql 里 CST 时区的坑 一.问题简述 mysql 里 CST 时区是个非常坑的概念,因为在 mysql 里CST既表示中国也表示美国的时区.但是在Jdk代码里,CST 这个字符串被理解为Ce ...

  10. [转帖]SQL SERVER DBCC命令详解

    https://developer.aliyun.com/article/867768   简介: SQL数据库开发 DBCC DROPCLEANBUFFERS:从缓冲池中删除所有缓存,清除缓冲区 在 ...