Run file and checksec.
$ file fluff
fluff: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=2b14d9e5fb7a6bcac48b5304b5153fc679c3651c, not stripped
$ checksec fluff
[*] '/home/hwkim301/rop_emporium/fluff/fluff'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
RUNPATH: b'.'
Stripped: No
Load the binary into ghidra.
Here’s the main function.
undefined8 main(void)
{
pwnme();
return 0;
}
pwnme doesn’t have much.
void pwnme(void)
{
/* WARNING: Bad instruction - Truncating control flow here */
halt_baddata();
}
There is a usefulFunction in the binary though.
void usefulFunction(void)
{
print_file("nonexistent");
return;
}
Below the disassembly of usefulFunction is the questionable_gadgets.

Press d on the ?? to show the disassembly.
Here’s the result.

There are assembly instructions that I’ve never ever seen in my life.
The first unfamiliar instruction is xlat.
Now let’s check for any useful functions in libfluff.so.
Load the shared library into ghidra.
Here’s pwnme.
void pwnme(void)
{
undefined1 local_28 [32];
setvbuf(_stdout,(char *)0x0,2,0);
puts("fluff by ROP Emporium");
puts("x86_64\n");
memset(local_28,0,0x20);
puts("You know changing these strings means I have to rewrite my solutions...");
printf("> ");
read(0,local_28,0x200);
puts("Thank you!");
return;
}
There’s also a print_file function.
void print_file(char *param_1)
{
char local_38 [40];
FILE *local_10;
local_10 = (FILE *)0x0;
local_10 = fopen(param_1,"r");
if (local_10 == (FILE *)0x0) {
printf("Failed to open file: %s\n",param_1);
/* WARNING: Subroutine does not return */
exit(1);
}
fgets(local_38,0x21,local_10);
puts(local_38);
fclose(local_10);
return;
}