首页
社区
课程
招聘
[求助]概念性问题,PE文件在内存中的存在方式?
发表于: 2009-11-26 14:00 8863

[求助]概念性问题,PE文件在内存中的存在方式?

2009-11-26 14:00
8863
书上说一些DLL和SYS文件在内存中的映射只有一份,就是说我在一个进程中对内存中这个DLL的映射进行改动那么另一个进程也要受影响?但是又说了不同进程的DLL模块中的数据等内容又是不同的,要使它共享就使用共享内存,即给区段加上 shared属性。
问题就是区段在内存中是否共享是受shared属性决定的?那么我用PE文件查看器查看DLL的区段默认都没有这个属性啊,是否代表每个进程中的这个DLL模块都是独立的,修改一个进程的DLL模块不会影响到另一个进程中的DLL??
疑惑中,求助大家

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (35)
雪    币: 14
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
个人观点。。你修改了任何一个系统DLL
99%的可能都会引起所有调用这个DLL的程序死掉!!
2009-11-26 14:19
0
雪    币: 2513
活跃值: (620)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
答案是不会受到影响
2009-11-26 14:49
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
楼主,你要理解磁盘文件与内存文件的区别。
操作系统加载DLL是 把磁盘文件(C盘里很多都是)COPY到内存中去。所以说每一个PE文件使用系统DLL都是复制到内存中,然后调用内存的DLL文件,所以同一个DLL文件可以被多个进程加载而互不影响,这也是“HOOK是万能的”的理论依据之一。
所以大家修改DLL都是本进程加载后在内存中修改DLL(所以这个修改也只对本进程有效——注意操作系统还有很多其他的机制,所以有的时候你修改的方式很有限,或者几乎不能修改),而不是修改磁盘文件
2009-11-26 14:57
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
书上说一些DLL和SYS文件在内存中的映射只有一份,就是说我在一个进程中对内存中这个DLL的映射进行改动那么另一个进程也要受影响?

不会受影响的,因为你修改的只是加载到自己空间的dll副本,但是如果你修改的数据是位于一个特殊段——共享数据段(假设这个dll有这个特殊段),那就会对其他进程有影响了!如果根本就没有这个特殊段,那任你怎么修改dll的代码,也只是修改自己身上那个“副本”,对其他进程不会产生任何影响。

详细解释如下:
    在一个应用程序发出加载一个 DLL 的请求时,系统首先检查该 DLL 是否已经被加载到内存中去了,如果已经在内存中了,则copy该dll在内存中的映像到自己的地址空间里去;如果没有,则先将该dll加载到内存中再copy该dll一份映像到自己的地址空间。所以说,dll在内存中的映像只有一份,谁需要它,系统就把这份映像copy到谁的地址空间里去。所以你修改dll里面的数据只是修改你自身这份copy来的数据,对于其他进程的调用不会产生任何的影响。

    而共享数据段是dll中一个比较特殊的段,是一些比较特殊的dll才有的,在VC++里,微软提供了#pragma data_seg()方便程序员在dll中创建共享数据段,为什么要搞一个这么特殊的区段呢?因为考虑到,有一种特殊的dll需要把自己的全局变量让多个进程共享,可是一般dll里的全局变量对于每一个调用它的进程来说都是私有的,互不相干的(都是从内存中copy来的,当然互不相干了),而这个“共享数据段”就相当于应用程序调用dll时,并没有把它从内存里copy过来(其他区段都copy过来了,就剩这个“共享数据段”没copy)要访问操作这个数据段的话,直接访问操作内存里这个“共享数据段”! 因此,修改这个段的数据势必影响到其他进程,想修改它之前必须三思,否则会出意料!
2009-11-26 15:26
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
错别字太多,修改好几次了
2009-11-26 15:32
0
雪    币: 183
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
那是不是就是说在物理内存中同一个DLL的映像就会有多个?如果只是由于是同一份dll映射到不同地址空间,那么修改一个也就会影响到其它地址空间中的dll啊?或者说是采用了传说中的copyonwrite机制??
2009-11-26 15:33
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
是不是就是说在物理内存中同一个DLL的映像就会有多个?

这句话是错的,任何情况下,dll在内存中的映像只有一份!不然要dll来干嘛?干脆在每个exe文件都加入那一份代码就得了。dll是为了节省内存才出现的!
2009-11-26 15:36
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
楼主,请仔细看我5楼写的,但愿我没理解错,要不就误导你了~~
2009-11-26 15:38
0
雪    币: 14
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
学习了!
2009-11-26 15:40
0
雪    币: 183
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
既然内存中只有一份dll,那么任何进程对此dll的修改就是修改这份dll啊,那么其他链接到这个dll的进程当然要受影响啊,不知道理解对不对??
2009-11-26 15:50
0
雪    币: 254
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
确实是一份,不过为啥解释那么怪,一个映象又copy过去?

我理解是这样,如果已经在内存中了,那系统只是把后来的进程的地址也映射到同一块内存中

而修改的时候再会发生copy-on-write

所以你上面说的把那个映象copy到另一个进程中,这种说法我觉得很乱。。

也不知道我理解的对不
2009-11-26 15:53
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
5楼基本正确,楼主问的“如果只是由于是同一份dll映射到不同地址空间,那么修改一个也就会影响到其它地址空间中的dll啊?”。明显我们只要不修改初始的留给我们复制的那个保存在磁盘里的DLL,那么其他被复制的DLL副本们是互相不影响的。

