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?


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.

| improve this answer | |
  • 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 '16 at 20:03

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.