I want to make a jump like this in my MASM program (32-bit, flat, win32):

jmp 854fc488h

But MASM just refuses to do this (I tried lots of variations of that jump instruction too, but all in vain), and tells me "jump destination must specify a label".

Isn't there anyway to go around this (except building the instruction by hand)?


It seems strange that MASM should prevent people from doing things like this. A warning would probably be good, but not just complete refusal. :(


If my only choice is to build the instruction by hand, could anyone help me with that? I assume I would use the 0EAh opcode, but I don't understand how it encodes the segments in that instruction, so I haven't been able to do even that. :(


Any tips would be appreciated.

Thanks!


PS.
I know I can do it like this:


mov eax, 854fc488h
jmp eax

but it would be interesting to know if I can do it with one instruction anyway.
Posted on 2003-02-12 11:21:45 by dELTA
.data
JmpAddy dd 854fc488h

.code
jmp JmpAddy
Posted on 2003-02-12 13:39:02 by dionysus
No, that's cheating (not to mention the extra memory reference and the 4 extra bytes). :) It's the absolute direct jump instruction that I'm after.
Posted on 2003-02-12 14:32:09 by dELTA
I've posted two methods to do so.
Try search.
Posted on 2003-02-12 14:41:43 by The Svin
Posted on 2003-02-12 15:04:13 by dionysus
dionysus,
Thanks for the link, but that thread only discussed how to use the relative opcode to perform an absolute jump, but I'd like to know how to us the direct opcode (EA). :(

The Svin,
I did not find the posts you are talking about. I think it can be quite hard to find such specific things (lacking specific characteristic words) with the board search feature (either I get 500 threads to read through in search for it, or I get 0 hits :(). I found one post where it was said that the segment part in the EA opcode could be set to 0227 (or 2702) in Win9x, but it didn't work either. :(
Posted on 2003-02-12 16:07:16 by dELTA
you need a segment prefix for that, so code

jmp dword ptr ds:854fc488h


coding a jump with E9h opcode is more difficult because operant isn't an absolute address.

you may write:

externdef xxx:abs
jmp near xxx

and declare xxx in another source file (with "xxx equ 8000000h" for example) but results are pretty strange

Posted on 2003-02-12 16:19:28 by japheth
That compiles to an indirect jump (FF opcode), and hence does not land at the specified address. :(
Posted on 2003-02-12 16:47:58 by dELTA
Try jmp far xxxxxxxx
Posted on 2003-02-12 17:02:12 by mrgone
Nope, it gives "missing operator in expression" from the compiler. :(
Thanks for the try anyway. :)
Posted on 2003-02-12 17:15:32 by dELTA
dELTA,

I think you have asked this question before but the format of seperate memory space for each app controlled by the OS prevents absolute memory addressing. If you have an address you wish to jump to, use either,


mov eax, 12345678 ; hard coded address
jmp eax

or

push 12345678 ; hard coded address
ret

The first is preferred as it does not mess up the CALL RET pairing on later processors.

Regards,

hutch@movsd.com
Posted on 2003-02-12 17:57:38 by hutch--
Thanks hutch, I just noted that I had asked a quite similar question before. Although the two questions look very similar here, they are quite different in my head. :) You see, this time I mostly wanted to get the EA opcode to work with any ugly hack, but before it was about getting a more stable solution for absolute calls, which could be used in any program. That's why I didn't connect the two postings in my head. I'm sorry for the near dupes anyway. :(
Posted on 2003-02-12 18:07:33 by dELTA

Thanks for the link, but that thread only discussed how to
use the relative opcode to perform an absolute jump,
but I'd like to know how to us the direct opcode

Your mnemonic says that you trying to use relative jmp.
32 imm. value with jmp - is relative jump, and it is not
about MASM - it is about i32 opcode format.
So the thread is exactly about what you tried to do.
'Cause what you post here is "partial" address - 32 bit displacement
in offset. And can be used only with relative jump.

Direct (if you mean by direct that imm. value = virtual addr)
using 48 bit value.
Now about "segment part" that doesn't work for:
Tell precisely:
1. What was OS?
2. What exactly did you write?
3. How did you figure out that it didn't work?
Posted on 2003-02-12 19:18:02 by The Svin
1.
The OS is Windows 98 (SE).

2.
I have pretty much tried to write any variation of jmp I can think of, and it always gets compiled into either a direct relative or indirect relative jmp (or not compile at all, but give an error).
To get a jmp using the EA opcode I've had to build it manually with db entries, but then I don't know what segment to give as an operand. :(

3.
I have verified that it does not work by looking at the compiled opcodes in my debugger, and executing them there.


One big problem is that I have never really understood the concept of segments in Windows. :( When tracing any program in e.g. SoftIce, all the code always seems to be in the same segment anyway, including code in any dll, even kernel32 and so on. Does anyone have some kind of explanation to make me understand this segment stuff better?

All I want to do in this case is to "jump to the address xxxxxxxx in the same code segment as I am currently in", using only one such absolute direct jump (EA opcode).

The problem here seems to be to know that correct segment number at compile time? Is this number always the same while running in the same operating system version? Is there any opcode prefix or something, to make an instruction use "the same segment as the current one" for instructions that want a segment as an operand?

What I was originally trying to do in my program was to make an absolute jump to the address of the ExitProcess API (I know that using a fixed address to an API will only work for my exact version of the operating system, but it is only a quick hack for debug purposes, which will also later be patched/overwritten in memory with something else). But please don't say that it can be done in a much better way, because I know there a lots of ways around it, but what I'm interested in is this EA instruction, and the theory/problems of segments in Windows.

Any help or comments about this would be much appreciated.

Thanks!
Posted on 2003-02-13 06:25:35 by dELTA
Use FASM instead MASM. :)
In FASM you can write:

jmp 123456h

and it will be assembled write way.
I think in MASM and TASM you can't do this without some tricks.
Posted on 2003-02-13 10:18:04 by JohnFound
Delta,
you said it doesn't work.
Could you just write line of code that doesn't work
with segemt part?
try include this macro:


absjmp macro addr
ifdef NT
db 0EAh
dd addr
dw 01Bh
else
db 0EAh
dd addr
dw 227h
endif

don't define NT anywhere.
in code write
absjmp 410000h ; for example

I used it in both NT,95 and 98 it worked.
Posted on 2003-02-13 14:28:32 by The Svin
Thanks The Svin, but that's exactly what I've tried before, and it doesn't work for me. :( As soon as that instruction is executed I get an access violation, even though I'm just trying to jump to the address which is directly after the jump instruction. :(

This is how the instruction looks in my debugger (it doesn't work if I run without a debugger either though):



00401000 EA 07104000 2702 JMP FAR 0227:00401007
00401007 60 PUSHAD
00401008 ...


Any ideas?
Posted on 2003-02-14 05:23:26 by dELTA
ok you got me interested for a few min so I made a prog that shows it working]
if you want you can hardcode the "addr1", but i think your problem is that you need to update your "cs1" value to reflect the current cs register




.486
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
EA BYTE 0EAh
addr1 DWORD 00000000h
cs1 WORD 0000h
msg DB "it worked",0
.code
start:
mov eax,OFFSET trial
mov addr1,eax
mov cs1,cs
mov eax,offset EA
jmp eax
INVOKE ExitProcess,NULL
trial proc
INVOKE MessageBox,NULL,OFFSET msg,OFFSET msg,MB_OK
INVOKE ExitProcess,0
trial endp
End start
Posted on 2003-02-14 14:02:20 by dionysus

Thanks The Svin, but that's exactly what I've tried before, and it doesn't work for me. :( As soon as that instruction is executed I get an access violation, even though I'm just trying to jump to the address which is directly after the jump instruction. :(

This is how the instruction looks in my debugger (it doesn't work if I run without a debugger either though):



00401000 EA 07104000 2702 JMP FAR 0227:00401007
00401007 60 PUSHAD
00401008 ...


Any ideas?


Shouldn't the address you're jumping to be aligned on a DWORD boundry and not an odd one?
Posted on 2003-02-14 14:18:01 by Mecurius
Thanks for the code dionysus. Although, I already suspected that such a method would work, but it is not really a "static jump" since it is using runtime information (the cs value). :( I want a single EA instruction that can be build at assemble time, and then directly executed without any other code to support it. :( The problem is this cs value. Is it different every time, or what? As far as I know it should be the same in all 9x versions, but the number reported earlier does not seem to be correct? Hmm, I will look in my debugger which number it is by copying cs, like you do in your code, and then try to hardcode this number.

And Mecurius, I don't know anything about that, but wouldn't that be a little strange, since instructions are not aligned in any way in the x86 architecture?
Posted on 2003-02-14 17:04:51 by dELTA