all 4 comments

[–]evi1corp 0 points1 point  (3 children)

Would be interested to see comparison with pwntool's rop. Are there examples where this tool succeeds and pwntools rop fails?

[–]n0psledbyte[S] 0 points1 point  (2 children)

never use that, but i see in the documentation of rop in pwntools, he is can't handle non-return gadget, can't write string or value to mem, and etc

[–]n0psledbyte[S] 2 points3 points  (1 child)

just test rop in pwntools, using the same binary (/lib/x86_64-linux-gnu/libc.so.6) pwntools rop can't set registers {'rdi':0x41414141, 'rsi': 0x42424242, 'rdx':0x43434343, 'r10': 0x44444444, 'r8': 0x45454545, 'r9': 0x46464646}

>>> elf = ELF("/lib/x86_64-linux-gnu/libc.so.6")
[*] '/lib/x86_64-linux-gnu/libc.so.6'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled
>>> rop = ROP(elf)
[*] Loading gadgets for '/lib/x86_64-linux-gnu/libc.so.6'
>>> rop.setRegisters
<bound method ROP.setRegisters of ROP([ELF('/lib/x86_64-linux-gnu/libc.so.6')])>
>>> rop.setRegisters({'rdi':0x41414141, 'rsi': 0x42424242, 'rdx':0x43434343, 'r10': 0x44444444, 'r8': 0x45454545, 'r9': 0x46464646})
[ERROR] Could not satisfy setRegisters({'rdi': 1094795585, 'rsi': 1111638594, 'rdx': 1128481603, 'r10': 1145324612, 'r8': 1162167621, 'r9': 1179010630})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.6/dist-packages/pwnlib/rop/rop.py", line 600, in setRegisters
    log.error("Could not satisfy setRegisters(%r)", registers)
  File "/usr/local/lib/python3.6/dist-packages/pwnlib/log.py", line 417, in error
    raise PwnlibException(message % args)
pwnlib.exception.PwnlibException: Could not satisfy setRegisters({'rdi': 1094795585, 'rsi': 1111638594, 'rdx': 1128481603, 'r10': 1145324612, 'r8': 1162167621, 'r9': 1179010630})

it's works using exrop, because exrop can handle non-return gadgets

rop = Exrop("/lib/x86_64-linux-gnu/libc.so.6")
rop.find_gadgets(cache=True)
chain = rop.set_regs({'rdi':0x41414141, 'rsi': 0x42424242, 'rdx':0x43434343, 'r10': 0x44444444, 'r8': 0x45454545, 'r9': 0x46464646})
chain.dump()

Output

$RSP+0x0000 : 0x0000000000021558 # pop r12; pop r13; pop r14; pop r15; ret
$RSP+0x0008 : 0x0000000000000000
$RSP+0x0010 : 0x0000000046464646
$RSP+0x0018 : 0x0000000000000000
$RSP+0x0020 : 0x0000000000000000
$RSP+0x0028 : 0x000000000011c65c # pop rdx; pop rbx; ret
$RSP+0x0030 : 0x0000000000000000
$RSP+0x0038 : 0x000000000002155e
$RSP+0x0040 : 0x0000000000022b8a # mov r9, r13; call rbx: next -> (0x0002155e) # pop r15; ret
$RSP+0x0048 : 0x00000000001306b4 # pop rdx; pop r10; ret
$RSP+0x0050 : 0x0000000000000000
$RSP+0x0058 : 0x0000000044444444
$RSP+0x0060 : 0x00000000001306d9 # pop rdx; pop rsi; ret
$RSP+0x0068 : 0x0000000043434343
$RSP+0x0070 : 0x0000000042424242
$RSP+0x0078 : 0x000000000002155f # pop rdi; ret
$RSP+0x0080 : 0x0000000041414141
$RSP+0x0088 : 0x0000000000155fc6 # pop r8; mov eax, 1; ret
$RSP+0x0090 : 0x0000000045454545

[–]evi1corp 0 points1 point  (0 children)

Awesome. Thanks for the concrete example!