Dan*_*las 7 assembly winapi x86-64
在解决错误时,我遇到了两个Win64 DLL的导入跳转表之间的区别.64位版本在其导入跳转表中kernel32.dll使用普通FF25 jmp指令.另一方面,64位版本的advapi32.dll使用48FF25指示jmp操作码REX.w=1之前的前缀.但是,两者似乎都有32位操作数指定RIP +偏移地址.
这个特定的操作码对REX.w前缀有什么意义吗?
我不经常使用机器代码,所以请原谅任何事实错误.
REX.W前缀被忽略.在64位模式下,FF /4操作码始终具有64位操作数(JMP r/m64),因此操作数大小更改前缀(REX.W,66)无效.
这个REX.W前缀存在的原因可能是符合Microsoft的x64调用约定关于展开的规则.跳转导入存根实际上是一个指令函数,由于Windows上的异常是异步的,它们可以随时发生,执行此函数时可能会生成异常.Microsoft 对函数开头和结尾使用的指令施加了许多限制.特别是该函数必须以仅包含某些指令的结尾结束.根据Kevin Frei在MSDN上的博客,如果最后一条指令是间接跳转,它必须使用REX.W前缀:
另外注意:如果最终的jmp不是ip-relative jmp,而是间接jmp,则它必须以REX前缀开头,以向操作系统指示展开跳转到函数外部的例程,否则,操作系统假设它跳转到同一功能内的不同位置.
使用REX.W之间的不一致可能是因为上面描述的这个规则与Microsoft官方文档对最终JMP指令的要求并不完全一致:
在epilog中只允许jmp语句的子集.这些只是具有ModRM内存引用的jmp类,其中ModRM mod字段值为00.禁止在具有ModRM mod字段值01或10的epilog中使用jmps.
请注意,因为这将排除不使用ModR/M编码的相对JMP指令,这是结束函数的最常见的JMP类型,所以我倾向于认为这是正确的官方文档.
不一致的其他可能原因是Microsoft的unwinder专门处理导入跳转存根或者没有REX.W前缀的跳转存根是一个错误,并且会导致程序在非常不可能的情况下终止,当他们发生异常时重新执行.
| 归档时间: |
|
| 查看次数: |
1329 次 |
| 最近记录: |