0

Working a basic buffer overflow on a 64bit system and putting together some basic shellcode. The main program does a call to puts@plt. When I disassemble main in gdb, the opcodes show as:

e8 6b fe ff ff    0x555555554580 <puts@plt>

I looked at the call instruction set reference which says its a relative displacement from the next instruction. The next instruction is:

0x0000555555554715 b8 00 00 00 00 mov eax, 0x0

How is "6b fe ff ff" displaced from "0x555555554715" to get the puts@plt address?

I'm dropping my shellcode onto the stack, is it possible to call to puts@plt from there as a displacement from the next instruction? Or do I just need to setup the registers for a syscall?

2

relative address can be forward or backward from end of current instruction or start of next instruction

that e8 00 00 00 00 will be call to the next immediate instruction
forward can be e8 ( 00 00 00 00 .... 7f ff ff ff )
backward can be e8 ( ff ff ff ff .... 80 00 00 00 )

so your immediate here is 0xfffffe6b that is == -0x195

negative numbers have their sign bit (31st bit ) set

0 & 0x80000000 == 0x80000000  will be False 
and
0xffffffff & 0x80000000 == 0x80000000  will be True

C:\>python -c "print((0xffffffff&0x80000000)==0x80000000);print((0x0&0x80000000)==0x80000000)"
True
False

so we can find out negative and positive numbers negative jumps backward positive jumps forward

positive 1 is 0 + 1
positive 2 is 0 + 2 and so on ......

negative 1 is 0x10000000 - 1
negative 2 is 0x10000000 - 2 and so on .......

>>> for i in range (1,20,1):
...     print (  "-%02d    ==    %x    +%02d    ==    %x" %  (i,( 0x10000000-i) ,i,( 0 + i )) )
...
-01    ==    fffffff    +01    ==    1
-02    ==    ffffffe    +02    ==    2
-03    ==    ffffffd    +03    ==    3
-04    ==    ffffffc    +04    ==    4
-05    ==    ffffffb    +05    ==    5
-06    ==    ffffffa    +06    ==    6
-07    ==    ffffff9    +07    ==    7
-08    ==    ffffff8    +08    ==    8
-09    ==    ffffff7    +09    ==    9
-10    ==    ffffff6    +10    ==    a
-11    ==    ffffff5    +11    ==    b
-12    ==    ffffff4    +12    ==    c
-13    ==    ffffff3    +13    ==    d
-14    ==    ffffff2    +14    ==    e
-15    ==    ffffff1    +15    ==    f
-16    ==    ffffff0    +16    ==    10
-17    ==    fffffef    +17    ==    11
-18    ==    fffffee    +18    ==    12
-19    ==    fffffed    +19    ==    13

so i subtract 0xfffffe6b from 0x100000000

C:\>python -c "print hex(0xfffffe6b - 0x100000000)"
-0x195L

C:\>python -c "print hex(0x0000555555554715 + (-0x195))"
0x555555554580L

demo in radare2

[0x00000000]> w \xe8\x00\x00\x00\x00 ; pd 1
            0x00000000      e800000000     call 5
[0x00000000]> w \xe8\x01\x00\x00\x00 ; pd 1
            0x00000000      e801000000     call 6
[0x00000000]> w \xe8\x02\x00\x00\x00 ; pd 1
            0x00000000      e802000000     call 7
[0x00000000]> w \xe8\x08\x00\x00\x00 ; pd 1
            0x00000000      e808000000     call 0xd
[0x00000000]> w \xe8\xff\xff\xff\xff ; pd 1
            0x00000000      e8ffffffff     call 4
[0x00000000]> w \xe8\xfe\xff\xff\xff ; pd 1
            0x00000000      e8feffffff     call 3
[0x00000000]> w \xe8\x6b\xff\xff\xff ; pd 1
            0x00000000      e86bffffff     call 0xffffff70
[0x00000000]> w \xe8\x6b\xfe\xff\xff ; pd 1
            0x00000000      e86bfeffff     call 0xfffffe70
[0x00000000]>

simulating an actual call opcodes

opening a random elf file 
:\>radare2 elfie

getting the address of sym.puts
[0x08048150]> ?v sym.puts
0x8048de0

calculating relative address for force writing a call to sym.puts
[0x08048150]> ?v sym.puts + 0x195 - 0x5
0x8048f70

seeking to target address
[0x08048150]> s sym.puts + 0x195 - 0x5

setting cache = true for writing to memory (radare2 opens in read only mode)
[0x08048f70]> e io.cache = true

checking the present disassembly
[0x08048f70]> pd 1
        `=< 0x08048f70      ebd7           jmp 0x8048f49
patching a call to sym.puts in place 

[0x08048f70]> w \xe8\x6b\xfe\xff\xff

checking disassembly again 

[0x08048f70]> pd 1
            0x08048f70      e86bfeffff     call sym.puts
  • I see how the -0x195 math works, but why the subtraction from 0x10000000? If forward can be 00 00 00 08 to ff ff ff ff and backward can be ff ff ff ff to 00 00 00 00, with the overlap, how do you know which direction the call is jumping? – gr0k Mar 9 at 19:12
  • added further details to answer btw there is no overlap it was typo corrected the range – blabb Mar 9 at 20:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.