关于DLL和PE

zjybestzjybest 2003-09-24 03:11:47
我们知道加载DLL过程中,是把DLL的导出表中的函数地址的数据读出来然后放在PE文件的IAT表中,通过这样来实现的地址映射,但是如果DLL映射在不同的进程的不同的空间里,可能基地址不一样,那么DLL他的导出表是否变化了?我想是应该不变化的,么不变化如何使调用他的进程的IAT表里面的函数地址手指向正确的调用地址了?
调用进程调用GETPROCADRESS这个函数是不是就是读出DLL的导出表中的地址了?他的实现细节如何?
...全文
161 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjybestzjybest 2003-09-29
  • 打赏
  • 举报
回复
HINSTANCE是线性区逻辑地址,映射地址如果不是编译器的漠认的基地址(线性地址)必然要重定位
W32API 2003-09-26
  • 打赏
  • 举报
回复
我想你是否应先理解所说的相对与绝对。
绝对一般指物理地址(物理存储器),
相对指线性地址(鬼知道他会在哪里)。

在 WIN 下,进程使用的是线性地址,所以都是相对的。
线性地址与物理地址的转换由操作系统完成(对应用程序透明)。

我认为你应先关心一下 WIN 对于进程空间的管理方式,
再讨论这个地址形成的问题。
zjybestzjybest 2003-09-26
  • 打赏
  • 举报
回复
注意我的问题是GETPROCADRESS的具体实现的思路!请大家讨论
W32API 2003-09-26
  • 打赏
  • 举报
回复
内存中却是只有一份。
我一直不是很明白你为何会纠缠于以下这个问题。
“那么每次映射DLL的时候,
OS首先把DLL的映射的实际的基地址也就是HINSTANCE保存起来”

你是否认为 HINSTANCE 是对于所有进程均有效的物理地址?

但是我想你是否可以从以下方面进行考虑:

在 INTEL 架构下,打开分页模式之后,所有的寻址都是页寻址(GDT 除外),
操作系统本身也是通过页进行寻址的。
那么此时的 HINSTANCE 也仅对于 WIN 本身有效,
除非 WIN 按照相同的地址映射进入所有进程空间(包括他自己),
如是这样,那么何须重定位?

如你认为以上合理,那么他又怎么去比较呢?
不同的地址空间的好像不具备可比性吧。
zjybestzjybest 2003-09-26
  • 打赏
  • 举报
回复
相对地址是相对基础地址的偏移地址
绝对地址是在进程地址空间中的地址不一定是物理地址
(有时候也称为线性地址)
物理地址是实际内存寻址是的地址总线的地址(也就是内存储器的实际地址)

对于WIN32中每一个进程都在自己的地址空间运行,寻址时由段表和页表进行绝对地址(线性地址)到物理地址的转换,这我很明白。

现在DLL可以映射到多个进程的逻辑空间,但是不一定DLL的基础地址是一样的,并且DLL在实际内存中只有一份映象就是DLL的导出表也只有一份,但是每一个PE调用者加载DLL时候(静态),都要把PE的导入表进行初时话,他怎样换算原来DLL的导出表中函数地址到自己空间的PE导入表来。

注意我的问题是GETPROCADRESS的具体实现的思路

可以这样理解吗?
因为DLL有一个重定位表,他标识出了所有需要重定位的地址
那么每次映射DLL的时候,OS首先把DLL的映射的实际的基地址也就是HINSTANCE保存起来
然后把实际映射的HINSTANCE和DLL的默认的DLL基地址进行比较,
然后把差直和DLL的输出表的函数地址进行运算,
然后把运行的结果传递给调用DLL的PE文件的IAT表里面(静态)
这样就能够调用完成重定位

W32API 2003-09-25
  • 打赏
  • 举报
回复
理论差不多。实际执行中,DLL 的装入地址是由操作系统安排的。
DLL 导出表是导出函数的相对偏移。
使用时只要知道装入地址和偏移地址,
就可以知道函数入口在进程线性地址空间的偏移了。
zjybestzjybest 2003-09-25
  • 打赏
  • 举报
回复
可以这样理解吗?
因为DLL有一个重定位表,他标识出了所有需要重定位的地址
那么每次映射DLL的时候,OS首先把DLL的映射的实际的基地址也就是HINSTANCE保存起来
然后把实际映射的HINSTANCE和DLL的默认的DLL基地址进行比较,
然后把差直和DLL的输出表的函数地址进行运算,
然后把运行的结果传递给调用DLL的PE文件的IAT表里面(静态)
这样就能够调用完成重定位
W32API 2003-09-25
  • 打赏
  • 举报
回复
对单一的进程,映射地址是相对固定的。
W32API 2003-09-25
  • 打赏
  • 举报
回复
基于页的全部是相对地址
YiDing0413 2003-09-25
  • 打赏
  • 举报
回复
不同的进程空间有着相互独立的地址空间,注意!这里说的是地址空间,而不是地址!或许dll在不同的进程空间里被映射的地址空间不同,但是,在保护模式下,地址空间并不等同于实际地址,因此经过系统的变换,最终不同进程对同一个导出函数的调用所访问的物理内存其实是同一块。
zjybestzjybest 2003-09-25
  • 打赏
  • 举报
回复
是的。我知道WIN调整DLL的基地址,但是我说的是调用DLL的PE文件是如何把DLL原来空间的绝对地址换成现在空间的绝对地址,然后写PE文件的IAT表的?
zjybestzjybest 2003-09-25
  • 打赏
  • 举报
回复
你用HEX看DLL的导出表里面的函数地址实际上都是虚空间的绝对地址而不是相对的转移。`
W32API 2003-09-25
  • 打赏
  • 举报
回复
WIN 调整的是装入地址,也就是 DLL 的起始地址。
zjybestzjybest 2003-09-25
  • 打赏
  • 举报
回复
那不是每次DLL映射时候,WIN都要重心写DLL的导出表,我想应该不会,应该是通过DLL的导出表根据现在DLL的当前映射基地址,来进行运算,来写调用DLL的PE文件的IAT表,
W32API 2003-09-25
  • 打赏
  • 举报
回复
DLL 映射进入进程线性地址空间时,WIN 可进行调整
zjybestzjybest 2003-09-25
  • 打赏
  • 举报
回复
DLL 导出表里面的地址应该是绝对地址呀,因为是相对于DLL的默认基地址的绝对地址
zjybestzjybest 2003-09-24
  • 打赏
  • 举报
回复
IAT表里面是一个DWORD应该是绝对地址呀???
W32API 2003-09-24
  • 打赏
  • 举报
回复
使用的是相对地址。

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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