kolibrios/kernel/trunk/core/peload.inc

300 lines
8.1 KiB
PHP
Raw Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
include 'export.inc'
align 4
; This function load file driver and output
; eax = address function START in driver
; ebx = address for kernel_free
proc load_PE stdcall, file_name:dword
locals
image dd ?
entry dd ?
base dd ?
endl
stdcall load_file, [file_name]
test eax, eax
jz .fail
mov [image], eax
mov edx, [eax + STRIPPED_PE_HEADER.SizeOfImage]
; mov cl, [eax + STRIPPED_PE_HEADER.Subsystem]
cmp word [eax], STRIPPED_PE_SIGNATURE
jz @f
mov edx, [eax + 60]
; mov cl, [eax + 5Ch + edx]
mov edx, [eax + 80 + edx]
@@:
mov [entry], 0
; cmp cl, 1
; jnz .cleanup
stdcall kernel_alloc, edx
test eax, eax
jz .cleanup
mov [base], eax
DEBUGF 1,'K : driver %s mapped to %x\n',[file_name],[base]
push ebx ebp
mov ebx, [image]
mov ebp, eax
call map_PE
pop ebp ebx
mov [entry], eax
test eax, eax
jnz .cleanup
stdcall kernel_free, [base]
.cleanup:
stdcall kernel_free, [image]
mov eax, [entry]
mov ebx, [base]
ret
.fail:
xor eax, eax
ret
endp
map_PE: ;ebp=base:dword, ebx=image:dword
push edi
push esi
sub esp, .locals_size
virtual at esp
.numsections dd ?
.import_names dd ?
.import_targets dd ?
.peheader dd ?
.bad_import dd ?
.import_idx dd ?
.import_descr dd ?
.relocs_rva dd ?
.relocs_size dd ?
.section_header_size dd ?
.AddressOfEntryPoint dd ?
.ImageBase dd ?
.locals_size = $ - esp
end virtual
cmp word [ebx], STRIPPED_PE_SIGNATURE
jz .stripped
mov edx, ebx
add edx, [ebx + 60]
movzx eax, word [edx + 6]
mov [.numsections], eax
mov eax, [edx + 40]
mov [.AddressOfEntryPoint], eax
mov eax, [edx + 52]
mov [.ImageBase], eax
mov ecx, [edx + 84]
mov [.section_header_size], 40
mov eax, [edx + 128]
mov [.import_descr], eax
mov eax, [edx + 160]
mov [.relocs_rva], eax
mov eax, [edx + 164]
mov [.relocs_size], eax
add edx, 256
jmp .common
.stripped:
mov eax, [ebx + STRIPPED_PE_HEADER.AddressOfEntryPoint]
mov [.AddressOfEntryPoint], eax
mov eax, [ebx + STRIPPED_PE_HEADER.ImageBase]
mov [.ImageBase], eax
movzx eax, [ebx + STRIPPED_PE_HEADER.NumberOfSections]
mov [.numsections], eax
movzx ecx, [ebx + STRIPPED_PE_HEADER.NumberOfRvaAndSizes]
xor eax, eax
mov [.relocs_rva], eax
mov [.relocs_size], eax
test ecx, ecx
jz @f
mov eax, [ebx + sizeof.STRIPPED_PE_HEADER + SPE_DIRECTORY_IMPORT*8]
@@:
mov [.import_descr], eax
cmp ecx, SPE_DIRECTORY_BASERELOC
jbe @f
mov eax, [ebx + sizeof.STRIPPED_PE_HEADER + SPE_DIRECTORY_BASERELOC*8]
mov [.relocs_rva], eax
mov eax, [ebx + sizeof.STRIPPED_PE_HEADER + SPE_DIRECTORY_BASERELOC*8+4]
mov [.relocs_size], eax
@@:
mov [.section_header_size], 28
lea edx, [ebx + ecx*8 + sizeof.STRIPPED_PE_HEADER + 8]
mov ecx, [ebx + STRIPPED_PE_HEADER.SizeOfHeaders]
.common:
mov esi, ebx
mov edi, ebp
shr ecx, 2
rep movsd
cmp [.numsections], 0
jz .nosections
.copy_sections:
mov eax, [edx + 8]
test eax, eax
je .no_section_data
mov esi, ebx
mov edi, ebp
add esi, [edx + 12]
mov ecx, eax
add edi, [edx + 4]
add ecx, 3
shr ecx, 2
rep movsd
.no_section_data:
mov ecx, [edx]
cmp ecx, eax
jbe .no_section_fill
sub ecx, eax
add eax, [edx + 4]
lea edi, [eax+ebp]
xor eax, eax
rep stosb
.no_section_fill:
add edx, [.section_header_size]
dec [.numsections]
jnz .copy_sections
.nosections:
cmp [.relocs_size], 0
je .no_relocations
mov esi, ebp
mov ecx, ebp
sub esi, [.ImageBase]
add ecx, [.relocs_rva]
.relocs_block:
mov edi, [ecx]
add edi, ebp
mov ebx, [ecx + 4]
add ecx, 8
sub [.relocs_size], ebx
sub ebx, 8
shr ebx, 1
jz .relocs_next_block
.one_reloc:
movzx eax, word [ecx]
add ecx, 2
mov edx, eax
shr eax, 12
and edx, 4095
cmp eax, 3
jne @f
add [edx+edi], esi
@@:
dec ebx
jnz .one_reloc
.relocs_next_block:
cmp [.relocs_size], 0
jg .relocs_block
.no_relocations:
cmp [.import_descr], 0
je .no_imports
add [.import_descr], ebp
mov [.bad_import], 0
.import_block:
mov ecx, [.import_descr]
cmp dword [ecx + 4], 0
jne @f
cmp dword [ecx + 12], 0
je .done_imports
@@:
mov edx, dword [ecx]
mov ecx, dword [ecx + 16]
test edx, edx
jnz @f
mov edx, ecx
@@:
mov [.import_idx], 0
add ecx, ebp
add edx, ebp
mov [.import_names], edx
mov [.import_targets], ecx
.import_func:
mov esi, [.import_idx]
mov edi, [.import_names]
mov eax, [edi + esi*4]
test eax, eax
je .next_import_block
js .next_import_block
lea edi, [ebp + eax]
mov eax, [.import_targets]
mov dword [eax + esi*4], 0
lea esi, [edi + 2]
movzx ebx, word [edi]
push 32
mov ecx, [__exports + 32]
mov eax, [ecx + OS_BASE + ebx*4]
add eax, OS_BASE
push eax
push esi
call strncmp
test eax, eax
jz .import_func_found
xor ebx, ebx
.import_func_candidate:
push 32
mov ecx, [__exports + 32]
mov eax, [ecx + OS_BASE + ebx*4]
add eax, OS_BASE
push eax
push esi
call strncmp
test eax, eax
je .import_func_found
inc ebx
cmp ebx, [__exports + 24]
jb .import_func_candidate
mov esi, msg_unresolved
call sys_msg_board_str
lea esi, [edi + 2]
call sys_msg_board_str
mov esi, msg_CR
call sys_msg_board_str
mov [.bad_import], 1
jmp .next_import_func
.import_func_found:
mov esi, [__exports + 28]
mov edx, [.import_idx]
mov ecx, [.import_targets]
mov eax, [esi + OS_BASE + ebx*4]
add eax, OS_BASE
mov [ecx + edx*4], eax
.next_import_func:
inc [.import_idx]
jmp .import_func
.next_import_block:
add [.import_descr], 20
jmp .import_block
.done_imports:
xor eax, eax
cmp [.bad_import], 0
jne @f
.no_imports:
mov eax, ebp
add eax, [.AddressOfEntryPoint]
@@:
add esp, .locals_size
pop esi
pop edi
ret