I can control these registers:

(gdb) i r
rax            0x1  1
rbx            0x4141414141414141   4702111234474983745
rcx            0x7ffff760cf90   140737343704976
rdx            0x49526df7d355ee04   5283406224028986884
rsi            0x1  1
rdi            0x7fffffffce00   140737488342528
rbp            0x49526df7d355ee04   0x49526df7d355ee04
rsp            0x49526df7d355ee04   0x49526df7d355ee04
r8             0x49526df7d355ee04   5283406224028986884
r9             0x49526df7d355ee04   5283406224028986884
r10            0x8  8
r11            0x246    582
r12            0x4141414141414141   4702111234474983745
r13            0x4141414141414141   4702111234474983745
r14            0x4141414141414141   4702111234474983745
r15            0x4141414141414141   4702111234474983745
rip            0x7ffff760cbbe   0x7ffff760cbbe <__longjmp+78>
eflags         0x10202  [ IF RF ]
cs             0x33 51
ss             0x2b 43
ds             0x0  0
es             0x0  0
fs             0x0  0

Can I somehow control rip thought these? Particularly when I control rbx?

All the examples I found were where rbp was controlled and how to do this is clear to me. Described for example here

Update 1:

Maybe that helps, I disassembled the function that is called after I modified the registers:

(gdb) disass png_error
Dump of assembler code for function png_error:
=> 0x00007ffff7bcf280 <+0>: push   %r12
   0x00007ffff7bcf282 <+2>: push   %rbp
   0x00007ffff7bcf283 <+3>: mov    %rsi,%rbp
   0x00007ffff7bcf286 <+6>: push   %rbx
   0x00007ffff7bcf287 <+7>: mov    %rdi,%rbx
   0x00007ffff7bcf28a <+10>:    sub    $0x30,%rsp
   0x00007ffff7bcf28e <+14>:    mov    %fs:0x28,%rax
   0x00007ffff7bcf297 <+23>:    mov    %rax,0x28(%rsp)
   0x00007ffff7bcf29c <+28>:    xor    %eax,%eax
   0x00007ffff7bcf29e <+30>:    test   %rdi,%rdi
   0x00007ffff7bcf2a1 <+33>:    je     0x7ffff7bcf2c6 <png_error+70>
   0x00007ffff7bcf2a3 <+35>:    mov    0x120(%rdi),%rcx
   0x00007ffff7bcf2aa <+42>:    test   $0xc0000,%ecx
   0x00007ffff7bcf2b0 <+48>:    jne    0x7ffff7bcf318 <png_error+152>
   0x00007ffff7bcf2b2 <+50>:    mov    0xc8(%rbx),%rax
   0x00007ffff7bcf2b9 <+57>:    test   %rax,%rax
   0x00007ffff7bcf2bc <+60>:    je     0x7ffff7bcf2c6 <png_error+70>
   0x00007ffff7bcf2be <+62>:    mov    %rbp,%rsi
   0x00007ffff7bcf2c1 <+65>:    mov    %rbx,%rdi
   0x00007ffff7bcf2c4 <+68>:    callq  *%rax

Any ideas how to control rip?

1 Answer 1


What you can do when you control a register depends on what the attacked code does with that register. So it is hard to make a generic answer.

In the x86-64 ABI, the %rbx register is one of the registers that the callee must preserve, so if a function uses %rbx, it must first save it, and restore it upon exiting. A consequence is that most functions will not use %rbx if they can avoid it. In the 32-bit ABI, the %ebx register is typically used to save the address of the GOT (the base table used to do dynamic linking) so modifying %ebx could possibly allow fiddling with subsequent function calls; but in the 64-bit ABI, PIC code typically uses RIP-relative addressing, which does not use %rbx.

To see what you can do with %rbx in a specific situation, you really have to disassemble the attacked code and see how it uses that register (or not) in the instructions after your alteration.

  • Thanks. I updated the question with the disassemble of the function that is called after the regs are modified. Does it help? Can you judge based on this something more?
    – dev
    Mar 1, 2016 at 20:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .