As an assignment for a security class, I am trying to use __asm__("jmp 0xbffff994");
in my code, but when I disassemble things in gdb, the instruction is changed to jmp 0xc8047e2a
.
Any idea why and how can I jump to a particular address?
Asked
Active
Viewed 2.5k times
9

1201ProgramAlarm
- 32,384
- 7
- 42
- 56

Martin
- 159
- 1
- 2
- 7
-
2Why the heck do you need to jump to a raw address? I'm having a hard time understanding any possible (non-nefarious) use for that. – kquinn Apr 21 '09 at 23:33
-
11@kquinn regardless, his question has been asked, let's try to answer it. – samoz Apr 21 '09 at 23:41
5 Answers
28
Probably because it's a jumping to a relative address, and the linker or loader has moved your code. Try putting the address into a variable, and then do:
jmp dword [var]
or alternatively:
push 0xbffff994
ret

Mark
- 6,269
- 2
- 35
- 34
-
5*that* is the correct answer, also note that: "mov eax, 0x11223344; jmp eax"; will also work and is likely the most straight forward. – Evan Teran Apr 21 '09 at 23:45
-
1very true, but he might be using fastcall (I'm not sure of the significance of 0xbffff994). – Mark Apr 21 '09 at 23:47
-
1
-
You don't want `push/ret` for performance. It unbalances the return-address predictor stack. (see [this comment](https://stackoverflow.com/questions/1546141/jmp-to-absolute-address-op-codes#comment104329413_2049606), and https://agner.org/optimize/ / http://blog.stuffedcow.net/2018/04/ras-microbenchmarks/). Use `mov eax, 0xbffff994` / `jmp eax` or see [Call an absolute pointer in x86 machine code](https://stackoverflow.com/q/19552158) – Peter Cordes Jun 08 '20 at 15:11
-
1
It is hard to determine the exact address upon compile time, have you tried using labels? It is much more common to use them with jmp.
example:
start:
jmp exit
exit:
ret

John T
- 23,735
- 11
- 56
- 82
0
Daniel Explains why your jump is not the same you programmed. It has to do with object files and linking.
if you want to jump to a particular address, it's best to patch the jump using a Debugger or Disassembler.

toto
- 880
- 11
- 21
0
On my system (gcc version 4.2.4, Ubuntu) this looks fine on the disassmbley (insight):
int main() { asm("jmp 0xbffff994"); return 0; };
results of the disassmbley (insight):
0x8048344 : lea 0x4(%esp),%ecx - 0x8048348 : and $0xfffffff0,%esp - 0x804834b : pushl -0x4(%ecx) - 0x804834e : push %ebp - 0x804834f : mov %esp,%ebp - 0x8048351 : push %ecx - 0x8048352 : jmp 0xbffff994 - 0x8048357 : mov $0x0,%eax - 0x804835c : pop %ecx - 0x804835d : pop %ebp - 0x804835e : lea -0x4(%ecx),%esp - 0x8048361 : ret

Liran Orevi
- 4,755
- 7
- 47
- 64
-
1I would guess that that disassembler is showing the offset of the jmp and not its actual target. (the jmp instruction takes an offset relative to eip when you give it a 32-bit immediate operand). – Evan Teran Apr 22 '09 at 00:28
-
Why would you guess that? is there a way to test it? it is running as a graphical interface with GDB below. – Liran Orevi Apr 22 '09 at 07:56
-
Or it could be that there's no relocation. However, if you dump the opcodes with the assembly you'll be able to see the offset. – Mark Apr 22 '09 at 11:55
-
I see this 8048352: e9 3d 76 fb b7 jmp bffff994 <_end+0xb7fb6454> can't find the _end label, but it looks mighty close to the end of the program. – Liran Orevi Apr 22 '09 at 13:39
0
I would recommend using a hex editor and simply changing the value if it's just a one time thing.

samoz
- 56,849
- 55
- 141
- 195