0

I'm trying to use the call instruction to enter another function These are my attempts:

call 0x08048b98

This for some reason just calls 0x5d6cc555 which I don't where its getting that value from.

mov eax, 0x08048b98
call eax

This gives me a seg fault at the mov instruction.

I know I must be missing something but I've been working for hours and can't figure it out. Any help would be greatly appreciated!

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Which assembler are you using? Using a plain `0x08048b98` probably refers to the memory located at that address... you somehow have to tell the compiler these are simple constants, not addresses. – cadaniluk Oct 28 '15 at 20:02
  • I'm using GCC as my compiler and ODJDUMP as my disassembler. I don't know how to tell the compiler these are simple constants – Cameron Thompson Oct 28 '15 at 20:09
  • 2
    Note that AT&T syntax is at play here (operand order, syntax in general). Prepend constants with a dollar sign to refer to constants and not addresses. – cadaniluk Oct 28 '15 at 20:11
  • I just tried 'code'(call $0x08048b98) and got a "operand type mismatch for `call'" error when trying to compile it. – Cameron Thompson Oct 28 '15 at 20:26
  • 1
    Yeah, frankly I don't know how to pass an absolute value to `call`. :/ Try `mov $0x08048b98, %eax; call %eax`. Search the Internet for more information. – cadaniluk Oct 28 '15 at 20:29

1 Answers1

0

As pointed out in the comments, just using call 0xdeadbeef should work. I have now verified this, and it works on my machine as well. So the answer below is not useful. I'll still leave it here so nobody later comes upon this question and disappointedly thinks there is no answer though.
I hope the code examples are still helpful to some other beginners.


Assuming ia-32 means GAS Syntax, it should be possible to use * to designate it as an absolute address (and not a relative jump) and $ to designate it as a constant instead of having it load the value from this address.
It would thus make sense if it were

call *$0xdeadbeef

but this doesn't work. So here some suggestions that do seem to work.

For 32-bit (gcc -m32), I know that the following works:

movl $0xdeadbeef, %edi
call *%edi

For 64-bit, you'd probably need to use %rdi instead.

Another option, if you don't want to use a reg, would be to use a label:

.section .text
.globl main
main:
        movl $0x3, %eax        # some other instructions
        call *(THE_ADDR)       # call to your constant absolute address
        ret                    # some other instructions
THE_ADDR:
        .long 0x80483e6        # your constant absolute address
other_func:                    # here is 0x80483e6
        movl $0x4, %eax        # this code is executed

Again, this is 32-bit AT&T GAS Syntax assembly code, assembled with gcc -m32.


For completeness' sake:

mov eax, 0x08048b98
    call eax

This gives me a seg fault at the mov instruction. This is because you're trying to move eax to the address, if you're using GAS Syntax. It would rather be mov $0x08048b98, %eax.

This Q&A might help you as well.

lucidbrot
  • 5,378
  • 3
  • 39
  • 68
  • 1
    You only use `*` for an *indirect* jump. `call 0xdeadbeef` in GAS AT&T syntax works correctly, calculating the right `rel32` at link time to reach that absolute address. – Peter Cordes Apr 26 '18 at 03:20
  • 1
    Also note that `movl 0xdeadbeef, %edi` is a load from that absolute address. The OP knows the absolute address of the target function, not of a pointer to it. So in position-independent code, you should to use `movl $0xdeadbeef, %edi` / `call *%edi`. (There is no near-`call` encoding that takes an absolute address, only relative. http://felixcloutier.com/x86/CALL.html) – Peter Cordes Apr 26 '18 at 03:24
  • 1
    `call 0xdeadbeef` works to generate a relative call to that address, IDK why you only mention attempts to use absolute indirect `call *something`. (`call 0xdeadbeef` won't link in 64-bit code, because `0xdeadbeef` is more than +-2GiB away from where static code will live, but it works in 32-bit mode. An address like `call 0x1234567` works in 64-bit mode with AT&T syntax, too.) – Peter Cordes Apr 26 '18 at 07:43
  • @PeterCordes Thanks for your inputs. I was apparently confused. I'll leave the answer here but I assume you are better suited than me to write a good answer. I assumed some thinfs based on the question that I shoult have verified first. – lucidbrot Apr 26 '18 at 07:56
  • 1
    I was looking at cleaning up duplicates of x86 call to absolute address questions, some of which I've already answered :) IDK, possibly the OP was doing something wrong, like assuming that `call 0xdeadbeef` was position-independent; it's not. Actually, IDK how `mov eax, 0x08048b98` would even assemble in AT&T syntax; `eax` (without `%`) is a symbol name, not a register. Question looks bogus and should probably be closed. Maybe I should just write up a canonical Q&A without a bunch of confusing stuff in the question, with AT&T and NASM syntax answers. – Peter Cordes Apr 26 '18 at 08:10
  • @PeterCordes A canonical would be great! would you mind tagging me here once you marked this Q as a duplicate, so I can check out your answer there? – lucidbrot Apr 26 '18 at 08:46
  • 1
    Ok, finished an update to [Call an absolute pointer in x86 machine code](//stackoverflow.com/q/19552158) to make it a good canonical answer. – Peter Cordes Apr 27 '18 at 02:33