
   Writing resident programs under Linux

   There  are  at  least  two  ways to run a program in background under
   Linux:
    1. adding  an ampersand (&) to the command line, like this: "program
       param1 param2 param3 &".
    2. using the screen program, like this: "screen -m -d program param1
       param2".

   But  we aren't programmers to count on the user to run our program in
   one  of  these ways. I'll show you how to make you program put itself
   in  the  background.  We're first going to use the daemon system call
   (see:  man  3  daemon)  from  the  C library. This is why the program
   writing process will be different than usually:
    1. instead  of  using LD to link the program, we're going to use GCC
       (which,  seeing the .o extension in our file's name, will link it
       correctly with the C library, without compiling)
    2. since  we're  using  GCC and the C library (which already has its
       own  _start symbol), our code will begin with the main label (the
       same as in programs written in the C language)
    3. the daemon function must be declared as external (extern)

   To  see that our daemon (TSR in Linux) really is working, we'll put a
   loop  inside,  which  displays  a  message once in a while. To make a
   pause  in  execution,  we're  going  to  use the sys_nanosleep system
   function (number 162).
   As  you  can  see  on  the manual page, the daemon function accepts 2
   integers (DWORDs) as parameters:
     * first  parameter  (last put on the stack) tells whether to change
       the  process  working directory to the root directory /. We don't
       want to change, so we'll put a 1 in the parameter.
     * second  parameter  (first put on the stack) tell whether to close
       the  input  and  output streams. We don't want to close, so we'll
       put a 1 here, too.

   After  saying  all this, it's time to move on to the example program.
   Its  job  is  to go into daemon mode and infinitely display the given
   message  each  5 seconds. Thus, the fact that the program is working,
   will be visible on the terminal on which the program was started. The
   program  itself  will  also  be  visible on the processes list (ps -A
   command).  The  only way to stop it will be to kill it using the kill
   command.
   here's the code in NASM syntax:
   (skip the code)
; Program going into daemon mode
;
; Author: Bogdan D., bogdandr (at) op.pl
;
; assemble:
; nasm -f elf -o demon.o demon.asm
; gcc -o demon demon.o


extern daemon                   ; external function declaration

section .text                   ; beginning of the code section
global main                     ; the symbol "main" must be global
                                ; for GCC to see it

main:
        push    dword 1         ; second parameter
        push    dword 1         ; first parameter
        call    daemon          ; calling the daemon function
        add     esp, 8          ; removing parameters from the stack

                        ; interval between consecutive messages
                        ; will last for 5 seconds and 0 nanoseconds:
        mov     dword [t1+timespec.tv_nsec], 0
        mov     dword [t1+timespec.tv_sec], 5

.petla:
        mov     eax, 4          ; file writing function
        mov     ebx, 1          ; standard output
        mov     ecx, napis      ; what to write
        mov     edx, napis_dl   ; length of the message
        int     80h

        mov     eax, 162        ; sys_nanosleep
        mov     ebx, t1         ; wait for this long
        mov     ecx, 0  ; address of a second timespec structure for the resul
t
        int     80h             ; make the pause...

        jmp     .petla          ; start all over again....

                                ; the below code will never be executed
        mov     eax, 1
        xor     ebx, ebx
        int     80h             ; exit the program

section .data

napis           db      "Your daemon is peaking.", 10
napis_dl        equ     $ - napis

struc timespec                  ; timespec structure definition
                                ; (anly as a data type)
        .tv_sec:        resd 1
        .tv_nsec:       resd 1
endstruc

t1 istruc timespec              ; create the t1 variable as a whole
                                ; timespec structure

   Assembling and linking goes like this:
        nasm -f elf -o demon.o demon.asm
        gcc -o demon demon.o

   One  thing  needs  to  mentioned:  the  sole fact that a program is a
   daemon  does  NOT  mean  that it is working with root privileges (and
   whole of the system security is useless).
     ________________________________________________________________

   Writing resident programs with int 80h

   The  daemon  function is from the C library, but you can transform it
   into code which uses only the int 80h. The code of the function is in
   the  misc/daemon.c  file in the glibc library sources. It is not long
   and it can be easily transformed into the following macro:
   (skip the macro)
%macro daemon 2
        ; first parameter: nochdir - not to change the working
        ;                               directory to the root directory?
        ; second parameter: noclose - not to close stdin and stdout?

        mov     eax, 2
        int     80h             ; sys_fork

        cmp     eax, 0
        jl      %%koniec        ; EAX < 0 means error

        test    eax, eax
        jz      %%dalej         ; EAX = 0 in the child process
                                ; EAX > 0 in the parent process

        mov     eax, 1
        xor     ebx, ebx
        int     80h             ; sys_exit - parent finishes work

 %%glowny:      db      "/", 0
 %%devnull:     db      "/dev/null", 0

 %%dalej:
        mov     eax, 66         ; sys_setsid
        int     80h             ; create a new session and set GID

        cmp     eax, 0
        jl      %%koniec        ; EAX < 0 means error

        %if %1 = 0

                mov     eax, 12         ; sys_chdir
                mov     ebx, %%glowny
                int     80h             ; change directory to root
        %endif

        %if %2 = 0

                ; otwieramy /dev/null:
                mov     eax, 5
                mov     ebx, %%devnull
                mov     ecx, 2
                mov     edx, 0
                int     80h

                cmp     eax, 0
                jl      %%koniec        ; EAX < 0 means error

                mov     ebx, eax        ; EBX = /dev/null descriptor

                ; duplicate the standard input, output and error output
                ; descriptors to an open /dev/null descriptor and close
                ; the descriptor after this

                mov     eax, 63
                mov     ecx, 0          ; input
                int     80h

                mov     eax, 63
                mov     ecx, 1          ; output
                int     80h

                mov     eax, 63
                mov     ecx, 2          ; error output
                int     80h

                mov     eax, 6
                int     80h             ; close /dev/null

        %endif
 %%koniec:

%endmacro

; useage:
        daemon 1, 1     ; no PUSH and ADD ESP

   No we can go back to the old program type, where the start symbol was
   _start and linking was done with LD, and not GCC with the C library.

   On-line contents (Alt+2)
   Helpers for people with disabilities (Alt+0)
