| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1623 人关注过本帖
标题:看来还是发个帖子求教吧-重定位
只看楼主 加入收藏
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
更深层次 push 是啥指令呢 是堆栈操作的指令 这里 压栈的 是数 也就是立即数(压eip貌似不能用指令 故而 用call代替)

而立即数 是写在指令中的 是指令的一部分 比如 mov eax.12345678h 则 这个12345678就会老实的出现在指令中 不会变

而我们这里需要的就是当前指令位置 故而不能用push的那一套


2010-10-01 14:33
你们都要疼我哦
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:火星
等 级:贵宾
威 望:49
帖 子:1296
专家分:2746
注 册:2008-7-13
收藏
得分:0 
记得前段时间我回答过这个问题,打了两大段字,不知道楼主是不是看的那个帖子?
如果仔细琢磨,理解是非常容易的。

几条代码的目的就是取得差值,要取得差值,就必须知道实际装载地址和默认装载地址,然后进行SUB。offset@B 这个在编译时就固定了,offset的使用也需要多注意。
这个是取得@@标号的默认装载地址,
pop ebx则是取得标号的实际装载地址,因为CALL需要把返回地址入栈,正是标号的
实际装载地址。

既然是重定位,当然是有可能需要重定位 也有可能不需要重定位。关键看offset@B和pop出的ebx是否相等。你非要忽视offset的作用 那也没办法

小妹,哥哥看你骨骼清奇,绝非凡人,将来必成大业,不如这样,你先把裤裤脱了,待哥哥为你开启灵窍,然后我们一起努力钻研如何
2010-10-01 14:36
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
顺便留个作业

    call $+5
    pop ebx
    sub ebx,$-1

这个 对吗? 自己想想啦

扩展阅读 Intel(R) 64 and IA-32 Architectures Software Developer’s Manual 有兴趣找来看看 看看call的机器码

CALL—Call Procedure



  Opcode            Instruction      64-Bit      Compat/        Description

                                     Mode        Leg Mode



  E8 cw             CALL rel16       N.S.        Valid          Call near, relative, displacement

                                                                relative to next instruction.



  E8 cd             CALL rel32       Valid       Valid          Call near, relative, displacement

                                                                relative to next instruction. 32-bit

                                                                displacement sign extended to 64-bits

                                                                in 64-bit mode.



  FF /2             CALL r/m16       N.E.        Valid          Call near, absolute indirect, address

                                                                given in r/m16.



  FF /2             CALL r/m32       N.E.        Valid          Call near, absolute indirect, address

                                                                given in r/m32.



  FF /2             CALL r/m64       Valid       N.E.           Call near, absolute indirect, address

                                                                given in r/m64.



  9A cd             CALL             Invalid     Valid          Call far, absolute, address given in

                    ptr16:16                                    operand.



  9A cp             CALL             Invalid     Valid          Call far, absolute, address given in

                    ptr16:32                                    operand.



  FF /3             CALL m16:16      Valid       Valid          Call far, absolute indirect address given

                                                                in m16:16.



                                                                In 32-bit mode: if selector points to a

                                                                gate, then RIP = 32-bit zero extended

                                                                displacement taken from gate; else RIP

                                                                = zero extended 16-bit offset from far

                                                                pointer referenced in the instruction.



  FF /3             CALL m16:32      Valid       Valid          In 64-bit mode: If selector points to a

                                                                gate, then RIP = 64-bit displacement

                                                                taken from gate; else RIP = zero

                                                                extended 32-bit offset from far

                                                                pointer referenced in the instruction.



  REX.W + FF /3     CALL m16:64      Valid       N.E.           In 64-bit mode: If selector points to a

                                                                gate, then RIP = 64-bit displacement

                                                                taken from gate; else RIP = 64-bit

                                                                offset from far pointer referenced in

                                                                the instruction.

呵呵 解答完毕


2010-10-01 14:39
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
还有个与这个相关的 跳转的问题 搜一下看看 也是我解答的 嘻嘻
2010-10-01 14:39
zongzhitao
Rank: 2
等 级:论坛游民
帖 子:16
专家分:10
注 册:2010-10-1
收藏
得分:0 
谢谢大家乐,我会好好想的,特别谢谢版主和你们都要疼我哦
2010-10-01 14:47
zongzhitao
Rank: 2
等 级:论坛游民
帖 子:16
专家分:10
注 册:2010-10-1
收藏
得分:0 
顺便留个作业

    call $+5
    pop ebx
    sub ebx,$-1

