flat assembler
Message board for the users of flat assembler.

flat assembler > Linux > Console output after intern program execution

Author
Thread Post new topic Reply to topic
andyz74



Joined: 26 Nov 2007
Posts: 36
Location: Germany
Hello my friends!
I have (like everytime) a problem.

There's some code which starts via
Code:
mov eax,0Bh
mov ecx,args
mov edx,0
mov ebx,arg0
int 80h
    

a program, which gives itself some output on the console.
After this program being exited, I want to make MYSELF some output on the console via
Code:
mov     eax, 4          ;sys_write
mov     ebx, 1          ;stdout
mov     ecx, axwert     ;pointer to buffer to write
mov     edx, 7 ;buffer to write
int     80h
    


It compiles without any problems, but my OWN output doesn't work, just the output from the started program.
If i does comment out (with ";") the programstart then my own output can be read.

I don't understand what to do.
Any suggestion?
Post 05 Oct 2008, 15:19
View user's profile Send private message Visit poster's website Reply with quote
andyz74



Joined: 26 Nov 2007
Posts: 36
Location: Germany
It's awesome, I tried to replace the console output by logging in a file and the result is the same:
the extern program-call seems to block the whole process, my log-file isn't created!
Here the code
Code:
format elf executable

entry start
start:


mov eax,0Bh                      ;call extern prog (here 7-zip)
mov ecx,args
mov edx,0
mov ebx,arg0
int 80h

mov [alleregister],ah             ;store all registervalues in one huge variable
mov [alleregister+1],al
mov [alleregister+7],bh
mov [alleregister+8],bl
mov [alleregister+14],ch
mov [alleregister+15],cl
mov [alleregister+21],dh
mov [alleregister+22],dl
add [alleregister],48
add [alleregister+1],48
add [alleregister+7],48
add [alleregister+8],48
add [alleregister+14],48
add [alleregister+15],48
add [alleregister+21],48
add [alleregister+22],48

mov eax,08h            ; create file
mov ebx,f              ; ebx filename
mov ecx, 0x1a4
int 80h
mov ebx,eax              ; file descriptor nach ebx

mov eax,04h           ; write to file
mov ecx,alleregister
mov edx,ars
int 80h

mov eax,06h            ; close file
int 80h

mov eax,1
int 80h

;*********** here the variables ***********************

f db 'execlog.txt',0

arg0 db '/usr/bin/PeaZip/res/7z/7z',0
arg1 db 't',0
arg2 db '-ptest',0
arg3 db 'archiv-m.7z',0
args dd arg0,arg1,arg2,arg3,0

alleregister db "00-ax",13,10,"00-bx",13,10,"00-cx",13,10,"00-dx",13,10,13,10
ars =$-alleregister
    


I see no solution for me here. Sad
Post 06 Oct 2008, 14:03
View user's profile Send private message Visit poster's website Reply with quote
pelaillo
Missing in inaction


Joined: 19 Jun 2003
Posts: 862
Location: Colombia
edit (sorry, posted before your second post)
From the examples (elfexe)
Code:
; fasm demonstration of writing simple ELF executable

format ELF executable
entry start

segment readable executable

start:

  mov     eax,4
       mov     ebx,1
       mov     ecx,msg
     mov     edx,msg_size
        int     0x80

    mov     eax,1
       xor     ebx,ebx
     int     0x80

segment readable writeable

msg db 'Hello world!',0xA
msg_size = $-msg

    


The problem may be the buffer, or I didn't get your request.


Last edited by pelaillo on 06 Oct 2008, 15:44; edited 1 time in total
Post 06 Oct 2008, 14:13
View user's profile Send private message Yahoo Messenger Reply with quote
pelaillo
Missing in inaction


Joined: 19 Jun 2003
Posts: 862
Location: Colombia
Try to fork (0x02) before executing the external program.

I'm currently doing a test with your code. I'll let you know.
Post 06 Oct 2008, 14:23
View user's profile Send private message Yahoo Messenger Reply with quote
pelaillo
Missing in inaction


Joined: 19 Jun 2003
Posts: 862
Location: Colombia
Insert this in your code:

Code:
start:
mov eax,2 ;fork
int 80h
test eax,eax
jne continue

mov eax,0Bh                     ;call extern prog (here 7-zip)
mov ecx,args
mov edx,0
mov ebx,arg0
int 80h

continue:
mov [alleregister],ah
; and so on...
    

This is because the executed program inherits the resources and overwrites the caller. Cloning will permit you to continue execution in a copy that skips the external program launch.
Post 06 Oct 2008, 16:07
View user's profile Send private message Yahoo Messenger Reply with quote
andyz74



