jmp 远跳转绝对地址是怎么计算的?

VirtualRookit 2011-03-23 06:27:29
010BCDF3 6A 00 push 0
010BCDF5 6A 00 push 0
010BCDF7 6A 00 push 0
010BCDF9 6A 00 push 0
010BCDFB 68 03 CE 0B 01 push offset label_1 (10BCE03h)
010BCE00 FF 65 EC jmp dword ptr [hProc]
label_1:


//如上代码 hProc为MessageBoxA的地址..请问
010BCE00 FF 65 EC jmp dword ptr [hProc]
单步执行后如下:
76C4EA71 8B FF mov edi,edi
76C4EA73 55 push ebp

问: 绝对跳转地址新EIP(76C4EA71)是怎么由旧EIP(010BCE00 FF 65 EC)计算出来的?
就是绝对地址的计算方法(别讲些相对地址的计算方法,这个我懂)。哪位大牛给指点下,谢谢。
...全文
1549 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
VirtualRookit 2011-03-29
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zara 的回复:]
上面 microDebug 的说法不对吧。这个 FF 65 EC 的 jmp 指令是 jmp dword ptr [ebp-14h] ,[ebp-14h] 一般是个局部变量嘛,其在源程序里的标号应该是 hProc 。从这段代码的作用来看,hProc 里保存了 MessageBoxA() 函数的入口地址,如果这个地址是在编译链接阶段就确定了的话,它就不可能存在于 [ebp-14h] 这样的局部变量所……
[/Quote]

对不起,各位,我以为这贴没人答了,所以几天没上。
哥们,你解了我的疑问:
FF 65 EC 的 jmp 指令是 jmp dword ptr [ebp-14h]
我对机器码到汇编的翻译不是懂很多,原先以为 FF(jmp) 65(长跳型) EC(问题就卡在EC),原先以为EC是跳转距离,通过一定算法计算出来的,现在才知道,原来这地址是从栈ebp-14h取出来的,也就是65与EC是一块的,其汇编意义即dword ptr [ebp-14h]..终于明白咯...至于那些啥导出表,重定位,静、动态链接的俺都懂,不会困在那咯。另,一并感谢各位。
jesterjy 2011-03-28
  • 打赏
  • 举报
回复
目标地址 - 当前地址 - 指令长度 = JMP后的偏移
lih618 2011-03-25
  • 打赏
  • 举报
回复
MessageBoxA是API函数,系统在运行EXE时会将程序所需要的所有DLL映射到EXE的运行空间中,所有涉及DLL中函数的地址都是系统计算的,EXE中有一张DLL导入表,程序调用DLL时是根据表中的地址进行调用的,系统在载入EXE时会修改表的内容
lih618 2011-03-25
  • 打赏
  • 举报
回复
window下程序使用的都是虚拟内存地址,通过系统查找内存页表和段表对虚拟地址进行换算之后才能生成物理地址
至于跳转地址,是汇编程序在汇编时计算的啊,汇编程序会将代码中所有的跳转根据汇编后的代码位置进行地址换算
microDebug 2011-03-25
  • 打赏
  • 举报
回复
说细一点吧,以下是一个debug版本的调用过程,其实,不管是静态还是动态,调用外部DLL时都是一样的:

0041139f 8bf4 mov esi,esp
004113a1 6a00 push 0
004113a3 683c574100 push offset Mes!`string' (0041573c)
004113a8 683c574100 push offset Mes!`string' (0041573c)
004113ad 6a00 push 0
004113af ff1530834100 call dword ptr [Mes!_imp__MessageBoxW (00418330)] ds:0023:00418330={USER32!MessageBoxW (77d66534)}
004113b5 3bf4 cmp esi,esp

观察这句:ff1530834100 call dword ptr [Mes!_imp__MessageBoxW (00418330)]
其实就是CALL 到了这个地址上00418330(在内存显示为30834100)。因为LZ给的代码是构造的代码,所以用JMP来实现了,事实上,可以用JMP来构造一个CALL。

现在看00418330地址的内容:
0:000> dd 00418330
00418330 77d66534 00000000 00000000 00000000
00418340 00000000 00000000 00000000 00000000
00418350 00000000 00000000 00000000 00000000
00418360 654d0215 67617373 786f4265 53550057
00418370 32335245 6c6c642e 01210000 5452435f
00418380 4354525f 494e495f 00005754 635f021b
00418390 69666e6f 72687467 6c646165 6c61636f
004183a0 01c70065 65735f5f 65737574 74616d72

