NASM beginner / Running code from the heap

Programming, for all ages and all languages.
Post Reply
JoyKitikonti
Posts: 3
Joined: Mon Jan 17, 2011 4:26 am

NASM beginner / Running code from the heap

Post by JoyKitikonti »

Hi folks,

I am a beginner in low level programming and I am playing with Nasm under linux.
The purpose of the following code is to copy some code on the heap (using linux syscall brk) and jump to it.
Once running the code from the heap, the program simply prints out a message and returns to the address on top of the stack.
The problem I have depends on how I print the message. If I use a syscall, it works, but if I use a printf libc call, it fails.
The only thing I can get from GDB is :

Program received signal SIGSEGV, Segmentation fault.
0x08049f3d in _DYNAMIC ()

The buggy code is located after the inject label.

Do you have any idea, why the libc call is failling?

Thanks.

Code: Select all

segment .data

msg1		db	"Retrieving BRK value...", 10, 0
len 		equ	$-msg1
ptrval		db	"Found brk(0) = %p", 10, 0
junkval		db	"      junk   = %p", 10, 0
dump		db	"      dump   : %p", 10, 0
injection	db	"Injection complete, reading code from heap!", 10, 0
injectionlen 	equ	$-injection
injectsize	db	"Code injection requires %d bytes...", 10, 0

backloop	db	"Now, back in the loop.", 10, 0
dbg		db	"ebx=%d, cond=%d", 10, 0


segment .bss

	junk	resd 1
	ptr	resd 1
	ptr2	resd 1

segment .text
        global  main
	extern printf

main:
        enter   0,0			        ; setup routine
        pusha

	; Show msg1
	mov	edx, len
	mov	ecx, msg1
	mov	ebx, 1			; fd = 1 = stdout
        mov     eax, 4			; 4 = linux write system call
	int 	0x80			        ; syscall software interrupt

        ; get brk
	mov	ebx, 0			; 0 to get current brk pointer
        mov     eax, 45			; 45 = linux brk system call
	int 	0x80			        ; syscall software interrupt

	mov	[ptr], eax		        ; store brk(0) in ptr

	push	eax
	push	dword ptrval
	call	printf
	pop	ecx
	pop	ecx

        push    junk
        push    dword junkval
        call    printf
        pop     ecx
        pop     ecx

	mov	eax, [ptr]
	push    eax
        push    dword ptrval
        call    printf
        pop     ecx
        pop     ecx

	mov     eax, $skip-$inject
        push    eax
        push    dword injectsize
        call    printf
        pop     ecx
        pop     ecx

        ; get NEW brk
        mov     ebx, [ptr]         	     ; dynamic alloc of $skip-$inject bytes
	add	ebx, $skip-$inject
        mov     eax, 45            	     ; 45 = linux brk system call
        int     0x80            	             ; syscall software interrupt

        mov     [ptr2], eax      	     ; store new brk in ptr2

        push    eax
        push    dword ptrval
        call    printf
        pop     ecx
        pop     ecx

	mov	ebx, 0			     ; loop counter
	push	skip			             ; address used by injected ret instruction

whilecp:
	CMP	ebx, ($skip-$inject)/4	     ; div 4 since we move 4 bytes at once (32 bits reg)
	JZ	copyok
copy:					     ; perform the instruction copies
	mov	eax, [inject+ebx*4]
	mov	[ptr+ebx*4], eax

	mov	eax, [inject+ebx*4]	
	push	eax
	push    dword dump
        call    printf
        pop     ecx
	pop	ecx

	add	ebx, 1			      ; inc loop counter
	JMP	whilecp

copyok:
	JMP	ptr			              ; jump to heap code
	JMP	skip

inject:	
        ; THIS METHOD WORKS
	;mov	edx, injectionlen
	;mov	ecx, injection
	;mov	ebx, 1			     ; fd = 1 = stdout
        ;mov	eax, 4			     ; 4 = linux write system call
	;int 	0x80			             ; syscall software interrupt
	;nop

        ; THIS METHOD DOES NOT WORK
	push    dword injection
	call    printf
        pop     ecx
	ret
	nop
	nop
	nop
	nop

skip:
        push    dword backloop
        call    printf
        pop     ecx
	
	popa 
        mov     eax, 0
        leave
        ret
User avatar
NickJohnson
Member
Member
Posts: 1249
Joined: Tue Mar 24, 2009 8:11 pm
Location: Sunnyvale, California

Re: NASM beginner / Running code from the heap

Post by NickJohnson »

You're having problems because you're moving the code you're running, which means the dynamic linker doesn't know where the code is anymore and can't help it to call libc functions. I think your only options are to use syscalls or to have another piece of code in the current executable at a fixed address that the moved code can call in order to call libc functions.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re: NASM beginner / Running code from the heap

Post by Solar »

NickJohnson wrote:I think your only options are to use syscalls or to have another piece of code in the current executable at a fixed address that the moved code can call in order to call libc functions.
I wrote a short abstract on Amiga Library Base Pointers that might be a solution for your problem.
Every good solution is obvious once you've found it.
Post Reply