Joined: 26 Nov 2007
Posts: 36
Location: Germany
Ok, I've tested it, and it works, the log-file is written. Thanks for this one, man, but in reality, the program doesn't turn back to the system-prompt after execution, what i don't really understand...
Maybe I should specify on drinking beer, that's easier than coding Assembler. :-/
Post 06 Oct 2008, 16:26
View user's profile Send private message Visit poster's website Reply with quote
pelaillo
Missing in inaction


Joined: 19 Jun 2003
Posts: 862
Location: Colombia
Quote:

the program doesn't turn back to the system-prompt after execution

What do you mean?
Post 06 Oct 2008, 17:56
View user's profile Send private message Yahoo Messenger Reply with quote
Endre



Joined: 29 Dec 2003
Posts: 212
Location: Budapest, Hungary
Use sys_waitpid (0x07) system-call in parent process to have it wait for the child process to finish. I guess you want to retrieve exit value of the started application. Check out man page of "wait" and "waitpid".
Post 07 Oct 2008, 07:18
View user's profile Send private message Reply with quote
andyz74



Joined: 26 Nov 2007
Posts: 36
Location: Germany
Yes, in fact I want to get the exit value of the intern started program. At the moment the program doesn't return to system prompt. It has to be stopped by Ctrl-C.
I will see what i find to read about "sys_waitpid". Thx all for your help! Smile
Post 07 Oct 2008, 08:23
View user's profile Send private message Visit poster's website Reply with quote
Endre



Joined: 29 Dec 2003
Posts: 212
Location: Budapest, Hungary
I created a little snippet to demonstrate how to wait for child process to complete and to get exit status. By changing "active" arg0 in the source you can examine exit status of different external programs
Code:
/**
 * For debugging compile with
 * gcc -g -nostdlib vfork.S -o vfork
 *
 * or for releasing with
 *
 * gcc -s -nostdlib vfork.S -o vfork
 */

        .if 0
#include <asm/unistd.h>
#include <unistd.h>
#include <sys/wait.h>
        .endif

        .line __LINE__
        .intel_syntax noprefix
        .globl _start
        .text

_start:
        /* create new process */
        mov     rax, __NR_vfork
        syscall
        /* check if child or parent */
        test    rax, rax
        jnz     parent_process
        /* child process, start application */
        mov     rax, __NR_execve
        mov     rdi, OFFSET arg0
        mov     rsi, OFFSET argv
        xor     rdx, rdx
        syscall
        /**
         * execve returns only if any error occured,
         * so here we exit child process
        **/
        mov     rdi, rax
        mov     rax, __NR_exit
        syscall

        /* parent process */
parent_process: 
        /* wait for child process to complete */
        mov     rdi, rax
        mov     rsi, OFFSET exit_status
        mov     rdx, WUNTRACED
        xor     r10, r10 /* we ain't interrested in resources used */
        mov     rax, __NR_wait4
        syscall
        /* print "Thread completed" message */
        mov     rax, __NR_write
        mov     rdi, STDOUT_FILENO
        mov     rsi, OFFSET msg
        mov     rdx, OFFSET msg_size
        syscall
        mov     rax, __NR_write
        mov     rsi, OFFSET status_ok
        mov     rdx, OFFSET status_ok_size
        /* only the least 8 bits of the exit status */
        cmp     BYTE PTR [rip + exit_status + 1], 0
        jz      ok
        mov     rsi, OFFSET status_fail
        mov     rdx, OFFSET status_fail_size
ok:   
        syscall
        /* exit */
        xor     rdi, rdi
        mov     rax, __NR_exit
        syscalll

msg:
        .ascii  "Thread completed! Exit status: "
msg_size = . - msg

status_ok:
        .ascii  "Succeeded\n"
status_ok_size = . - status_ok
        
status_fail:
        .ascii  "Failed\n"
status_fail_size = . - status_fail        

arg0:
        .asciz  "/usr/bin/sleep"
//        .asciz  "/bin/true"
//        .asciz  "/bin/false"
arg1:
        .asciz  "1"
argv:
        .quad   arg0, arg1, 0         

        .data
exit_status:    
        .long   -1    
Post 26 Apr 2009, 15:11
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15913
Location: SDSS J140821.67+025733.2
Endre: Erm, any chance that you could post fasm code please? Strange that I would be expecting to see fasm code on the fasm board.
Post 26 Apr 2009, 15:16
View user's profile Send private message Visit poster's website Reply with quote
Endre



Joined: 29 Dec 2003
Posts: 212
Location: Budapest, Hungary
You're absolutely right, but programming syscalls in fasm is a pain, and I just wanted to show how things work but not how I can interpret dozen of headers.

