Pedro
Pedro

Reputation: 21

Improper operand type error __asm

LEA EDX,DWORD PTR SS:[EBP-0x810]
PUSH EDX
LEA EAX,DWORD PTR SS:[EBP-0x80C]
PUSH EAX
PUSH DWORD PTR SS:[EBP+0x8]
CALL HKD_GetTeleportPosition
ADD ESP, 0xC

CMP EAX, -1
JNZ 0x42891B

LEA EDX,DWORD PTR SS:[EBP-0x810]
MOV EAX, 0x042890B
JMP EAX

In JNZ 0x42891B I get the error. What's wrong? I don't have any idea.

Upvotes: 0

Views: 1481

Answers (2)

Peter Cordes
Peter Cordes

Reputation: 363980

x86 has no absolute near jump encoding. If you know the current value of CS, you could in theory use far jmp ptr16:32, but that's probably slower than any of the alternatives.


If your assembler won't do the math for you to calculate the relative displacement to a given absolute address, you could try to encode it yourself (except I tested with NASM, and this doesn't work):

;; DOESN'T WORK in NASM or YASM, maybe try in MASM / MSVC
db 0x0F, 0x85              ; The opcode for JNZ rel32
dd 0x42891B - ($+4)        ; The rel32 itself, from the end of the JNZ.

$ is the current output position, not including the current instruction. (But jump displacements are from the end of the instruction).

In theory this is possible in position-dependent code (that knows its own address at link time), but there may not be assembler / linker support for it.

YASM won't assemble that (error: data expression too complex). NASM 2.13.01 will assemble it, but treats it as if $ = 0. So it branches forward by 0x42891B - 4 bytes. In the linked binary, I get 400093: 0f 85 93 00 40 00 jne 80012c

I don't have MASM or MSVC, so it might be worth trying there.


The flexible alternative (using a register-indirect JMP)

    CMP   EAX, -1
    jz    @nojump
    mov   ecx, 0x42891B   ; pick any register that you can clobber here
    jmp   ecx
@nojump:

Upvotes: 1

Fifoernik
Fifoernik

Reputation: 9899

In JNZ 0x42891B i get the error, what's wrong? I dont have no ideia

It's conceivable that an assembler could accept JNZ 0x42891B as a valid instruction. It would calculate the distance between the absolute address that you provided and the location where this instruction sits and then encode the correct relative address. Your assembler apparantly does not!

On most assemblers the operand for a conditional branch is expressed as a label.

  CMP EAX, -1
  JNZ YourTarget

  LEA EDX,DWORD PTR SS:[EBP-0x810]
  MOV EAX, 0x042890B
  JMP EAX

YourTarget:
  ...

Upvotes: 2

Related Questions