forked from KolibriOS/kolibrios
221 lines
5.8 KiB
NASM
221 lines
5.8 KiB
NASM
|
format ELF
|
|||
|
section '.text' executable
|
|||
|
public start
|
|||
|
public start as '_start'
|
|||
|
;extrn mf_init
|
|||
|
extrn main
|
|||
|
;include 'debug2.inc'
|
|||
|
include '..\..\..\..\..\proc32.inc'
|
|||
|
include '..\..\..\..\..\macros.inc'
|
|||
|
include '..\..\..\..\..\dll.inc'
|
|||
|
__DEBUG__=0
|
|||
|
|
|||
|
;start_:
|
|||
|
virtual at 0
|
|||
|
db 'MENUET01' ; 1. Magic number (8 bytes)
|
|||
|
dd 0x01 ; 2. Version of executable file
|
|||
|
dd start ; 3. Start address
|
|||
|
imgsz dd 0x0 ; 4. Size of image
|
|||
|
dd 0x100000 ; 5. Size of needed memory
|
|||
|
dd 0x100000 ; 6. Pointer to stack
|
|||
|
hparams dd 0x0 ; 7. Pointer to program arguments
|
|||
|
hpath dd 0x0 ; 8. Pointer to program path
|
|||
|
end virtual
|
|||
|
|
|||
|
start:
|
|||
|
;DEBUGF 'Start programm\n'
|
|||
|
;init heap of memory
|
|||
|
mov eax,68
|
|||
|
mov ebx,11
|
|||
|
int 0x40
|
|||
|
|
|||
|
mov [argc], 0
|
|||
|
mov eax, [hparams]
|
|||
|
test eax, eax
|
|||
|
jz .without_path
|
|||
|
mov eax, path
|
|||
|
cmp word ptr eax, 32fh ; '/#3' UTF8
|
|||
|
jne .without_path
|
|||
|
mov word ptr eax, 12fh ; '/#1' fix to CP866
|
|||
|
.without_path:
|
|||
|
mov esi, eax
|
|||
|
call push_param
|
|||
|
; retrieving parameters
|
|||
|
mov esi, params
|
|||
|
xor edx, edx ; dl - <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(1) <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(0)
|
|||
|
; dh - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> (1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, 0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
|||
|
mov ecx, 1 ; cl = 1
|
|||
|
; ch = 0 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
|||
|
.parse:
|
|||
|
lodsb
|
|||
|
test al, al
|
|||
|
jz .run
|
|||
|
test dl, dl
|
|||
|
jnz .findendparam
|
|||
|
;{<7B><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
cmp al, ' '
|
|||
|
jz .parse ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
mov dl, cl ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
cmp al, '"'
|
|||
|
jz @f ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
mov dh, ch ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
dec esi
|
|||
|
call push_param
|
|||
|
inc esi
|
|||
|
jmp .parse
|
|||
|
|
|||
|
@@:
|
|||
|
mov dh, cl ;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
call push_param ;<3B><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
jmp .parse ;<3B><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>}
|
|||
|
|
|||
|
.findendparam:
|
|||
|
test dh, dh
|
|||
|
jz @f ; <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
cmp al, '"'
|
|||
|
jz .clear
|
|||
|
jmp .parse
|
|||
|
@@:
|
|||
|
cmp al, ' '
|
|||
|
jnz .parse
|
|||
|
|
|||
|
.clear:
|
|||
|
lea ebx, [esi - 1]
|
|||
|
mov [ebx], ch
|
|||
|
mov dl, ch
|
|||
|
jmp .parse
|
|||
|
|
|||
|
.run:
|
|||
|
call load_imports
|
|||
|
push argv
|
|||
|
push [argc]
|
|||
|
call main
|
|||
|
.exit:
|
|||
|
xor eax,eax
|
|||
|
dec eax
|
|||
|
int 0x40
|
|||
|
dd -1
|
|||
|
.crash:
|
|||
|
jmp .exit
|
|||
|
;============================
|
|||
|
push_param:
|
|||
|
;============================
|
|||
|
;parameters
|
|||
|
; esi - pointer
|
|||
|
;description
|
|||
|
; procedure increase argc
|
|||
|
; and add pointer to array argv
|
|||
|
; procedure changes ebx
|
|||
|
mov ebx, [argc]
|
|||
|
cmp ebx, max_parameters
|
|||
|
jae .dont_add
|
|||
|
mov [argv+4*ebx], esi
|
|||
|
inc [argc]
|
|||
|
.dont_add:
|
|||
|
ret
|
|||
|
;==============================
|
|||
|
|
|||
|
;==============================
|
|||
|
load_imports:
|
|||
|
;==============================
|
|||
|
;parameters
|
|||
|
; none
|
|||
|
;description
|
|||
|
; imports must be located at end of image (but before BSS sections)
|
|||
|
; the address of end of imports (next byte after imports) is located in imgsz
|
|||
|
; look at each import from that address up to illegal import
|
|||
|
; legal import is such that:
|
|||
|
; first pointer points to procedure name
|
|||
|
; and is smaller than imgsz
|
|||
|
; second pointer points lo library name, starting with 0x55, 0xAA
|
|||
|
; and is smaller than imgsz
|
|||
|
; each library should be initialized as appropriate, once
|
|||
|
; so as library is initialized, its name will be replaced 0x00
|
|||
|
mov ebx, [imgsz] ; byte after imports
|
|||
|
.handle_next_import:
|
|||
|
sub ebx, 4 ; ebx = pointer to pointer to library name
|
|||
|
mov esi, dword[ebx] ; esi = pointer to library name
|
|||
|
push ebx
|
|||
|
push esi
|
|||
|
call load_library ; eax = pointer to library exports
|
|||
|
pop esi
|
|||
|
pop ebx
|
|||
|
test eax, eax
|
|||
|
jz .done
|
|||
|
sub ebx, 4 ; ebx = pointer to pointer to symbol name
|
|||
|
push ebx
|
|||
|
stdcall dll.GetProcAddress, eax, dword[ebx]
|
|||
|
pop ebx
|
|||
|
test eax, eax
|
|||
|
jz .fail
|
|||
|
mov dword[ebx], eax
|
|||
|
jmp .handle_next_import
|
|||
|
.done:
|
|||
|
ret
|
|||
|
.fail:
|
|||
|
ret
|
|||
|
;==============================
|
|||
|
|
|||
|
;==============================
|
|||
|
load_library:
|
|||
|
;==============================
|
|||
|
;parameters
|
|||
|
; ebx: library name address
|
|||
|
;description
|
|||
|
; each library should be initialized as appropriate, once
|
|||
|
; so as library is initialized, its name will be replaced 0x00
|
|||
|
; and 4 next bytes will be set to address of library
|
|||
|
; first two bytes of library name must be 0x55, 0xAA (is like a magic)
|
|||
|
cld ; move esi further, not back
|
|||
|
cmp esi, [imgsz]
|
|||
|
ja .fail
|
|||
|
lodsb ; al = first byte of library name
|
|||
|
cmp al, 0x55
|
|||
|
jne .fail
|
|||
|
lodsb ; al = second byte of library name
|
|||
|
cmp al, 0xAA
|
|||
|
jne .fail
|
|||
|
lodsb ; al = third byte of library name (0x00 if the library is already loaded)
|
|||
|
test al, al
|
|||
|
jnz .load
|
|||
|
lodsd ; if we here, then third byte is 0x00 => address of library is in next 4 bytes
|
|||
|
; now eax contains address of library
|
|||
|
ret
|
|||
|
.load:
|
|||
|
dec esi ; we checked on 0 before, let's go back
|
|||
|
mov eax, 68
|
|||
|
mov ebx, 19
|
|||
|
mov ecx, esi
|
|||
|
int 0x40 ; eax = address of exports
|
|||
|
mov byte[esi], 0 ; library is loaded, let's place 0 in first byte of name
|
|||
|
mov [esi + 1], eax ; now next 4 bytes of library name are replaced by address of library
|
|||
|
; call lib_init
|
|||
|
stdcall dll.GetProcAddress, eax, lib_init_str ; eax = address of lib_init
|
|||
|
test eax, eax
|
|||
|
jz .ret
|
|||
|
stdcall dll.Init, eax
|
|||
|
.ret:
|
|||
|
mov eax, [esi + 1] ; put address of library into eax
|
|||
|
ret
|
|||
|
.fail:
|
|||
|
mov eax, 0
|
|||
|
ret
|
|||
|
;==============================
|
|||
|
|
|||
|
lib_init_str db 'lib_init', 0
|
|||
|
|
|||
|
public argc as '__argc'
|
|||
|
public params as '__argv'
|
|||
|
public path as '__path'
|
|||
|
|
|||
|
section '.bss'
|
|||
|
buf_len = 0x400
|
|||
|
max_parameters=0x20
|
|||
|
argc rd 1
|
|||
|
argv rd max_parameters
|
|||
|
path rb buf_len
|
|||
|
params rb buf_len
|
|||
|
|
|||
|
;section '.data'
|
|||
|
;include_debug_strings ; ALWAYS present in data section
|