9

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?

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
Martin
  • 159
  • 1
  • 2
  • 7
  • 2
    Why 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 Answers5

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
  • 1
    very true, but he might be using fastcall (I'm not sure of the significance of 0xbffff994). – Mark Apr 21 '09 at 23:47
  • 1
    0xbffff994 likely = a location on the stack on a linux box :-P – Evan Teran Apr 22 '09 at 00:11
  • 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
  • Performance is usually very low on the list of priorities for shellcode. – Mark Jun 09 '20 at 00:31
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
  • 1
    I 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