JMP指令不使用MASM32编译

时间:2013-11-26 22:06:15

标签: assembly x86 masm opcode masm32

这是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'不匹配。我真的迷失在那种情况面前。有没有人可以请帮帮我?

非常感谢您的帮助。

3 个答案:

答案 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

这段代码不是自修改的,汇编程序中的这种技巧很常见。