Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Syscall problem

Status
Not open for further replies.

keratox

Programmer
Apr 10, 2004
3
0
0
EU
Hi all,

the problem is that my program produces a segmentation fault but I don't know why, but the strange thing is that when I use gdb and I set a breakpoint to a specific line of the code, the program terminates correctly!
Here's the code:

global main
main:
lea esi,[sh]

xor eax,eax ;syscall execve("/bin/sh")
mov byte[esi+7],$0
mov [esi+8],esi
mov [esi+0xc],eax
lea edx,[esi+0xc]
lea ecx,[esi+0x8]
mov ebx,esi
mov al,0xb
;1° breakpoint (If i set a break here the program terminates normally)
int 0x80

xor eax, eax ;syscall exit(0)
xor ebx, ebx
inc eax
int 0x80

.data
sh db '/bin/sh';

As you can see, this code issues an execve("/bin/sh"..) syscall which spawns a shell, but it produces a segmentation fault at run-time.
Debugging with gdb I got this error, that looks like eip is overwritten by something (eip points to 0x40000bb0 but it shouldn't!!):

Program received signal SIGTRAP, Trace/breakpoint trap.
0x40000bb0 in ?? ()

But when I set a breakpoint in the 1° point the program terminates correctly!?!?

(gdb) run
Breakpoint 1, main () at a.asm:16
16 int 0x80
(gdb) continue
Continuing.
sh-2.05b$ exit ;<--------execve("/bin/sh"...)
exit

Program exited normally.
(gdb)

How come if I set the breakpoint it terminates fine?
Is there something wrong in the code?
Any help is really appreciated!!




 
Hi keratox,

I'm not sure what are you trying to achieve with that code. But if I look from it, I can't see what's wrong. Is that only a small part of your code?

Try to trace (from the debugger) step by step.

-- AirCon --
 

Thank you for your reply AirCon,

That's all the code of my program, I'm new in the assembly language on linux and I'm trying to understand how syscall work, but I can't figure out what is wrong on my code.
However this is what I got from gdb by tracing step to step:

.....
.....
(gdb) step
12 lea ecx,[esi+0x8]
(gdb) step
13 mov ebx,esi
(gdb) step
14 mov al,0xb
(gdb) step
16 int 0x80
(gdb) step
Warning:
Cannot insert breakpoint 0.
Error accessing memory address 0x1: Input/output error.
The same program may be running in another process.
(gdb) step
Cannot find bounds of current function
(gdb) step
Cannot find bounds of current function
(gdb) step

It seems that the process is already running but it isn't.
What does it mean?


 
Ahh.. no wonder. I'm sorry, can't help you in this case. I don't have any experience with Linux. Anyone ?

-- AirCon --
 
keratox,

A segmentation fault can occur when you attempt to write to unreserved memory.
keratox said:
mov [esi+0xc],eax

I recently developed some shell code to invoke /bin/ksh, and I've included it here in the hope you will find it useful.
Code:
; shellcode.s
;
; nasm -f elf shellcode.s
; ld -o shellcode shellcode.o

[SECTION .text]
	global _start          ; Global for the linker's benefit

_start:

	; shell string
	xor	edx, edx        ; NULL

	push   edx             ; /0
	push   0x68736B2F      ; /ksh
	push   0x6E69622F      ; /bin


	mov	ebx, esp        ; shell string

	push   edx             ; push another null for argv
	push   ebx             ; push argv
	mov	ecx, esp        ; pointer to shell

	mov	eax, 0xFFFFFFFF
	sub	eax, 0xFFFFFFF4 ; sys_execve (11)
	int	0x80

	; sys_exit
	xor	ebx, ebx        ; return status 0
	xor	eax, eax
	inc	eax	         ; sys_exit (1)
	int	0x80

The implementation may look odd at first, but it was designed to not have any null values (0x00) in the compiled code (thus the seperate mov and sub to get 11 into eax).

Regards,
Jason Deckard

 
I'm not a linux person so disregard anything here that's obviously rubbish:

(1) it shouldn't be necessary to use mov and sub separately to get a value into eax. mov eax, 011h should not be a dangerous instruction in any system.

(2) keratox, what lies after sh in your data segment? You are setting the values of things after this (e.g. setting the 8th byte to zero). If you don't own that memory then you can't just do that - it might overwrite something important.

(3) For putting the zero at the end of the string, had you considered db 'anytext', 0
rather than writing it at runtime.


 
lionelhill said:
(1) it shouldn't be necessary to use mov and sub separately to get a value into eax. mov eax, 011h should not be a dangerous instruction in any system.
JasonDeckard said:
The implementation may look odd at first, but it was designed to not have any null values (0x00) in the compiled code (thus the seperate mov and sub to get 11 into eax).
I made an attempt to explain why I was doing that, but I may not have clear enough. The reason for not using mov eax, 011h is it compiles (on my system) to b8 11 00 00 00. My code was designed to not have any null bytes in it, because it was used in an example of overflowing a string buffer.

Regards,
Jason

 

I think the problem was in the instruction "mov byte [esi+7],0, now I've changed this works fine:

.data
sh db "/bin/sh"

in:

SECTION .data
sh db "/bin/sh",0

And obviously I removed the "mov byte [esi+7],0" which seems to write some other memory location.

Thank you
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top