Dear Gurus,
I encountered such a problem: How to hardcode an unconditional jump in
64-bit mode?
For instance, I want to jump to 0x1122334455667788 from current RIP.
What is the machine code of this instruction?
I have referenced Intel and AMD's manuals, but found no information
available.
Hope anybody here can give me a solution, Thanks in advance.
|
|
0
|
|
|
|
Reply
|
xmllmx
|
9/24/2008 5:57:11 AM |
|
I think you can use 0ea to have a try, i.e. define a descriptor, set
the base address, limit, attribute, etc. Then define a macro like this
%macro JUMP 2
db 0eah
dw %1 ;base
dw %2 ;offset
%endmacro
when u need a jump, u can use JUMP selector(selector of your
descriptor),offset of your code label. 0x1122334455667788 for
instance, u can put it into the descriptor, and set the offset as 0,
then JUMP selector, 0
|
|
0
|
|
|
|
Reply
|
buaacss
|
9/24/2008 12:52:01 PM
|
|
"buaacss" suggested:
>I think you can use 0ea to have a try, i.e. define a descriptor, set
> the base address, limit, attribute, etc. Then define a macro like this
> %macro JUMP 2
> db 0eah
> dw %1 ;base
> dw %2 ;offset
> %endmacro
> when u need a jump, u can use JUMP selector(selector of your
> descriptor),offset of your code label. 0x1122334455667788 for
> instance, u can put it into the descriptor, and set the offset as 0,
> then JUMP selector, 0
A lesser detouring, but also heavy time consuming method:
push 55667788h
push 11223344h
ret
a bit better by keeping CALL/RET pairing alive:
push 55667788h
push 11223344h
call qword[rsp]
ret 8
the best method seem to be:
jmp qword[mem/reg]
or faster, but needs one register
mov rax,1122334455667788h
jmp rax
__
wolfgang
|
|
0
|
|
|
|
Reply
|
Wolfgang
|
9/24/2008 1:49:34 PM
|
|
xmllmx wrote:
> Dear Gurus,
>
> I encountered such a problem: How to hardcode an unconditional jump in
> 64-bit mode?
>
> For instance, I want to jump to 0x1122334455667788 from current RIP.
> What is the machine code of this instruction?
>
> I have referenced Intel and AMD's manuals, but found no information
> available.
>
> Hope anybody here can give me a solution, Thanks in advance.
>
I presume you want to jump to an arbitrary 64-bit address, and not just
±2 GB (otherwise just use a plain JMP).
There are a few ways to do it.
a) Use a register:
mov eax,0x1122334455667788
jmp eax
b) Use the stack (this might screw up your CPU's call/ret stack, which
would result in a performance penalty):
push dword 0x11223344
push dword 0x55667788
ret
c) Use a "fake immediate", which is really a data reference:
jmp [rel foo]
foo: dq 0x1122334455667788
The byte encoding is FF 25 00 00 00 00 followed by the 64-bit absolute RIP.
Here is a NASM macro for this:
%macro jmpq 1.nolist
%push
%assign %$where %1
jmp [rel %$ptr]
%$ptr: dq %$where
%pop
%endmacro
-hpa
|
|
0
|
|
|
|
Reply
|
H
|
9/25/2008 12:59:21 AM
|
|
On Sep 24, 5:59�pm, "H. Peter Anvin" <spamt...@crayne.org> wrote:
....
> b) Use the stack (this might screw up your CPU's call/ret stack, which
> � � would result in a performance penalty):
>
> � � � � push dword 0x11223344
> � � � � push dword 0x55667788
> � � � � ret
In 64-bit mode you can only push and pop 64-bit and 16-bit values
because the default operand size for stack operations is 64 bits and
there's no prefix to override the size to 32 bits, just 16.
Alex
|
|
0
|
|
|
|
Reply
|
Alexei
|
9/25/2008 4:44:18 AM
|
|
Alexei A. Frounze detected:
> H. Peter Anvin wrote:
> ...
>> b) Use the stack (this might screw up your CPU's call/ret stack, which
>> would result in a performance penalty):
>> push dword 0x11223344
>> push dword 0x55667788
>> ret
> In 64-bit mode you can only push and pop 64-bit and 16-bit values
> because the default operand size for stack operations is 64 bits and
> there's no prefix to override the size to 32 bits, just 16.
Right, and I fell into the same trap with my untested reply to buaccss.
AMD says:
PUSH imm8 6A +ib Push an 8-bit immediate value
(sign-extended to 16, 32,or 64 bits)
PUSH imm16 68 +iw Push a 16-bit immediate value
PUSH imm32 68 +id Push a 32-bit immediate value
***(No prefix for encoding this in 64-bit mode.)***
***
PUSH imm64 68 +id Push a "32 bit sign-extended to 64 bit"
***
Sorry for I added confusion
__
wolfgang
|
|
0
|
|
|
|
Reply
|
Wolfgang
|
9/25/2008 9:22:25 AM
|
|
Alexei A. Frounze wrote:
> On Sep 24, 5:59 pm, "H. Peter Anvin" <spamt...@crayne.org> wrote:
> ...
>> b) Use the stack (this might screw up your CPU's call/ret stack, which
>> would result in a performance penalty):
>>
>> push dword 0x11223344
>> push dword 0x55667788
>> ret
>
> In 64-bit mode you can only push and pop 64-bit and 16-bit values
> because the default operand size for stack operations is 64 bits and
> there's no prefix to override the size to 32 bits, just 16.
>
Erk, you're right -- brainfart on my part. The immediate form won't
work, of course, since the immediate is still only 32 bits long.
-hpa
|
|
0
|
|
|
|
Reply
|
H
|
9/25/2008 9:46:26 AM
|
|
On Sep 25, 2:46�am, "H. Peter Anvin" <spamt...@crayne.org> wrote:
> Alexei A. Frounze wrote:
> > On Sep 24, 5:59 pm, "H. Peter Anvin" �<spamt...@crayne.org> wrote:
> > ...
> >> b) Use the stack (this might screw up your CPU's call/ret stack, which
> >> � � would result in a performance penalty):
>
> >> � � � � push dword 0x11223344
> >> � � � � push dword 0x55667788
> >> � � � � ret
>
> > In 64-bit mode you can only push and pop 64-bit and 16-bit values
> > because the default operand size for stack operations is 64 bits and
> > there's no prefix to override the size to 32 bits, just 16.
>
> Erk, you're right -- brainfart on my part. �The immediate form won't
> work, of course, since the immediate is still only 32 bits long.
Nor will non-immediate (PUSH r/m32 FF /6, PUSH r32 50+rd, PUSH 32-bit
FS/GS 0F A0/A8) -- they all aren't encodable because of the default
operand size being 64 and not 32. If it was 32, you'd be able to
double or halve it using the appropriate prefix, but when it's already
64, you can only go down to 16.
Alex
|
|
0
|
|
|
|
Reply
|
Alexei
|
9/25/2008 10:18:02 AM
|
|
"Alexei A. Frounze" <spamtrap@crayne.org> wrote in message
news:74d36e56-c25e-45a7-9000-ab4c32bbcb8a@c36g2000prc.googlegroups.com...
> On Sep 24, 5:59 pm, "H. Peter Anvin" <spamt...@crayne.org> wrote:
> ...
> > b) Use the stack (this might screw up your CPU's call/ret stack, which
> > would result in a performance penalty):
> >
> > push dword 0x11223344
> > push dword 0x55667788
> > ret
>
> In 64-bit mode you can only push and pop 64-bit and 16-bit values
> because the default operand size for stack operations is 64 bits and
> there's no prefix to override the size to 32 bits, just 16.
>
...."can only push and pop 64-bit and 16-bit values"...
Well, I'd say: Not so! :-)
Are you saying there is no 'push imm8' instruction in 64-bit mode? ;-)
All values are pushed as 64-bits (or "virtual" 64-bits) since that's the
stack size.
Rod Pemberton
|
|
0
|
|
|
|
Reply
|
Rod
|
9/25/2008 2:21:13 PM
|
|
On Sep 25, 7:21�am, "Rod Pemberton" <spamt...@crayne.org> wrote:
> "Alexei A. Frounze" <spamt...@crayne.org> wrote in messagenews:74d36e56-c25e-45a7-9000-ab4c32bbcb8a@c36g2000prc.googlegroups.com...
>
> > On Sep 24, 5:59 pm, "H. Peter Anvin" �<spamt...@crayne.org> wrote:
> > ...
> > > b) Use the stack (this might screw up your CPU's call/ret stack, which
> > > would result in a performance penalty):
>
> > > push dword 0x11223344
> > > push dword 0x55667788
> > > ret
>
> > In 64-bit mode you can only push and pop 64-bit and 16-bit values
> > because the default operand size for stack operations is 64 bits and
> > there's no prefix to override the size to 32 bits, just 16.
>
> ..."can only push and pop 64-bit and 16-bit values"...
>
> Well, I'd say: �Not so! �:-)
>
> Are you saying there is no 'push imm8' instruction in 64-bit mode? �;-)
You know what I'm saying -- there's no PUSH instruction that when
applied once in 64-bit mode will place exactly 4 bytes worth of data
onto the stack.
> All values are pushed as 64-bits (or "virtual" 64-bits) since that's the
> stack size.
With the 66H prefix values will be pushed as 16 bits, not 64. I did
verify that in a debugger.
Alex
|
|
0
|
|
|
|
Reply
|
Alexei
|
9/25/2008 4:16:20 PM
|
|
|
9 Replies
472 Views
(page loaded in 3.903 seconds)
|