Anyway fasm would not need anything else only this .if / .endif feature to be able to use c-headers (the way gas does) which would then make life of (not only unix) programmers easier.

But you're right again. I should write a script which could preprocess and convert a fasm-like source into compilable and strict fasm-syntax source. I just simply don't want to. Fasm has tones of superfluous features, maybe I can this way just protest for this missing but useful one Smile.
Post 26 Apr 2009, 16:05
View user's profile Send private message Reply with quote
Endre



Joined: 29 Dec 2003
Posts: 212
Location: Budapest, Hungary
Here a dumb solution to work-around revolution's problem. If you don't like it you may try baldr's proposal.
Code:
;;;
;;; Preprocessing:
;;; cpp -C -m32 vfork32.asm | awk 'BEGIN {while(getline && $1 !~ /FASMCODE/);} {print}' > vfork32_prep.asm
;;; Compiling:
;;; fasm vfork32_prep.asm
;;;

#include <asm/unistd.h>
#include <unistd.h>
#include <sys/wait.h>

;;; after the next line only fasm syntax is permitted
FASMCODE

format ELF executable
entry $

        ;; create new process
        mov     eax, __NR_vfork
        int     0x80
        ;; check if child or parent
        test    eax, eax
        jnz     parent_process
        ;; child process
        ;; start sleep application
        mov     eax, __NR_execve
        mov     ebx, arg0
        mov     ecx, argv
        xor     edx, edx
        int     0x80
        ;; execve returns only if any error occured,
        ;; so here we exit child process
        mov     ebx, eax
        mov     eax, __NR_exit
        int     0x80

        ;; parent process
parent_process:
        ;; wait for child process to complete
        mov     ebx, eax
        mov     ecx, exit_status
        mov     edx, WUNTRACED
        xor     esi, esi
        mov     eax, __NR_wait4
        int     0x80
        ;; print "Thread completed" message
        mov     eax, __NR_write
        mov     ebx, STDOUT_FILENO
        mov     ecx, msg
        mov     edx, msg_size
        int     0x80
        mov     eax, __NR_write
        mov     ecx, status_ok
        mov     edx, status_ok_size
        ;; only the least 8 bits of the exit status
        cmp     byte [exit_status + 1], 0
        jz      ok
        mov     ecx, status_fail
        mov     edx, status_fail_size
ok:
        int     0x80
        ;; exit
        xor     ebx, ebx
        mov     eax, __NR_exit
        int     0x80

msg:
        db      "Thread completed! Exit status: "
msg_size = $ - msg

status_ok:
        db      "Succeeded", 0xa
status_ok_size = $ - status_ok

status_fail:
        db      "Failed", 0xa
status_fail_size = $ - status_fail

arg0:
        db      "/usr/bin/sleep", 0
;;         db      "/bin/true", 0
;;         db      "/bin/false", 0
arg1:
        db      "1", 0
argv:
        dd      arg0, arg1, 0

        segment readable writeable
        
exit_status:
        dd      -1    


Last edited by Endre on 03 May 2009, 12:06; edited 1 time in total
Post 30 Apr 2009, 22:05
View user's profile Send private message Reply with quote
r22



Joined: 27 Dec 2004
Posts: 805
Cool hack Endre, keeping with the proud tradition of Linux "work-arounds".

Is AWK standard on most distros? I've only had experience with embeded linux (kernel 2.4.*) running on PPC.
Post 01 May 2009, 20:57
View user's profile Send private message AIM Address Yahoo Messenger Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2294
Location: Usono (aka, USA)
I don't know Awk, personally, but it looks like something sed would be good at. And sed is pretty standardized and ubiquitous (if you don't do anything really heavy-duty).
Post 02 May 2009, 10:15
View user's profile Send private message Visit poster's website Reply with quote
Endre



Joined: 29 Dec 2003
Posts: 212
Location: Budapest, Hungary
I changed a little bit ("FASMCODE" keyword commented out, sed added).
Code:
;;;
;;; Preprocessing:
;;; cpp -C -m32 vfork32.asm | awk '/^[ \t]*;+[ \t]*FASMCODE/,EMPTY' > vfork32_prep.asm
;;; or
;;; cpp -C -m32 vfork32.asm | sed -n '/^[ \t]*;\+[ \t]*FASMCODE/,/$^/!b; p' > vfork32_prep.asm
;;;
;;; Compiling:
;;; fasm vfork32_prep.asm
;;;

#include <asm/unistd.h>
#include <unistd.h>
#include <sys/wait.h>

;;; after the next line only fasm code is permitted
;;; FASMCODE

;;; *** above fasm code here ***    
Post 03 May 2009, 12:05
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2018, Tomasz Grysztar.

Powered by rwasa.