Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Execute concatenated position independent code within dynamic memory

7 views
Skip to first unread message

Adam Warner

unread,
May 13, 2006, 9:17:09 AM5/13/06
to
Hi all,

I have compiled a rudimentary virtual machine loop using GCC's labels as
values extension on Debian AMD64 (Linux 2.6.16). I have isolated the entry
and exit code (I'm compiling at -O0 and there's forced register pressure):

00000000004007ae <vm_loop>:
4007ae: 55 push %rbp
4007af: 48 89 e5 mov %rsp,%rbp
4007b2: 41 57 push %r15
4007b4: 41 56 push %r14
4007b6: 41 55 push %r13
4007b8: 41 54 push %r12
4007ba: 48 83 ec 20 sub $0x20,%rsp
4007be: 48 89 7d c8 mov %rdi,0xffffffffffffffc8(%rbp)
--------------------------------------------------------------------------
4007c2: 48 83 7d c8 00 cmpq $0x0,0xffffffffffffffc8(%rbp)
4007c7: 0f 85 00 01 00 00 jne 4008cd <vm_loop+0x11f>
...

...
400a83: eb 00 jmp 400a85 <vm_loop+0x2d7>
--------------------------------------------------------------------------
400a85: 48 83 c4 20 add $0x20,%rsp
400a89: 41 5c pop %r12
400a8b: 41 5d pop %r13
400a8d: 41 5e pop %r14
400a8f: 41 5f pop %r15
400a91: c9 leaveq
400a92: c3 retq

I have concatenated the entry and exit code in dynamic (malloc'd) memory:

55 48 89 e5 41 57 41 56 41 55 41 54 48 83 ec 20 48 89 7d c8 \
48 83 c4 20 41 5c 41 5d 41 5e 41 5f c9 c3

The vm_loop has function signature "void vm_loop(unsigned char* code)". I
have duplicated this function declaration as variable fn:
void (*fn)(unsigned char*); and assigned fn to this area of memory.

main() calls fn(<dummy value>) before finally returning [this fragment,
which starts at a final printf("\n"), is evidence of this]:

...
40078f: e8 bc fd ff ff callq 400550 <putchar@plt>
400794: 48 8d 45 d8 lea 0xffffffffffffffd8(%rbp),%rax
400798: 48 89 45 e0 mov %rax,0xffffffffffffffe0(%rbp)
40079c: 48 8b 05 15 0a 10 00 mov 1051157(%rip),%rax # 5011b8 <_DYNAMIC+0x190>
4007a3: 48 89 c7 mov %rax,%rdi
4007a6: 48 8b 45 e0 mov 0xffffffffffffffe0(%rbp),%rax
4007aa: ff d0 callq *%rax
4007ac: c9 leaveq
4007ad: c3 retq

The code segfaults instead of silently returning. Any tips for what I've
overlooked in the direct execution of PIC within dynamic memory?

Many thanks,
Adam

Paul Pluzhnikov

unread,
May 13, 2006, 10:53:40 AM5/13/06
to
Adam Warner <use...@consulting.net.nz> writes:

> The code segfaults instead of silently returning. Any tips for what I've
> overlooked in the direct execution of PIC within dynamic memory?

Perhaps you neglected to add PROT_EXEC to the page permissions?
(on x86, PROT_READ implies PROT_EXEC; not so on AMD64).

Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.

Adam Warner

unread,
May 13, 2006, 7:34:39 PM5/13/06
to
On Sat, 13 May 2006 07:53:40 -0700, Paul Pluzhnikov wrote:

> Adam Warner <use...@consulting.net.nz> writes:
>
>> The code segfaults instead of silently returning. Any tips for what I've
>> overlooked in the direct execution of PIC within dynamic memory?
>
> Perhaps you neglected to add PROT_EXEC to the page permissions?
> (on x86, PROT_READ implies PROT_EXEC; not so on AMD64).

Indeed I had to mprotect the dynamic memory. Once I learned how to use gdb
and ddd to single step through instructions I found I was also calling the
wrong area of memory! With that fixed the code terminates successfully.

Many thanks,
Adam

0 new messages