1,32 → 1,35 |
; |
; 2021, Edited by Coldy |
; |
; This module same as original crt0.asm, but cut: |
; 1. virtual header block (hparams change to __app_params, hpath change to __app_path) |
; 2. init heap of memory - not needed because 68.18 (68.19) init heap implicitly |
; (it is does dll.obj) |
; 3. loader (he lives in dll.obj) |
; |
|
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' |
__DEBUG__ = 0 |
include '../../../../../proc32.inc' |
include '../../../../../macros.inc' |
include '../../../../../dll.inc' |
;include '../../../../../debug.inc' |
|
__app_params equ 0x1C ; Pointer to program arguments |
;__app_path equ 0x20 ; Pointer to program path |
;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, [__app_params] |
mov eax, [hparams] |
test eax, eax |
jz .without_path |
mov eax, path |
82,6 → 85,7 |
jmp .parse |
|
.run: |
call load_imports |
push argv |
push [argc] |
call main |
108,9 → 112,101 |
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: |
;DEBUGF 1, "Library: %s not loaded!\n", esi |
;mcall -1 |
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' |
123,5 → 219,3 |
path rb buf_len |
params rb buf_len |
|
;section '.data' |
;include_debug_strings ; ALWAYS present in data section |