JMP过去,就是77d66534,也就是ds:0023:00418330={USER32!MessageBoxW (77d66534)}的地址。

LZ大概想了解的就是:为什么CALL 00418330地址,EIP却跳到了77d66534地址上。就是这个道理了。

以上是静态调用的,动态调用也是一样,只是,将这里的00418330内容,放到了一个[ebp-xx]局部变量里。





microDebug 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zara 的回复:]
上面 microDebug 的说法不对吧。这个 FF 65 EC 的 jmp 指令是 jmp dword ptr [ebp-14h] ,[ebp-14h] 一般是个局部变量嘛,其在源程序里的标号应该是 hProc 。从这段代码的作用来看,hProc 里保存了 MessageBoxA() 函数的入口地址,如果这个地址是在编译链接阶段就确定了的话,它就不可能存在于 [ebp-14h] 这样的局部变量所……
[/Quote]

zara分析的仔细,FF 65 EC 反汇编后确实是引用了一个局部变量。
这说明,在这段程序里调用MessageBoxA的方法是动态调用的;
我上面说的是静态链接的情况。
zara 2011-03-25
  • 打赏
  • 举报
回复
上面 microDebug 的说法不对吧。这个 FF 65 EC 的 jmp 指令是 jmp dword ptr [ebp-14h] ,[ebp-14h] 一般是个局部变量嘛,其在源程序里的标号应该是 hProc 。从这段代码的作用来看,hProc 里保存了 MessageBoxA() 函数的入口地址,如果这个地址是在编译链接阶段就确定了的话,它就不可能存在于 [ebp-14h] 这样的局部变量所处的堆栈空间里,它应该是由上面的代码根据个什么手段获得而填入到这个变量里(从这个程序的类型来说,往往都是通过 LoadLibrary() 载入所在的模块,然后查看其导出函数表,找到对应的入口地址,进行基址修正而得到当前实际的入口地址),再被该 jmp 指令所引用的。另外,由导入函数方式确定的地址,在编译链接阶段也只是个猜测的可能的值,真正的实际值是在程序载入时被校正的,这是因为不同环境、不同版本的系统,对应于同一函数,其入口地址也可能不一样。
tanqing900920 2011-03-25
  • 打赏
  • 举报
回复
同意microDebug的说法,这里面有个类似8051PC(Programme Counter)的计数器,在编译的时候将标号和jump的字节数差值(补码)填入后面的字节, 在EXE里面是不会识别标号的,只认识相对位移(字节差),exe只是简单的跳好多个字节,明白?(其实这里面还有两个类别:前跳和后跳,两个方式有点区别哦)
microDebug 2011-03-25
  • 打赏
  • 举报
回复
补充一下:可以用IDA工具查看生成的EXE文件里的import table表验证。

另外LZ你用的是DEBUG版本,已经带符号了,如果是release版本,那这句jmp dword ptr [hProc]
就应该是 jmp dword ptr XXXXXXXX地址的样子
microDebug 2011-03-25
  • 打赏
  • 举报
回复
如果想确定的话,可以用IDA等工具打开EXE工具,查看import table表验证,呵呵
microDebug 2011-03-25
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 lih618 的回复:]
MessageBoxA是API函数,系统在运行EXE时会将程序所需要的所有DLL映射到EXE的运行空间中,所有涉及DLL中函数的地址都是系统计算的,EXE中有一张DLL导入表,程序调用DLL时是根据表中的地址进行调用的,系统在载入EXE时会修改表的内容
[/Quote]
答非所问!

客观一点来说,LZ你的问题是一个编译器link的问题;
10BCE00 FF 65 EC jmp dword ptr [hProc];这句是一个绝对地址跳转,但它不是在运行时计算出来的;而是在编译的时候已经确定了的;

MessageBoxA是User32.dll中的函数,对它的链接默认都是static链接;编译时,引用到外部DLL的export table的函数,都会在生成的exe的import table文件中记录下来。在程序运行时,就直接JMP过去了。

程序运行过程中的相对跳转(进跳转,远跳转)比较频繁,但是绝对跳转除了外部干预(指inject代码),大多都是在编译的时候就确定了的。这也就是为什么需要重定位,为什么会存在相对跳转的意义了。

建议LZ补全知识体系的结构。

9,513

社区成员

发帖
与我相关
我的任务
社区描述
Windows专区 安全技术/病毒
社区管理员
  • 安全技术/病毒社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