返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C# 关于LoadLibrary的疑问详解
  • 555
分享到

C# 关于LoadLibrary的疑问详解

2024-04-02 19:04:59 555人浏览 安东尼
摘要

关于 LoadLibrary 的疑问 Win32 api 中 LoadLibrary 函数的功能是加载某个库文件(通常是 dll 文件),然后返回 HMODULE 句柄,可以使用两个

关于 LoadLibrary 的疑问

Win32 api 中 LoadLibrary 函数的功能是加载某个库文件(通常是 dll 文件),然后返回 HMODULE 句柄,可以使用两个这个句柄来调用dll中的导出函数,一切似乎就这么简单。下面我们考虑深入一点,提出几个问题。

使用 Process Explorer 可以看到进程所加载的 dll,当然也可以看到使用 LoadLibrary 函数所加载进来的 dll。一个dll被某个进程加载后,这个dll就表现为被占用了(不能被更改、不能删除)。那问题就来了,LoadLibrary是怎样占用一个dll文件的呢?是用CreateFile函数打开的吗?我们先不急着解答此问题。更进一步我们发现,在Process Explorer 进程的handle 列表中[1]并没有发现哪个handle跟被加载的dll相关,这个问题又跟前面的问题发生了矛盾,既然dll被占用了,为什么不存在handle与被占用dll文件相关呢?

别急,下面我们将会解答上面提出的两个问题。不过在解答之前,我们先做个知识铺垫。我们都知道,在 windows 中去占用一个文件最直接、最简单的方式就是调用 CreateFile API 函数来打开文件,读者可以试着写个 Demo 使用 CreateFile 来打开某个文件,打开文件后,使用 Process Explorer 就可以看到被载入文件的句柄(注意Vista、Win7中的进程完整度级别问题)。具体原因:CreateFile会创建一个内核对象,与被打开的文件相关,Process Explorer 可以查看内核对象,当然就可以看到刚才被打开的文件句柄了。

有了上面的知识铺垫,我们可以开始解答上述第二个问题了。dll被载入后,为什么不存在handle与被占用dll文件相关的问题。仔细阅读关于 Windows 内核对象的文档可以发现,Windows 内核对象在编码上使用 HANDLE 类型来表述的,有文件、管道、油槽、事件等等,并且是由 CloseHandle 函数来予以关闭。而LoadLibrary 返回的是一个HMODULE,由 FreeLibrary 释放,其并非内核对象,而 Process Explorer 的handle列表只会显示内核对象句柄。所以这就解释了上述的第二个问题。

LoadLibrary既然没有创建内核对象(由HANDLE来表述的对象)来占用dll文件,那它是怎样将文件占用的呢?不过完全可以肯定的一点是,不是用 CreateFile 来打开的,如果用 CreateFile 来打开文件,则应该可以在 Process Explorer 列表中看到。要解释此问题,我们可以试着写个程序,然后调试到 LoadLibray 中[2],看看其究竟是怎样占用dll文件的。经过逐步深入调试发现,LoadLibrary 最终是调用 Windows DDK(Windows Driver Develop Kit)函数 ZwOpenFile 来实现文件被占用的。具体函数调用栈信息如下:

       ntdll.dll!_ZwOpenFile@24()  + 0xa bytes 

      ntdll.dll!_LdrpFindORMapDll@24()  + 0x2c36 bytes

      ntdll.dll!_LdrpLoadDll@24()  + 0x145 bytes    

      ntdll.dll!_LdrLoadDll@16()  + 0x74 bytes

      KernelBase.dll!_LoadLibraryExW@12()  + 0x120 bytes  

      kernel32.dll!_LoadLibraryW@4()  + 0x11 bytes      

      Te.exe!wmain(int arGC, wchar_t * * argv)  Line 16 + 0xd bytes       c++

      Te.exe!__tmainCRTStartup()  Line 552 + 0x19 bytes C

      Te.exe!wmainCRTStartup()  Line 371 C

      kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes

      ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes  

      ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes    

ZwOpenFile 为 Windows DDK 函数,跟 CreateFile 等用户态函数不同,此函数打开文件并占用之,但其不创建内核对象。所以这就解释了,为什么使用 LoadLibrary 函数加载 dll 后,在 Process Explorer 的 handle 列表中看不到对应的 dll,而dll又被占用的原因。简而言之,就是使用了打开文件函数来打开文件,但此函数跟 CreateFile 不同,不会创建内核对象handle。

[1] 开启 Process Explorer 的handle列表方式为:View à Lower Pane View à Handles

[2] 关于怎样调试进入到 Windows API 中的方法,可以查看我的另一篇文章:调试 Windows API

到此这篇关于C# 关于LoadLibrary的疑问详解的文章就介绍到这了,更多相关C# LoadLibrary的疑问内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C# 关于LoadLibrary的疑问详解

