Dll运行机理

咸清 2011-02-28 01:40:25
“而对于DLL,函数储存在一个独立的动态链接库文件中。在创建Windows程序时,链接过程并不把DLL文件链接到程序上。直到程序运行并调用一个DLLs中的函数时,该程序才要求这个函数的地址。此时Windows才在DLL中寻找被调用函数,并把它的地址传送给调用程序。一般情况下,如果一个应用程序使用了动态链接库,Win32系统保证内存中只有DLL的一份复制品,这是通过内存映射实现的。DLL首先被调入Win32系统的全局堆栈,然后映射到调用这个DLL的进程的地址空间。在Win32系统中,每个进程拥有自己的32位线性地址空间。如果一个DLL被多个进程调用,每个进程都会被分配一份该DLL的映像。”

既然是被调入Win32系统的全局堆栈,那么我就想知道,dll的代码区、数据区都拷贝到内存中了吗?
如果这个dll处于网络中的一个位置,映射到调用这个DLL的进程的地址空间时,会不会包含dll的详细地址?IP+端口号+路径……

欢迎发表意见!
十分感谢阅读!
...全文
271 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
csorca 2011-03-01
  • 打赏
  • 举报
回复
反正都是在一个特定的“space”里头, 并且经过了各种系统层的保护, 不断校验这些数据链的合法性

你可以认为你要的信息都在他是一个 文件分配表, 也可以是个特定的文件头里头, 因为你的那些信息都是很重要的概要信息!

但系统设计角度,合理的想法肯定是每个文件头的入口, 同样也是被一个系统“表”收集了, 系统访问内存文件先从这些表入手。 你就找这个表就可以了。 找到这个表, 再看看系统对这些在干什么? 每个时钟周期内系统在校验什么。 至少这2个方面要搞清楚才能在根本上把握!

这个方面最好还是能参阅一下微软的系统设计, 看看调度文件的整个过程是怎么样的, 涉及到哪些东西, 这样就很容易从一个大局面来把握, 如果对系统设计熟悉, 在这个层次上回头看这些就容易多了, 现在想还不如去看看。
Saingel 2011-03-01
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 ybh37 的回复:]

我觉得,regsvr32.exe的注册原理值得研究~~
[/Quote]
先搞清楚是动态链接库dll还是activeX/com Dll,
前者无需注册所以即使在共享目录只要有权限就能使用,
后者需要注册,本地没注册不能使用,注册了也是使用本地的activex dll
Tiger_Zhao 2011-03-01
  • 打赏
  • 举报
回复
其实为了简单,我 7 楼只说了物理内存。
exe 进程通过映射调用 dll 函数时,系统保证该函数存在与某个物理页面中。
但是,每个进程有2G的虚拟空间(常规设置),物理内存总是不够用的,所以系统会用到磁盘上的交换文件,将某些虚拟内存的页面临时存放在磁盘上。
而对“已加载”的 dll,理想情况当然是一直驻留在物理内存中,但真要腾出物理内存时,并不需要将该页写入交换文件,下次调用时再从磁盘上的 dll 文件中载入就行了。所以系统会将该 dll 文件锁定。
14 楼所讲的 B 关机后 A 就出错,应该就是 A 系统认为该 dll 失去了锁定,再也不能按照上面的调度方式重新从磁盘载入了,所以报错。
咸清 2011-03-01
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 csorca 的回复:]
……
[/Quote]
我觉得问题可能出自Windows的注册机制。我们也不知道它怎么搞的,貌似也没有公开吧?
咸清 2011-03-01
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 chenjl1031 的回复:]

动态链接库DLL的代码并不是某个应用程序的组成部份,而是在运行时链接到应用程序中。与动态链接不同,静态链接方式是在链接期间把库(静态链接库)中的代码链接到可执行文件中,也就是说,在可执行文件中含有库函数的代码。
动态链接分为两阶段,即链接过程和装过程。
当应用程序调用动态链接库中的某个函数时,链接程序并不拷贝被调用函数的代码,而只是从引入库中拷贝一些指示信息,指出被调……
[/Quote]
恩,研究研究
咸清 2011-03-01
  • 打赏
  • 举报
回复
我觉得,regsvr32.exe的注册原理值得研究~~
赵4老师 2011-03-01
  • 打赏
  • 举报
回复
OleView.exe工具不能不用!
咸清 2011-03-01
  • 打赏
  • 举报
回复
LS的几位都说的不错,果断决定看 COM本质论
LX 还有要讲的吗?
没有的话结贴了~~~
csorca 2011-02-28
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 ybh37 的回复:]
引用 5 楼 csorca 的回复:

“dll处于网络中的一个位置..." , 能举个例子么 , 你这个有点前卫呀, 难道是个网络系统?

想试这个东西很简单,比方说,在局域网中有A、B两台电脑,假设B有一个可执行的EXE需要调用的DLL放在B本地目录,并且已经注册,B共享这个目录,A拷贝这个目录,不要注册它的DLL,A打开B共享目录并点击运行可执行的EXE,然后再点击运行本地的可执行的……
[/Quote]


其实我觉得把,你的A调用了B的DLL, DLL本身肯定是被完整地加载到A的内存, A的内存空间将对B的DLL所有函数入口分配内存地址, 在执行DLL目标函数的时候直接访问A的这个入口地址, 而不是B的内存地址, 你也不可能访问到(常规技术下我觉得是这样的). 这个过程里头, 是根本不需要 B机器的任何信息的. 但在实际系统设计的时候肯定为了考虑全局安全因素\系统效率\及独占模式等, B的在线主机信息应该是被记录下来的...放哪里还真不知道 ....

