计算逻辑地址

    不知道有木有骚年和我一样曾经疑惑过,我们说的分段机制转换最开始的逻辑地址哪里来的,比如程序的指令地址?要明白这个,我们首先需要知道代码编译成二进制后在磁盘上是怎么组织的(以windows下的exe文件为例)

    举个栗子:

.386
.model flat,stdcall
Option Casemap:none

include			windows.inc
include			user32.inc
includelib		user32.lib
include			kernel32.inc
includelib		kernel32.lib

.data
	szText db 'fwddsg',0

.code
Start:
	invoke MessageBoxA,NULL,offset szText,offset szText,MB_OK
	invoke ExitProcess,0
end Start
    这段汇编使用MASMPlus编译后会生成一个exe文件,功能很简单,就是弹出个提示框。这段代码启动后第一条指令的地址是多少?


    这边是OD加载程序后的截图,这边可以看到,Start处的地址为0x401000,’fwddsg’字符串的地址是0x403000,这些逻辑地址怎么来的呢?我们随便用款PE文件解析器打开程序:
PE头信息:


    这边很容易看出,加载基址是0x400000,入口地址是0x1000,按这么算第一条指令的地址恰好是0x401000,我们再看下代码段和数据段在磁盘上的内容(想看文件在磁盘的内容,用UE打开exe文件即可)
代码段:

    这边RVA虚地址0x1000在磁盘0x400(节数据地址)上对应的内容和OD上的内容一模一样,也就是说此节保存的就是代码编译后的指令(当然.text不一定保存的全是指令,只要节属性相同的内容,数据也可以放这边),所以第一条指令的起始地址就是0x40000+0x1000=0x401000,这边由于程序的main地址就是代码节起始地址,所以可以这样计算

数据段:


    这边的RVA虚地址0x3000在磁盘0x800(节数据地址)上对应的内容是’fwddsg’,加上起始地址0x400000=0x403000,这下知道常量字符串的地址怎么算出来的吗?(这边要说下,dsg的含义据说语文好的认为是大帅哥,语文不好的就认为是大骚狗,很奇怪的是我身边的人的语文好像都不怎么好~)

    上面PE文件的相关信息是在程序编译连接的时候由编译器和连接器完成的(注意这个时候保存的是RVA),所以最初的逻辑地址在程序编译连接完成后基本就可以计算出来了,细心的同学会发现大部分程序的加载基址都是0x400000(高10位为1),这个表示使用页目录的第一项,所有程序都用这一个基址没问题吗?别忘了,程序每次启动,操作系统都会为其分配一个独一无二的页目录基址,所以程序线性地址的索引相同也无所谓
(这边所有描述基本基于EXE文件,其他格式的PE文件可能有点不同,PE文件结构和加载详细过程可参考《琢石成器》相关章节)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值