本文链接: https://lsjlt.com/news/133915.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C# 关于LoadLibrary的疑问详解
    关于 LoadLibrary 的疑问 Win32 API 中 LoadLibrary 函数的功能是加载某个库文件(通常是 dll 文件),然后返回 HMODULE 句柄,可以使用两个...
    99+
    2024-04-02
  • 关于Ajax的疑难杂症详解
    目录跨域问题解决方案请求成功进error问题总结跨域问题 如图所示,这是通过jquery封装的ajax请求了一个本地的php文件(无框架),console提示CORS策略已阻止&ld...
    99+
    2024-04-02
  • 关于android布局的layout_marginLeft疑问
    layout_marginLeft是用于设置View的左边距的属性。它指定了View与其父布局左边的距离。当设置layout_mar...
    99+
    2023-08-08
    Android
  • python中关于对super()函数疑问解惑
    目录案例一:运行下面的代码结果是什么?案例二:运行下面的代码结果是什么?案例三、更复杂些的继承,和上面的同理总结案例一:运行下面的代码结果是什么? class Person: ...
    99+
    2024-04-02
  • 关于ORACLE RAC心跳问题的释疑
    1、rac心跳的作用:检测集群节点间的网络健康状态,还可用做缓存同步刷新及全局资源维护。在grid control出现后还传输数据块,其内联数据通信量比较大,通常是千兆网,当然使用万兆更好。2、rac心跳能...
    99+
    2024-04-02
  • 完全指南:解决你关于pip3安装的疑问
    解决疑惑:pip3安装教程,解答你的疑问,需要具体代码示例 在Python开发中,pip3是一个重要的工具,用于管理和安装Python的各种库和模块。然而,对于一些新手而言,使用pip3可能会遇到一些疑问和困惑。本文将带你深入了...
    99+
    2024-01-18
    教程 pip 安装
  • 【Otter】关于otter双A模式的一点疑问
    何为双A模式:可以简单理解为mysql的双主模式,互为主从 具体可参考:https://github.com/alibaba/otter/wiki/Manager配置介绍 官方博客的配置方法: 双A...
    99+
    2024-04-02
  • 聊一聊关于php源码中refcount的疑问
    在浏览PHP源码的时候,在众多的*.stub.php中,发现了这样的注释,@refcount 1。 通过翻看build/gen_stub.php源码,发现了在解析*.stub.php...
    99+
    2022-11-13
    php源码refcount php @refcount 1
  • 关于C#中的Invoke示例详解
    目录C# 关于Invoke什么时候用?为什么要用1、Control的Invoke2、Delegate的Invoke怎么用?1、Control 的 Invoke2、Delegate的I...
    99+
    2023-02-06
    c#的invoke c#中invoke方法详解 c# Invoke
  • C语言中关于scanf函数的一些问题详解
    在学习创建二叉树时遇到了scanf的一些问题,在此记录下来 创建根节点A后理想情况是输入A的左子树,若不为空继续创建左子树,但输入A后发现重复创建了一个左子树,测试后发现输入A换行...
    99+
    2024-04-02
  • 关于C++中二分法详解
    目录一、整数二分1.整数二分模板2.求解二分问题的思路3.练习二、浮点数二分1.浮点数二分模板2.练习三、总结一、整数二分 单调性与二分的关系:有单调性一定可以二分,用二分不一定是单...
    99+
    2024-04-02
  • 关于C语言一维数组算法问题详解
    目录问题1:将数组中的数逆序存放问题2:求数组中最大值及其下标问题3:找出不是两个数组的共有元素问题4:找出出现次数最多的数问题5:数组中插入数字并排序问题6:数组循环右移问题总结问...
    99+
    2024-04-02
  • 关于C/C++内存管理示例详解
    1、内存分配方式 在C++中,内存分成五个区,分别是堆、栈、自由存储区、静态存储区和常量存储区。 1) 栈 执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这...
    99+
    2024-04-02
  • php中关于token验证的相关问题详解
    目录token验证首先是为什么用?那么怎么用呢?token的组成一般 token 组成:JWT 组成:标准的组成:总结token验证 什么是token?我相信很多开发者都或多或少听过...
    99+
    2023-05-20
    php token验证 php token生成和验证 php接口验证token源码
  • 关于C语言qsort函数详解
    目录C语言qsort函数详解一.qsort函数是什么 二.使用qsort排序-以升序为例1.整形数组排序2.字符数组排序3.字符指针数组排序4.结构体数组排序5.浮点型数组...
    99+
    2024-04-02
  • 通过HashMap原理详解entrySet中的疑问
    目录HashMap底层变量put()方法:2. get(Object key)方法:3. remove(Object key)方法:4.entrySet()方法:EntrySet类代...
    99+
    2022-11-13
    HashMap entrySet HashMap 原理
  • 如何解疑C++多态覆盖问题
    这篇文章给大家介绍如何解疑C++多态覆盖问题,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。C++编程语言中的多态性是一个比较重要的概念,在实际应用中有许多比较重要的细节问题值得我们去关注。在这里就先来了解一下C++多态...
    99+
    2023-06-17
  • 如何解析学习C++时的疑难问题
    本篇文章为大家展示了如何解析学习C++时的疑难问题,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。许多编程人员学习C++总结经验为,有的觉得C++语言是一门独立的语言,并不是在C语言的基础上,可以直接...
    99+
    2023-06-17
  • 有关mongodb升级的一些疑问
    我们的mongodb数据库是简单的一主一从架构,目前是2.4版本,我想升级到3.2,网上介绍的方式基本都是一步步升级的那种,我有一种升级想法,那就是,用3.2启一个从库,等同步完成后直接把这个3.2从库关闭...
    99+
    2024-04-02
  • 关于C# 类的封装详情
    目录1、前言2、实例1、前言 法存取数据。除此之外,还可以控制数据的存取方式。在面向对象编程中,大多数都是以类作为数据封装的基本单位。类将数据和操作数据的方法结[成一个单位。设计类...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作