这个 对吗? 自己想想啦
;--------------------------------------------
交作业了,我觉得应该是对的,call &+5正好是pop ebx的地址(这样形容可以吗),sub ebx,$-1也正好是pop ebx
;--------------------------------------------
终于找到我问题的关键了,zklhp 版主说的 刚才call @f的机器码是 E8 00000000,而push @f 的机器码68 05104000     因为带了05104000,所以移动的话会出错。。。。
不知道我的理解是不是
2010-10-01 15:13
你们都要疼我哦
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:火星
等 级:贵宾
威 望:49
帖 子:1296
专家分:2746
注 册:2008-7-13
收藏
得分:0 

站内短消息不好用 以后别发了。

暂时不理解就不必强行理解了。偏离初衷就不好了。以后该明白时自然就明白。
举一才能反三,连举一都不行,就忙着反三是不可能的任务。
先理解透彻那几句吧。
call @F
@@:pop ebx
sub ebx,offset@B

CALL是伪指令,实际运行时会先把下条指令地址入栈,然后才会执行CALL。
而执行CALL既是执行了pop ebx,就把刚才入栈的下条指令地址弹出送入ebx,这个地址
就是pop ebx指令本身的地址 也即标号@@的实际地址。
相信你理解应该没问题。

重定位有2个方面 一是什么地方需要重定位 二是需要修正的差值是多少。
这几句代码的作用就是求得重定位需要的差值。

取得标号@@的实际地址以后,还要取得在默认装载情况下的地址。
这就是offset@B的作用。记得回答类似问题的时候,我反复讲,一定要
注意offset,甚至可以说这个是理解的关键。上午回贴时看到zklhp版主
在上页有个手误的地方,就是这个offset@B编译后的值。他自己发现了。

offset@B在编译时就固定了,以常量的形式存在,如果代码按照默认装载
地址装入,那么就不需要重定位,存在于ebx中的@@标号的实际地址和以常
量的形式存在的offset@B的值相等。
如果没有按照默认地址装载,那么他们的值是不等的,SUB以后就得到了两者
的差值,这个差值最后放在ebx中, 然后用这个差值去修正代码中需要进行
重新定位的数据。

实际装载地址可以每次都不同,即存在于ebx中的@@标号的实际地址可以每次
都不同, 但是offset@B在编译时就固定了,以常量的形式存在,不管实际地址
如何改变,这个值是固定不变的,它表示的就是不需重定位时@@标号的地址。

至于反汇编后的机器码什么的,暂时不必去多看,牵扯到opcode的知识,真要感兴趣可以去看看罗聪的OPCODE系列文章,很不错。

读书百遍,其义自见,多看看书 耐住性子。 象这些很简单的问题,多读读 多想想 多
动动手,不成任何问题的。

在透彻理解的前提下,再去扩展思路去想别的-----至少 如果你能理解sub ebx,offset@B的作用是取得差值的话,你也不会在主贴里想要把offset去
掉而变成实际地址减实际地址永远都是0了 那还有必要搞这几句代码吗?

这也是偶一直以来强调的,汇编语言单条指令查查手册谁都懂,但是重点要放在代码段
上 要放在代码段实现的功能上,
为什么要这几句代码?需要取得重定位需要的差值。
如何取得差值? 通过取得@@标号的实际装载地址,再去和@@标号的默认装载地址相减。
代码段完成后有什么结果? ebx中存放着所需的数据。

偶都成唐僧了, 偶看楼主骨骼清奇 眉清目秀 所以罗嗦半天

小妹,哥哥看你骨骼清奇,绝非凡人,将来必成大业,不如这样,你先把裤裤脱了,待哥哥为你开启灵窍,然后我们一起努力钻研如何
2010-10-02 00:18
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
以下是引用你们都要疼我哦在2010-10-2 00:18:33的发言:


站内短消息不好用 以后别发了。

