首页
社区
课程
招聘
一段汇编码不是很懂
发表于: 2010-10-3 12:26 4598

一段汇编码不是很懂

2010-10-3 12:26
4598
小弟下面的一段代码不是很懂,麻烦高人解释一下,谢谢大家了!!!
MAIN1:
   PUSHAD
   CALL NEXT
NEXT:
   POP EBP
 [COLOR="Red"]  SUB EBP ,OFFSET NEXT    //GET BASE EBP[/COLOR]?????不懂

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 459
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
call指令要将下一条指令地址压入堆栈。这么说,你懂了不?
2010-10-3 13:13
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
3
取偏移地址..应该是用来重定位吧? 如果你没把这代码移植到其他地方,结果肯定是0
2010-10-3 15:22
0
雪    币: 459
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
exe文件一般是0,dll一般不是0。
2010-10-3 22:32
0
雪    币: 38
活跃值: (48)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
5
这是重定位的典型用法

1.为什么要重定位?
PE文件加载到内存都有个 基地址 就是,从哪个线性地址开始 映射可执行文件 内容,比如
EXE通常都是 00400000h,DLL一般是 10000000h,这就是为什么你经常看到的 为什么,反汇编出来的
代码都在 线性地址00400000h左右的原因。那么系统是不是 总是加载 到 这两个 地址呢?
答案是--不是 这个基地址存在于 PE 文件的文件头的 ImageBase (一个dword量)中,连接生成
程序时 可以 自己指定,若不指定那么 默认就是如果是 EXE文件00400000h,DLL文件就是10000000h

对于EXE来说,由于不同进程地址空间是相互隔离的,因此不会有其它文件来抢它的位置,也就是说,
它总能如意的在自己的 ImageBase 处,开始映射。
而dll就不一样了,为什么?
因为 设想 一个EXE文件的两个DLL的默认 ImageBase 都是10000000h,那么必定有一个不能如愿---
着另外的就要由操作系统 为它另找一个地方了 ----

那这又跟重定位有什么关系呢???

因为 对于PE文件,当它编译连接后,其中的许多 指令、数据就是绝对的地址值,比如
szString        db        '0'
push        offset szString
那么PE中实际的机器码就应该是  68 20 00 40 00 这种形式,看 00 20 40 00 ,Intel小尾方式 看过来就是 00 40 20 00
就是个绝对地址,这个绝对地址是与 ImageBase 的 00400000h息息相关的。
当某个DLL需要重定位,那么它的直接寻址指令(就是翻译成机器码后成为绝对数值 的那些地址),就必须修正
否则会访问到错误的地址。

比如 原 ImageBase == 10000000h,实际加载基址 == 20000000h
那么那些直接寻址指令就得加上这个 差值,差值= 实际加载基址 - 默认加载地址

2.重定位技术
MAIN1:
   PUSHAD
   CALL NEXT
NEXT:
   POP EBP
   SUB EBP ,OFFSET NEXT

编译结束时:
offset 是个操作符 OFFSET NEXT 回转化为 以默认加载地址为基址的 一个线性地址值,也就是 NEXT 标号的地址,比如 10002000h
也就是 POP EBP这条指令 的首地址
实际执行时:
call 把当前 EIP 入栈,转到标号 NEXT 执行,巧妙就在于,此时 的 EIP 是 CALL 的下一条 指令的首地址即 POP EBP 当前首地址,
POP        EBP         弹出这个EIP到EBP 比如 20002000h,此时 一减 就是 实际地址与默认地址的差值了,以后利用这个差值来修正直接寻址的数值。
(用EBX比较好,EBP还是不要乱动)
这段代码常见于 插入到 其他文件 或 进程 的程序中。
上面说的 DLL 文件 有重定位节 不用这个技术。
2010-10-3 23:12
0
雪    币: 459
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我是针对我的楼上说的话,当然dll不会采取这个技术重定位,这个代码自定位技术技术一般用来DIY的。
2010-10-3 23:50
0
雪    币: 58
活跃值: (40)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7
CALL NEXT
就是把NEXT:中的POP EBP这条指令的地址压入堆栈,刚POP EBP运行后EBP=offset NEXT
这是没用到重定位的情况

可以这样理解,CALL NEXT是运行时把映射到内存中的EIP压入堆栈,而offset NEXT是编译后就生成的,存在PE文件中。
重定位时SUB ebp,offset NEXT不一定是0,而没有重定位是就是0
2010-10-4 00:52
0
雪    币: 38
活跃值: (52)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
谢谢各位的支持和帮助
2010-10-4 10:24
0
雪    币: 38
活跃值: (52)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
个人认为这个很有道理的。
2010-10-4 10:30
0
雪    币: 28
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
路过学习了。这方法不错~~
2010-10-4 15:51
0
游客
登录 | 注册 方可回帖
返回
//