能力值:
( LV2,RANK:10 )
|
-
-
2 楼
1)0x00401000是虚拟地址,实际OD代码中标注地址时都加了cs,ds等段选择子,但windows为了安全强制每个段选择子所引到的base都是000000(可是一些特殊的fs等是非0起始的哦 ,这在od的寄存器窗口是可以看到,如od窗口中cs的左边4位数是选择子的值,右边8位值是base),于是我门win32汇编中不必顾及选择子而直接使用 了0x00401000等偏移地址(屏蔽了复杂寻址机制,安全又方便),只是因为cs,ds等都是索引的base是000000,所以0x00401000等地址又可以直接作为平坦地址空间的虚拟地址来对待(毕竟从000000再加上0x00401000还是0x00401000)。我们win32汇编中使用的包括od中的地址都是这些虚拟地址,要从虚拟地址到物理地址,就必须用到页表页目录进行映射才行,这些对程序员是透明的。
2)每个pe文件头有个字段值作为建议加载地址,vc编译时默认填充这个字段为00400000,当然这也可以从settings中修改,windows作为分时多任务操作系统,每个进程有其自身的地址空间,每个进程互相不干扰的,这个是你没理解操作系统原理了 ,自己补习吧
3)这个吧大多是堆与栈的空间,具体自己看书吧
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
第一个问题:
物理地址需要在ring0级别下才能看到,用ollydbg反汇编是在ring3级别下进行的,此时我们看到的内存地址都是虚拟地址。
第二个问题:
在反汇编工具中看到的PE文件的指令地址是相对于磁盘文件而言的,当PE文件装入内存时还会有一个地址,即虚拟内存地址。
虚拟内存地址=基址+偏移量
基址:PE文件装入内存时的基地址。默认情况下,exe文件在内存中的基址是0x00400000。一般PE文件的0字节就对应这个地址,所以如你所说,PE头总是从0x00400000开始填充内存。而内存中的进程是互相独立的(各自拥有4G的内存寻址空间),所以这个地址是不变的。基址可以通过编译选项更改。
打个比方说,你从北京到上海,现在在过了郑州100公里的地方,那么郑州是基址,100公里就是偏移量。
第三个问题:
与win32的内存管理有关。win32系统每个进程都有4G的内存寻址空间,具体分配如下:
0xFFFFFFFF-0xC0000000的1GB用于VxD、存储器管理和文件系统;
0xBFFFFFFF-0x80000000的1GB用于共享的WIN32 DLL、存储器映射文件和共享存储区;
0x7FFFFFFF-0x00400000为每个进程的WIN32专用地址;
0x003FFFFF-0x00001000为MS-DOS 和 WIN16应用程序;
0x00000FFF-0x00000000为防止使用空指针的4,096字节。
|
|
|