你说的B断线过后A会出错啥的, 这个恰恰类似于,本地程序的保护模式, 一个本地保护程序被执行了, 你是删除不掉这个程序的, 如果你用了系统低层高权限强制将物理信息修改, 系统的保护模式就会给出警告出错!!!这个过程确实间接反映了, 内存的保护模式和磁盘文件时有关联的, 不论他在任何地方....当然网络和本地的区别就是数据交互的方式不同了....原理应该差不了哪里去.

成熟的保护模式, 应该非常复杂, 那些小黑字们就喜欢钻这些空巴 , 对系统谙熟技术高超,他可以做异步注册, 其实就是告诉系统我是合法的, 并没有破坏你的保护, 但实际却是已经突破了保护限制了...这个应该就是攻进暴露漏洞了...
东方之珠 2011-02-28
  • 打赏
  • 举报
回复
动态链接库DLL的代码并不是某个应用程序的组成部份,而是在运行时链接到应用程序中。与动态链接不同,静态链接方式是在链接期间把库(静态链接库)中的代码链接到可执行文件中,也就是说,在可执行文件中含有库函数的代码。
动态链接分为两阶段,即链接过程和装过程。
当应用程序调用动态链接库中的某个函数时,链接程序并不拷贝被调用函数的代码,而只是从引入库中拷贝一些指示信息,指出被调用函数属于哪个动态链接库(.dll文件)。因此,在应用程序的可执行文件中,存放的不是被调用的函数的代码,而是DLL中该函数的内存地址。程序运行后,当需要调用该函数时,进入装入过程,把应用程序与DLL库一起装入内存,由Windows读入DLL中的函数并运行程序。
可以看出,动态链接是在应用程序被装入到内存时进行的。这样,当多个应用程序调用库中的同一个函数时,不会在内存中有该函数的多个拷贝,而是只有一份拷贝,每个应用程序的可执行文件中装入的只是该函数的内存地址,程序运行时再把应用程序代码与被调用函数代码动态链接起来,从而可以节省内存资源。同时,由于DLL与应用程序分开,即使更新DLL,也不用修改已编译好的可执行文件。
----节选自清华大学出版社《Visual basic 6.0 Win32 API 程序设计》(刘炳文 李凤华著)第1章 1.1.2 动态链接库
咸清 2011-02-28
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 tiger_zhao 的回复:]

应该是和内存管理机制有关。
每个进程只能访问自己的虚拟地址空间,通过进程私有的页目、页表来将虚拟地址和物理地址对应。
所以DLL被调入Win32系统的全局堆栈后,引用它的不同进程的页表就可以指向它所在的同一个物理地址。
在执行时,通过切换进程环境,dll 没有变动物理地址,函数指针在不同的进程内却可以表现为不同的虚拟地址。
至于写 dll 专有的数据区,会自动复制一份,然后将页表指向复制……
[/Quote]
我慢慢理解一下……
咸清 2011-02-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 csorca 的回复:]

“dll处于网络中的一个位置..." , 能举个例子么 , 你这个有点前卫呀, 难道是个网络系统?
[/Quote]
想试这个东西很简单,比方说,在局域网中有A、B两台电脑,假设B有一个可执行的EXE需要调用的DLL放在B本地目录,并且已经注册,B共享这个目录,A拷贝这个目录,不要注册它的DLL,A打开B共享目录并点击运行可执行的EXE,然后再点击运行本地的可执行的EXE,这时A电脑调用的Dll就是源于B。我们将B电脑关机,不重新注册本地Dll下,会系统报错。根据系统日志查看Dll的注册信息。

这么长,不知道看糊涂了没有~~
  • 打赏
  • 举报
回复
搬个小板凳来听课的说
lorl2 2011-02-28
  • 打赏
  • 举报
回复
DLL只能是在本地的,也就是说必需把对方映射为本地文件系统的一个分区,WinPE加载器不用考虑这个问题。
只有进程外组件(ActiveX exe),才可以离开主EXE单独在远程主机中存活,他们之前的联系一般采用TCP或管道(管道似呼也是用TCP?135端口?)。
king06 2011-02-28
  • 打赏
  • 举报
回复
网络应用一般都是利用额外的dataspace传递信息.
jiashie 2011-02-28
  • 打赏
  • 举报
回复
我是来学习的,DLL COM DCOM (防删除)
king06 2011-02-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 ybh37 的回复:]
既然是被调入Win32系统的全局堆栈,那么我就想知道,dll的代码区、数据区都拷贝到内存中了吗?
如果这个dll处于网络中的一个位置,映射到调用这个DLL的进程的地址空间时,会不会包含dll的详细地址?[/Quote]
1.是
2.否
Tiger_Zhao 2011-02-28
  • 打赏
  • 举报
回复
网络调用指 MTS/COM+ 之类?
这应该是代理模式,实现具体功能的 dll 只在服务器上加载,本地加载的 dll 在调用者和服务器直接进行代理,它内部的确有服务器的信息。
Tiger_Zhao 2011-02-28
  • 打赏
  • 举报
回复
应该是和内存管理机制有关。
每个进程只能访问自己的虚拟地址空间,通过进程私有的页目、页表来将虚拟地址和物理地址对应。
所以DLL被调入Win32系统的全局堆栈后,引用它的不同进程的页表就可以指向它所在的同一个物理地址。
在执行时,通过切换进程环境,dll 没有变动物理地址,函数指针在不同的进程内却可以表现为不同的虚拟地址。
至于写 dll 专有的数据区,会自动复制一份,然后将页表指向复制后的物理地址。
赵4老师 2011-02-28
  • 打赏
  • 举报
回复
DCOM
加载更多回复(5)

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