Re: [Linux-ia64] executable data segment ?

From: CH Gowri Kumar <gkumar_at_csa.iisc.ernet.in>
Date: 2003-05-10 14:30:24
> 	Is there a way in linux on ia64 to execute code in the
> datasegment ? 
Yes, it is possible to execute code in the data segment.
The data segment by default is not executable. You might have to 
make it executable using the mprotect system call.

The following example might be of some use to you:
(the C file is provided as ataachment also)

-----------Cut Here------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/mman.h>


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;
}
-------------Cut Here----------

Regards,
Gowri Kumar



Received on Fri May 09 21:31:32 2003

This archive was generated by hypermail 2.1.8 : 2005-08-02 09:20:14 EST