I want to make a jump like this in my MASM program (32-bit, flat, win32):
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:
but it would be interesting to know if I can do it with one instruction anyway.
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.
.data
JmpAddy dd 854fc488h
.code
jmp JmpAddy
JmpAddy dd 854fc488h
.code
jmp JmpAddy
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.
I've posted two methods to do so.
Try search.
Try search.
heres a cool thread on it dELTA
http://www.asmcommunity.net/board/index.php?topic=5505&highlight=jmp
http://www.asmcommunity.net/board/index.php?topic=5505&highlight=jmp
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. :(
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. :(
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
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
That compiles to an indirect jump (FF opcode), and hence does not land at the specified address. :(
Try jmp far xxxxxxxx
Nope, it gives "missing operator in expression" from the compiler. :(
Thanks for the try anyway. :)
Thanks for the try anyway. :)
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,
The first is preferred as it does not mess up the CALL RET pairing on later processors.
Regards,
hutch@movsd.com
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
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. :(
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?
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!
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!
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.
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.
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:
don't define NT anywhere.
in code write
absjmp 410000h ; for example
I used it in both NT,95 and 98 it worked.
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.
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):
Any ideas?
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?
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
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
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?
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?
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?