这是MASM代码:
.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\msvcrt.lib
.code
start:
jmp Debut
Suite:
mov esi, 7706304eh
call esi
jmp 00000000h
Debut:
xor eax, eax
push eax
call Suite
db "C:\WINDOWS\system32\calc.exe"
end start
如您所见,我需要使用与操作码'E9'对应的特殊JMP指令。 但是,似乎使用MASM语法不正确。
我有以下错误消息:
A2076 : Jump destination must specify a label
我知道'jmp _label'有效,但这不是我在这里寻找的东西。所以我尝试了另一种方式,比如“jmp dword ptr ds:00000000h”或'mov eax,00000000h; jmp eax',但生成的操作码与'E9'不匹配。我真的迷失在那种情况面前。有没有人可以请帮帮我?
非常感谢您的帮助。
答案 0 :(得分:0)
如果您只想在代码中发出特定的字节序列(e9和一些零),那么您可以使用db。
答案 1 :(得分:0)
'E9'操作码有'跳短'命令
如果在“jmp”指令(范围-128 ... 127字节)附近定义'label',那么你可以这样写:
jmp short label
label:
如果你想跳转到地址0x00000000,那么你可以使用这种结构,但jmp的操作码(一般情况下)不会等于'E9':
org 0
label0:
...
jmp label0
答案 2 :(得分:0)
OP说:一旦编译了这段代码,我将用有效的地址替换00000000h地址。 ASM代码中存在的地址是在编译代码后保持相同数量的操作码
那么你可能想写的是:
my_jump:
jmp near ptr $ ; produces a 4 byte long relative jump instruction that jmps-to-self
当您知道要跳转的目标地址,并在eax中加载该地址时,您可以编码:
mov eax, .... ; desired target address
sub eax, offset my_jump+4 ; compute relative offset for jmp to get to target
mov dword ptr my_jump+1, eax ; update the jump instructio
这应该有效。它的缺点是自修改代码,在您的操作系统下可能不允许,如果允许,则不被接受为良好实践。
更简单,更好的方法是将所需的目标位置放在众所周知的数据位置,并修改代码以使用它:
.data
target_location dword 0 ; filled in later
.code
Suite:
mov esi, 7706304eh ; hardwiring this constant is bad practice, too, but you didn't ask about that
call esi
mov esi, target_location
jmp esi
这段代码不是自修改的,汇编程序中的这种技巧很常见。