对于“既然内存中只有一份dll,那么任何进程对此dll的修改就是修改这份dll啊,那么其他链接到这个dll的进程当然要受影响啊,”。楼主要明白,“那么任何进程对此dll的修改就是修改这份dll副本啊,不会影响那一份DLL”
2009-11-26 15:55
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
既然内存中只有一份dll,那么任何进程对此dll的修改就是修改这份dll啊

回11楼,内存中只有一份dll,进程调用该dll时就把它copy到自己的地址空间里了,要修改也是修改这个copy过来的副本。你还是没看明白我5楼写的,都写得那么通俗了。。
2009-11-26 15:59
0
雪    币: 14
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
搞糊涂了。。
------------------------
他先说:
则copy该dll在内存中的映像到自己的地址空间里去;如果没有,则先将该dll加载到内存中再copy该dll一份映像到自己的地址空间。所以说,dll在内存中的映像只有一份,谁需要它,系统就把这份映像copy到谁的地址空间里去。所以你修改dll里面的数据只是修改你自身这份copy来的数据,对于其他进程的调用不会产生任何的影响。

然后又说:
任何情况下,dll在内存中的映像只有一份!不然要dll来干嘛?干脆在每个exe文件都加入那一份代码就得了。dll是为了节省内存才出现的!
--------------
难道CPU COPY到其他地址空间的不叫映像么?
如果像他说的那样,每个程序都COPY一份,那不还就相当于在每个EXE文件中加入了一份么。只是文件在关了之后把他释放了而已。。。这样的话,他也不节省内存,而是节省硬盘啊。。
个人意见!!
-------------
到底是什么样的。。。有没有高手出来解答。。。。。。。。。。。。。。。。。。。。。。。。。。。
2009-11-26 16:00
0
雪    币: 183
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
[QUOTE=怀特迈恩;717766]5楼完全正确,楼主问的“如果只是由于是同一份dll映射到不同地址空间,那么修改一个也就会影响到其它地址空间中的dll啊?”。明显我们只要不修改初始的留给我们复制的那个保存在磁盘里的DLL,那么其他被复制的DLL副本们是互相不影响的。[/QUOTE]

谈谈我看了5L的理解:
复制DLL意思也就是会有多个复制出来的DLL,不论它是在内存里还是在磁盘上,也就是说并不是加载一个dll到内存里,其他进程都通过分页机制链接到这个dll,而是通过每个进程都被复制一个dll,再链接到这些复制的dll上?

错误的话请你们帮忙纠正下
2009-11-26 16:03
0
雪    币: 4560
活跃值: (1012)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
100%是一份,只是把DLL的内存映射到EXE的内存空间里,如果修改代码就会复制一份然后修改,再把映射地址改掉,而共享段就不会发生这种事情,所以修改DLL内存代码只会影响自己的进程,以上纯属个人理解,欢迎大侠批评
2009-11-26 16:03
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
如果已经在内存中了,那系统只是把后来的进程的地址也映射到同一块内存中

回12楼,你的“系统只是把后来的进程的地址也映射到同一块内存中”这句话错了,每个exe被加载到内存之前,PE加载器都为其分配4GB的虚拟内存空间,而且是独立的。
2009-11-26 16:03
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
检讨: 这个说法是错误的——这个DLL加载就是节约硬盘空间。
DLL加载机制,不存在节约磁盘空间的问题;是否节约内存空间由于自己水平有限,坐听 各位大大 解释。

“dll在内存中的映像只有一份,谁需要它,系统就把这份映像copy到谁的地址空间里去。”我认为这个DLL是在系统分区里的,是保存在硬盘里的,加载的时候是从硬盘读数据到内存里(因OD调试时,加载有些DLL时,会卡一下,如果是从内存拷贝应该很块不会卡一下)。
2009-11-26 16:06
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
难道CPU COPY到其他地址空间的不叫映像么?
如果像他说的那样,每个程序都COPY一份,那不还就相当于在每个EXE文件中加入了一份么。只是文件在关了之后把他释放了而已。。。这样的话,他也不节省内存,而是节省硬盘啊


回15楼,每个EXE文件都有自己独立的4GB内存空间,但由于CPU分页管理机制,每一时刻系统只是把需要的加载到真正物理内存里面去
2009-11-26 16:09
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
我不明白你们为什么跟磁盘文件联系起来,在磁盘上的PE文件被加载进内存后,才称为映像或模块。内存的大小跟磁盘的大小 有联系吗?
2009-11-26 16:13
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
回19楼
15楼说的对,这个加载就是节约硬盘空间

这个加载是节省内存空间,跟磁盘空间没任何关系
2009-11-26 16:14
0
雪    币: 14
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
程序加载DLL到底是连接还是COPY

如果连接的话,修改了DLL的话,会影响其他调用DLL的程序
如果是COPY的话,他在自己的空间里,怎么修改都不会影响其他程序

但是不管是连接还是COPY对破解应该都没有用吧,因为再次启动程序后,系统会重新加载这个DLL啊。。
除非把这个DLL给保存起来。。
2009-11-26 16:16
0
雪    币: 183
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
我觉得也是这样,但是不敢肯定,还得请各位大大来给个确切答案
2009-11-26 16:19
0
雪    币: 259
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
明显我们只要不修改初始的留给我们复制的那个保存在磁盘里的DLL

回13楼,在进程中修改自己进程空间的dll模块,怎么会影响到磁盘文件上的dll文件了?你这话让人很费解啊,试问你用OD修改汇编代码,为什么退出OD再打开,又回到原来的样子了?必须“复制到文件”然后“保存”才能修改在磁盘上的文件吧?
2009-11-26 16:21
0
游客
登录 | 注册 方可回帖
返回
//