Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly JMP到绝对地址(操作码) 我试图编写一个EXE打包器/保护器,作为学习汇编程序、C++和PE文件工作的一种方式。我现在已经让它工作了,所以包含EP的部分用一个密钥XORD,并创建了一个包含我的解密代码的新部分。除了解密后我尝试和JMP到原始EP之外,一切都很顺利_Assembly_X86_Executable_Masm_Opcode - Fatal编程技术网

Assembly JMP到绝对地址(操作码) 我试图编写一个EXE打包器/保护器,作为学习汇编程序、C++和PE文件工作的一种方式。我现在已经让它工作了,所以包含EP的部分用一个密钥XORD,并创建了一个包含我的解密代码的新部分。除了解密后我尝试和JMP到原始EP之外,一切都很顺利

Assembly JMP到绝对地址(操作码) 我试图编写一个EXE打包器/保护器,作为学习汇编程序、C++和PE文件工作的一种方式。我现在已经让它工作了,所以包含EP的部分用一个密钥XORD,并创建了一个包含我的解密代码的新部分。除了解密后我尝试和JMP到原始EP之外,一切都很顺利,assembly,x86,executable,masm,opcode,Assembly,X86,Executable,Masm,Opcode,基本上我是这样做的: DWORD originalEntryPoint = optionalHeader->AddressOfEntryPoint; // -- snip -- // crypted.put(0xE9); crypted.write((char*)&orginalEntryPoint, sizeof(DWORD)); 但是,ollydbg并没有跳转到入口点,而是将此代码反汇编为: 00404030 .-E9 00100000 JMP 0040

基本上我是这样做的:

DWORD originalEntryPoint = optionalHeader->AddressOfEntryPoint;
// -- snip -- //
    crypted.put(0xE9);
 crypted.write((char*)&orginalEntryPoint, sizeof(DWORD)); 
但是,ollydbg并没有跳转到入口点,而是将此代码反汇编为:

00404030   .-E9 00100000    JMP 00405035 ; should be 00401000 =[
当我试图在olly中手动更改它时,新的操作码显示为

00404030    -E9 CBCFFFFF    JMP crypted.00401000

0xCBCFFFFF来自哪里?我如何从C++方面生成这个?

我认为 E9< /Cl>是相对跳跃的操作码:它的操作数指定了一个相对的跳跃距离,从下一个指令开始的正或负。 如果希望操作数指定绝对地址,则需要不同的操作码。

可以使用:

push DESTINATION_VA
ret

相对E9 jmp编码的使用方式如下:

CURRENT_RVA: jmp (DESTINATION_RVA - CURRENT_RVA - 5 [sizeof(E9 xx xx xx xx)])

如果您有VA地址且图像未重新定位,则push+ret是最佳解决方案

绝对间接跳转的操作码为FF+4字节地址。这通常用于数据中存储的地址跳转表

绝对地址在未加载到预期地址时需要重新定位,因此通常首选相对地址。相对跳转的代码也要小2个字节

Intel optimization manual声明cpu期望call和ret成对使用,因此回答2中建议的没有调用的ret将导致所谓的“性能损失”


此外,如果代码没有加载到编译器假定的相同地址,ret可能会使程序崩溃。计算相对地址会更安全。

关于E9的替代品有什么想法吗?跳转通常是相对的。有一个用于跳转到绝对远地址的操作码
EA
,还有一个用于跳转到间接地址的操作码(操作数指定包含要跳转到的地址的内存位置)。这并没有回答问题,只是确认OP的答案是错误的。@baordog问题是,“0xCBCFFFFF来自哪里?“无论如何,OP显然理解答案,并且/或者对评论中的
EA
感到满意。也许你的意思是FF 25 4字节.”。。FF 4字节毫无意义。@Laie它仍然有意义,因为
FF
是操作码,我们知道助记符是
jmp
。它可以是
FF/4
FF/5
,因为它们都是绝对间接跳,一个是近跳,另一个是远跳。但是,是的,
FF 25 aa bb cc dd
是您在机器代码中观察到的
FF/4
(两者中较常见的一种)。最后一段不正确:
push imm32
/
ret
不会崩溃,重新定位代码不会更改
ret
跳转到的绝对目标地址。问题在于性能:不平衡返回地址堆栈将导致某些未来的返回预测失误。如果出于某种原因,您不能仅从已知地址对
jmp rel32
进行编码,那么
mov reg,imm32
+2字节寄存器间接跳转可能是您最好的选择(而不是从内存加载指针)。如果能为64位模式提供一个匹配的jmp操作码,那就太好了。我正在为64位地址空间寻找一个类似的方法,带有操作码。@ThomasTempelmann:covers x86-64。用
push
/
ret
解决了严重的性能问题,但不幸的是海报将其回滚。如果您关心现代x86上的性能,请使用
mov-eax,dst
/
jmp-eax
,而不是使用与
调用不匹配的
ret
()来平衡返回地址预测器。和/或见
mov
/
jmp
与推送相比额外花费1个字节,避免了未来的分支预测失误。如果您从目标客户那里获得了ret
,那么在RE.SE有一个类似的问题,我提供了一个非常详细的解释:
CURRENT_RVA: jmp (DESTINATION_RVA - CURRENT_RVA - 5 [sizeof(E9 xx xx xx xx)])