暂时不理解就不必强行理解了。偏离初衷就不好了。以后该明白时自然就明白。
举一才能反三,连举一都不行,就忙着反三是不可能的任务。
先理解透彻那几句吧。
call @F
@@:pop ebx
sub ebx,offset@B

CALL是伪指令,实际运行时会先把下条指令地址入栈,然后才会执行CALL。
而执行CALL既是执行了pop ebx,就把刚才入栈的下条指令地址弹出送入ebx,这个地址
就是pop ebx指令本身的地址 也即标号@@的实际地址。
相信你理解应该没问题。

重定位有2个方面 一是什么地方需要重定位 二是需要修正的差值是多少。
这几句代码的作用就是求得重定位需要的差值。

取得标号@@的实际地址以后,还要取得在默认装载情况下的地址。
这就是offset@B的作用。记得回答类似问题的时候,我反复讲,一定要
注意offset,甚至可以说这个是理解的关键。上午回贴时看到zklhp版主
在上页有个手误的地方,就是这个offset@B编译后的值。他自己发现了。

offset@B在编译时就固定了,以常量的形式存在,如果代码按照默认装载
地址装入,那么就不需要重定位,存在于ebx中的@@标号的实际地址和以常
量的形式存在的offset@B的值相等。
如果没有按照默认地址装载,那么他们的值是不等的,SUB以后就得到了两者
的差值,这个差值最后放在ebx中, 然后用这个差值去修正代码中需要进行
重新定位的数据。

实际装载地址可以每次都不同,即存在于ebx中的@@标号的实际地址可以每次
都不同, 但是offset@B在编译时就固定了,以常量的形式存在,不管实际地址
如何改变,这个值是固定不变的,它表示的就是不需重定位时@@标号的地址。

至于反汇编后的机器码什么的,暂时不必去多看,牵扯到opcode的知识,真要感兴趣可以去看看罗聪的OPCODE系列文章,很不错。

读书百遍,其义自见,多看看书 耐住性子。 象这些很简单的问题,多读读 多想想 多
动动手,不成任何问题的。

在透彻理解的前提下,再去扩展思路去想别的-----至少 如果你能理解sub ebx,offset@B的作用是取得差值的话,你也不会在主贴里想要把offset去
掉而变成实际地址减实际地址永远都是0了 那还有必要搞这几句代码吗?

这也是偶一直以来强调的,汇编语言单条指令查查手册谁都懂,但是重点要放在代码段
上 要放在代码段实现的功能上,
为什么要这几句代码?需要取得重定位需要的差值。
如何取得差值? 通过取得@@标号的实际装载地址,再去和@@标号的默认装载地址相减。
代码段完成后有什么结果? ebx中存放着所需的数据。

偶都成唐僧了, 偶看楼主骨骼清奇 眉清目秀 所以罗嗦半天

我也是唐僧、、、

很好奇 为嘛您的发言里面加了回车 难道是手机发的 呵呵
2010-10-02 08:53
zongzhitao
Rank: 2
等 级:论坛游民
帖 子:16
专家分:10
注 册:2010-10-1
收藏
得分:0 
你们真早啊,我刚送丫头去上学。。
2010-10-02 09:06
zongzhitao
Rank: 2
等 级:论坛游民
帖 子:16
专家分:10
注 册:2010-10-1
收藏
得分:0 
offset@B在编译时就固定了,以常量的形式存在,如果代码按照默认装载
地址装入,那么就不需要重定位,存在于ebx中的@@标号的实际地址和以常
量的形式存在的offset@B的值相等。
如果没有按照默认地址装载,那么他们的值是不等的,SUB以后就得到了两者
的差值,这个差值最后放在ebx中, 然后用这个差值去修正代码中需要进行
重新定位的数据。
实际装载地址可以每次都不同,即存在于ebx中的@@标号的实际地址可以每次
都不同, 但是offset@B在编译时就固定了,以常量的形式存在,不管实际地址
如何改变,这个值是固定不变的,它表示的就是不需重定位时@@标号的地址。
--------------------------------------------------------------------
感谢你们不厌其烦的为我解答,谢谢你们啦
2010-10-02 09:11
快速回复:看来还是发个帖子求教吧-重定位
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.013121 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved