Code: Select all
MAX_SUPPORTED_MENUET_FILE_VERSION = 2
proc fs_execute
; edx = flags
; ecx -> cmdline
; ebx -> absolute file path
; eax = string length
locals
cmdline rd 1
flags rd 1
slot rd 1
slot_base rd 1
; app header data
hdr_cmdline rd 1
hdr_path rd 1
hdr_eip rd 1
hdr_esp rd 1
hdr_edata rd 1
hdr_emem rd 1
file_base rd 1
file_size rd 1
filename_size rd 1
cmdline_size rd 1
path_string rd 1
endl
mov [flags], edx
mov [cmdline], ecx
mov [path_string], ebx
mov [filename_size], eax
mov esi, -ERROR_FILE_NOT_FOUND
test eax, eax
jz .err_file
stdcall load_file, ebx
test eax, eax
jz .err_file
mov [file_base], eax
mov [file_size], ebx
lea ebx, [hdr_cmdline]
call test_app_header
mov esi, -0x1F
test eax, eax
jz .err_hdr
call lock_application_table
call alloc_thread_slot
mov esi, -0x20 ; too many processes
test eax, eax
jz .err_0
mov [slot], eax
shl eax, 8
lea edi, [SLOT_BASE+eax]
mov [slot_base], edi
; clean extended information about process
mov ecx, sizeof.APPDATA/4
xor eax, eax
cld
rep stosd
; write application name
stdcall strrchr, [path_string], '/'
lea esi, [eax+1] ; -> name without path
mov ecx, 11
mov edi, [slot_base]
@@:
call utf8to16
call uni2ansi_char
cmp al, '.'
jz @f
test al, al
jz @f
stosb
loop @b
@@:
mov edi, [cmdline]
xor eax, eax
test edi, edi
jz @f
mov ecx, 65535
call _strnlen
cmp eax, 256
jb @f
lea ebx, [eax+1]
add [hdr_emem], ebx
@@:
mov [cmdline_size], eax
stdcall create_process, [hdr_emem]
mov esi, -30 ; no memory
test eax, eax
jz .err_hdr
mov ebx, [sys_proc+LHEAD.prev]
__list_add eax, ebx, sys_proc
mov ebx, [hdr_emem]
mov [eax+PROC.mem_used], ebx
mov ebx, [slot_base]
mov [ebx+APPDATA.process], eax
lea edx, [ebx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail edx, ecx
mov eax, [cmdline_size]
add eax, sizeof.APP_HDR
stdcall kernel_alloc, eax
mov [ebx+APPDATA.exec_params], eax
mov edi, eax
lea esi, [hdr_cmdline]
mov ecx, sizeof.APP_HDR/4
rep movsd
mov ecx, [cmdline_size]
mov esi, [cmdline]
rep movsb
lea eax, [hdr_cmdline]
stdcall set_app_params , [slot], eax, [flags]
call try_to_load_imports_if_any
test eax,eax
js .err_with_cleanup_needance
mov eax, [process_number] ;set result
call unlock_application_table
ret
.err_with_cleanup_needance:
; we must free all entities that created since lock_application_table
; and make slot back freed
.err_0:
call unlock_application_table
.err_hdr:
stdcall kernel_free, [file_base]
.err_file:
stdcall kernel_free, [path_string]
mov eax, esi
ret
endp
align 4
try_to_load_imports_if_any:
pushad
mov ebp, eax
mov eax, [ebp+36] ; +36 - imports field
test eax, eax
jz .locret ; no imports section
cmp eax, [ebp+16] ; check that content fit in init range
jae .locret ; more likely app dont know about placing imports there
cmp dword[eax], 'ProM' ; check import signature
jne .locret ; more likely app dont know about placing imports there
cmp dword[eax+4], 'iNic' ; check import signature
jne .locret ; more likely app dont know about placing imports there
cmp byte[eax+8], 'k' ; I stolen 12 bytes for signature
jne .locret ; more likely app dont know about placing imports there
add eax,12
push eax
jmp LoadLibraries
.locret:
popad
xor esi, esi
ret
virtual at 0
LIBRARY_ENTRY:
.lookup_table dd ?
.lpname dd ?
sizeof.LIBRARY_ENTRY = $
end virtual
virtual at 0
EXPORT_ENTRY:
.lpname dd ?
.lpproc dd ?
sizeof.EXPORT_ENTRY = $
end virtual
virtual at 0
IMPORT_ENTRY:
.lpproc dd ?
sizeof.IMPORT_ENTRY = $
end virtual
GetStrLength:
; string: [in] edi
; string length: [out] ecx
; [unchanged] ebx, edx, esi, edi, ebp, esp
or ecx, -1
xor eax, eax
cld
repne scasb
not ecx
sub edi,ecx
retn
GetProcOrdinalAddress:
; hInstance (export table): [in] esi
; proc ordinal: [in] edi
; proc address: [out] eax
; [unchanged] ebx, ecx, edx, ebp, esp
xor edi, $80000000
.check_entry:
mov eax, [esi+EXPORT_ENTRY.lpname]
test eax, eax
jz .not_found
sub edi, 1
je .matched
add esi, sizeof.EXPORT_ENTRY
jmp .check_entry
.matched:
mov eax, [esi+EXPORT_ENTRY.lpproc]
.not_found:
retn
GetProcAddress:
; hInstance (export table): [in] esi
; proc name: [in] edi
; proc address: [out] eax
; [unchanged] ebp, esp
call GetStrLength
mov edx, ecx
mov ebx, edi
mov eax, esi
.check_entry:
mov esi, ebx
mov edi, [eax+EXPORT_ENTRY.lpname]
test edi, edi
jz .not_found
repe cmpsb
je .matched
mov ecx, edx
add eax, sizeof.EXPORT_ENTRY
jmp .check_entry
.not_found:
sub eax, EXPORT_ENTRY.lpproc
.matched:
mov eax, [eax+EXPORT_ENTRY.lpproc]
retn
ResolveImports:
; hInstance (export table): [in] esi
; lib.lookup table: [in] ebp
; ?isResolved: [out] eax
; [unchanged] esi, esp
load_libraries_error equ esp+16
.import_loop:
mov edi, [ebp+IMPORT_ENTRY.lpproc]
test edi, edi
jz .done
push esi
js .search_by_ordinal
call GetProcAddress
jmp .get_proc_addr_done
.search_by_ordinal:
call GetProcOrdinalAddress
.get_proc_addr_done:
pop esi
test eax, eax
jz .import_not_found
mov [ebp+IMPORT_ENTRY.lpproc], eax
add ebp, sizeof.IMPORT_ENTRY
jmp .import_loop
.import_not_found:
or [ebp+IMPORT_ENTRY.lpproc], -1
or dword[load_libraries_error], -$1001
if defined unresolved_proc_termination
jmp ShowImportErrorWindow
else
add ebp, sizeof.IMPORT_ENTRY
jmp .import_loop
end if
.done:
retn
restore load_libraries_error
@copy_path_wo_pdname:
; library name: [in] edx
; result path: [in] esi
; library path: [in] edi
; [out] no
; [unchanged] ebx, edx, ebp, esp
call GetStrLength
add edi, ecx
mov al, '/'
std
repne scasb
cld
sub edi, ecx
add ecx, 2
xchg esi, edi
mov eax, ecx
shr ecx, 2
rep movsd
mov ecx, eax
and ecx, 3
rep movsb
mov esi, edx
xchg esi, edi
call GetStrLength
xchg esi, edi
mov eax, ecx
shr ecx, 2
rep movsd
mov ecx, eax
and ecx, 3
rep movsb
retn
LoadLibrary:
; library name: [in] edx
; hInstance (export table): [out] eax
; [unchanged] edx, ebp, esp
mov edi, cur_dir_path
mov esi, library_path
call @copy_path_wo_pdname
mcall SF_SYS_MISC,SSF_LOAD_DLL,library_path
test eax, eax
jnz .done
mov edi, LoadLibrary.sys_lib_path
mov esi, library_path
call @copy_path_wo_pdname
mcall SF_SYS_MISC,SSF_LOAD_DLL,library_path
.done:
retn
.sys_lib_path db '/sys/lib/',0
TryEnterLibEntryPoint:
; hInstance (export table): [in] esi
; [out] no
; [unchanged] esp
mov edi, TryEnterLibEntryPoint.name
call GetProcAddress
test eax, eax
jz .processed
push eax
mov eax, mem.Alloc
mov ebx, mem.Free
mov ecx, mem.ReAlloc
mov edx, LoadLibraries
.processed:
retn
.name db 'lib_init',0
align 4
proc LoadLibraries stdcall, current_lib_entry,pushad_edi,load_libraries_error,pushad_ebp,pushad_esp,pushad_ebx,pushad_edx,pushad_ecx,file_base
; eax -> import.root aka 1st_lib_entry
.LoopLibraries:
mov eax, [current_lib_entry]
mov ebp, [eax+LIBRARY_ENTRY.lookup_table]
test ebp, ebp
jz .done
mov edx, [eax+LIBRARY_ENTRY.lpname]
call LoadLibrary;edx=name
test eax, eax
jz .loadlibError
mov esi, eax
mov eax, dword[current_lib_entry]
call ResolveImports
call TryEnterLibEntryPoint
add dword[current_lib_entry], sizeof.LIBRARY_ENTRY
jmp .LoopLibraries
.loadlibError:
call DisplayErrorSomeway
mov [load_libraries_error],-$1000
ret
endp
mem.Alloc:
size equ esp+4
push ebx
push ecx
mcall SF_SYS_MISC, SSF_MEM_ALLOC, dword[size]
pop ecx
pop ebx
retn 4
restore size
mem.ReAlloc:
mptr equ esp+4
size equ esp+8
push ebx
push ecx
push edx
mcall SF_SYS_MISC, SSF_MEM_REALLOC, dword[size], dword[mptr]
pop edx
pop ecx
pop ebx
retn 8
restore size,mptr
mem.Free:
mptr equ esp+4
push ebx
push ecx
mcall SF_SYS_MISC, SSF_MEM_FREE, dword[mptr]
pop ecx
pop ebx
retn 4
restore mptr
align 4
DisplayErrorSomeway: ret ; òîëüêî çàãëóøêà
align 4
LoadLibrary:
; library name: [in] edx
; hInstance (export table): [out] eax
; [unchanged] edx, ebp, esp
mov edi, cur_dir_path
mov esi, library_path
call @copy_path_wo_pdname
mcall SF_SYS_MISC,SSF_LOAD_DLL,library_path
test eax, eax
jnz .done
mov edi, LoadLibrary.sys_lib_path
mov esi, library_path
call @copy_path_wo_pdname
mcall SF_SYS_MISC,SSF_LOAD_DLL,library_path
.done:
retn
.sys_lib_path db '/sys/lib/',0
align 4
test_app_header:
virtual at eax
APP_HEADER_00 APP_HEADER_00_
end virtual
virtual at eax
APP_HEADER_01 APP_HEADER_01_
end virtual
cmp dword [eax], 'MENU'
je .menuet_may_be
cmp dword [eax], 'KOLI'
jne .fail
cmp dword [eax+4], 'BRI1'
jne .fail
jmp .banner_OK
.menuet_may_be:
cmp word [eax+4], 'ET'
jne .fail
.banner_OK:
mov ecx, [APP_HEADER_00.start]
mov [ebx+APP_HDR.eip], ecx
mov ecx, [APP_HEADER_00.mem_size]
mov edx, [APP_HEADER_00.i_end]
cmp ecx, edx ; {diamond}[20.08.2006] test that inited mem fit in allocated mem to prevent kernel faults
jb .fail
mov [ebx+APP_HDR._emem], ecx
mov [ebx+APP_HDR._edata], edx
mov dx, word [eax+6]
cmp dx, 'I1'
jz .skip_menuet_checks
sub dx, '00'
jne .check_01_header
mov [ebx+APP_HDR.path], 0
shr ecx, 1
sub ecx, 0x10
mov edx, [APP_HEADER_00.i_param]
jmp @F
.check_01_header:
cmp dx, MAX_SUPPORTED_MENUET_FILE_VERSION
ja .fail
.skip_menuet_checks:
mov ecx, [APP_HEADER_01.i_icon]
mov [ebx+APP_HDR.path], ecx
mov ecx, [APP_HEADER_01.stack_top]
mov edx, [APP_HEADER_01.i_param]
@@:
mov [ebx+APP_HDR.esp], ecx
mov [ebx+APP_HDR.cmdline], edx
ret
.fail:
xor eax, eax
ret
одно но проброс лоадлибрари в библиотеки был юзермодной лоадлибрари, а если система теперь сразу это уметь будет, то при загрузке библиотеки уже должны грузится ее импорты.
Походу реализацию импорта надо где то на загрузке либ - туда реализовывать, а тут (в менуэт формате) лишь использовать.
будем изучать начинку ядра за реализацию mcall SF_SYS_MISC,SSF_LOAD_DLL - она и должна разрешать импорты для коффов.