* [Linux-ia64] executable data segment ?
@ 2003-05-10 3:11 Ronald Veldema
2003-05-10 4:42 ` CH Gowri Kumar
2003-05-10 7:01 ` David Mosberger
0 siblings, 2 replies; 3+ messages in thread
From: Ronald Veldema @ 2003-05-10 3:11 UTC (permalink / raw)
To: linux-ia64
Hi all,
Is there a way in linux on ia64 to execute code in the
datasegment ? My Java compiler generates code to the datasegment
for to dynamically remove tests to see if a classes'
static-variables have already been initialized.
Works great on ia32, on linux/ia64 won't allow it...
Ronald.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Linux-ia64] executable data segment ?
2003-05-10 3:11 [Linux-ia64] executable data segment ? Ronald Veldema
@ 2003-05-10 4:42 ` CH Gowri Kumar
2003-05-10 7:01 ` David Mosberger
1 sibling, 0 replies; 3+ messages in thread
From: CH Gowri Kumar @ 2003-05-10 4:42 UTC (permalink / raw)
To: linux-ia64
[-- Attachment #1: Type: TEXT/PLAIN, Size: 4097 bytes --]
> 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
[-- Attachment #2: Type: TEXT/PLAIN, Size: 3801 bytes --]
#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;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Linux-ia64] executable data segment ?
2003-05-10 3:11 [Linux-ia64] executable data segment ? Ronald Veldema
2003-05-10 4:42 ` CH Gowri Kumar
@ 2003-05-10 7:01 ` David Mosberger
1 sibling, 0 replies; 3+ messages in thread
From: David Mosberger @ 2003-05-10 7:01 UTC (permalink / raw)
To: linux-ia64
>>>>> On Sat, 10 May 2003 10:00:24 +0530 (IST), CH Gowri Kumar <gkumar@csa.iisc.ernet.in> said:
>> 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.
And if you want to be able to get a backtrace through dynamically
generated code, please consider using the dynamic unwind info API of
libunwind (http://www.hpl.hp.com/research/linux/libunwind/). No
man-page yet, I'm afraid, but there is an example in the libunwind
source distribution (tests/ia64-test-dyn1.c) which should make it
obvious how to use this API.
Imagine being about to use gdb to debug your dynamically-generated
code!
--david
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2003-05-10 7:01 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-05-10 3:11 [Linux-ia64] executable data segment ? Ronald Veldema
2003-05-10 4:42 ` CH Gowri Kumar
2003-05-10 7:01 ` David Mosberger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox