Rev 6614 | Rev 6810 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5195 | clevermous | 1 | format PE DLL GUI 0.8 at 7FF00000h |
2 | entry start |
||
3 | include '../../struct.inc' |
||
4 | include '../../proc32.inc' |
||
5 | include 'fpo.inc' |
||
6 | include 'export.inc' |
||
7 | include 'pe.inc' |
||
8 | section '.text' code readable executable |
||
9 | |||
10 | FS_STACK_MAX equ dword [fs:4] |
||
11 | FS_STACK_MIN equ dword [fs:8] |
||
12 | FS_SELF_PTR equ dword [fs:0x18] |
||
13 | FS_ERRNO equ dword [fs:0x34] |
||
14 | FS_SYSCALL_PTR equ dword [fs:0xC0] |
||
15 | |||
16 | ENOMEM = 12 |
||
17 | |||
18 | DLL_PROCESS_DETACH = 0 |
||
19 | DLL_PROCESS_ATTACH = 1 |
||
20 | DLL_THREAD_ATTACH = 2 |
||
21 | DLL_THREAD_DETACH = 3 |
||
22 | |||
23 | SYSCALL_METHOD_I40 = 1 |
||
24 | SYSCALL_METHOD_SYSENTER = 2 |
||
25 | SYSCALL_METHOD_SYSCALL = 3 |
||
26 | |||
27 | ; Pointer to this structure is passed as the third argument |
||
28 | ; to 'start' procedure by the kernel. |
||
29 | struct kernel_init_data |
||
30 | version dw ? |
||
31 | flags dw ? |
||
32 | syscall_method dd ? |
||
33 | ; either one of SYSCALL_METHOD_xxx or pointer to procedure |
||
34 | exe_base dd ? |
||
35 | stack_base dd ? |
||
36 | stack_size dd ? |
||
37 | exe_path dd ? |
||
38 | command_line dd ? |
||
6614 | clevermous | 39 | environment dd ? |
5195 | clevermous | 40 | ends |
41 | |||
6767 | clevermous | 42 | include 'sync.inc' |
5195 | clevermous | 43 | include 'malloc.inc' |
6614 | clevermous | 44 | include 'peloader.inc' |
6767 | clevermous | 45 | include 'modules.inc' |
6614 | clevermous | 46 | include 'cmdline.inc' |
5195 | clevermous | 47 | |
48 | proc syscall_int40 |
||
49 | int 0x40 |
||
50 | ret |
||
51 | endp |
||
52 | |||
6614 | clevermous | 53 | proc syscall_sysenter |
54 | push ebp |
||
55 | mov ebp, esp |
||
56 | push @f |
||
57 | sysenter |
||
58 | @@: |
||
59 | pop edx |
||
60 | pop ecx |
||
61 | ret |
||
62 | endp |
||
63 | |||
64 | proc syscall_syscall |
||
65 | push ecx |
||
66 | syscall |
||
67 | pop ecx |
||
68 | ret |
||
69 | endp |
||
70 | |||
5195 | clevermous | 71 | proc kercall |
72 | jmp FS_SYSCALL_PTR |
||
73 | endp |
||
74 | |||
75 | prologue@proc equ fpo_prologue |
||
76 | epilogue@proc equ fpo_epilogue |
||
77 | |||
78 | proc start stdcall, dll_base, reason, reserved |
||
79 | ; 1. Do nothing unless called by the kernel for DLL_PROCESS_ATTACH. |
||
80 | cmp [reason], DLL_PROCESS_ATTACH |
||
81 | jnz .nothing |
||
6614 | clevermous | 82 | ; 2. Initialize process. |
83 | ; 2a. Validate version of the init struct. |
||
5195 | clevermous | 84 | ; If not known, say a debug message and die. |
85 | mov ebp, [reserved] |
||
6614 | clevermous | 86 | mov esi, [dll_base] |
5195 | clevermous | 87 | cmp [ebp+kernel_init_data.version], 1 |
88 | jnz .version_mismatch |
||
6614 | clevermous | 89 | ; 2b. Get the system call code. |
90 | ; Note: relocations have not been fixed yet, |
||
91 | ; so we cannot use absolute addresses, only RVAs. |
||
5195 | clevermous | 92 | mov eax, [ebp+kernel_init_data.syscall_method] |
93 | cmp eax, 0x10000 |
||
6614 | clevermous | 94 | jae .syscall_absolute |
95 | dec eax |
||
96 | mov edx, rva syscall_int40 |
||
97 | cmp eax, num_syscall_methods |
||
5195 | clevermous | 98 | jae @f |
6614 | clevermous | 99 | mov edx, [esi+eax*4+rva syscall_methods] |
5195 | clevermous | 100 | @@: |
6614 | clevermous | 101 | lea eax, [edx+esi] |
102 | .syscall_absolute: |
||
5195 | clevermous | 103 | mov FS_SYSCALL_PTR, eax |
6614 | clevermous | 104 | ; 2c. Fixup relocations so that we can use absolute offsets instead of RVAs |
105 | ; in rest of code. |
||
106 | ; Note: this uses syscalls, so this step should be done after |
||
107 | ; configuring FS_SYSCALL_PTR at step 2b. |
||
108 | push kolibri_dll |
||
109 | call fixup_pe_relocations |
||
110 | pop ecx |
||
111 | jc .die |
||
6767 | clevermous | 112 | ; 2d. Initialize process heap. |
5195 | clevermous | 113 | mov eax, [ebp+kernel_init_data.exe_base] |
114 | mov edx, [eax+STRIPPED_PE_HEADER.SizeOfHeapReserve] |
||
115 | cmp word [eax], 'MZ' |
||
116 | jnz @f |
||
117 | add eax, [eax+IMAGE_DOS_HEADER.e_lfanew] |
||
118 | mov edx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeapReserve] |
||
119 | @@: |
||
120 | malloc_init |
||
6767 | clevermous | 121 | ; 2e. Allocate and fill MODULE structs for main exe and kolibri.dll. |
122 | mov eax, [ebp+kernel_init_data.exe_path] |
||
123 | @@: |
||
124 | inc eax |
||
125 | cmp byte [eax-1], 0 |
||
126 | jnz @b |
||
127 | sub eax, [ebp+kernel_init_data.exe_path] |
||
128 | push eax |
||
129 | add eax, sizeof.MODULE |
||
130 | stdcall malloc, eax |
||
131 | test eax, eax |
||
132 | jz .die |
||
133 | mov ebx, eax |
||
134 | stdcall malloc, sizeof.MODULE + kolibri_dll.size |
||
135 | test eax, eax |
||
136 | jz .die |
||
137 | mov edx, modules_list |
||
138 | mov [edx+MODULE.next], ebx |
||
139 | mov [ebx+MODULE.next], eax |
||
140 | mov [eax+MODULE.next], edx |
||
141 | mov [edx+MODULE.prev], eax |
||
142 | mov [eax+MODULE.prev], ebx |
||
143 | mov [ebx+MODULE.prev], edx |
||
144 | push esi |
||
145 | mov esi, kolibri_dll |
||
146 | mov ecx, kolibri_dll.size |
||
147 | lea edi, [eax+MODULE.path] |
||
148 | rep movsb |
||
149 | pop esi |
||
150 | call init_module_struct |
||
151 | mov eax, ebx |
||
152 | mov esi, [ebp+kernel_init_data.exe_path] |
||
153 | pop ecx |
||
154 | lea edi, [ebx+MODULE.path] |
||
155 | rep movsb |
||
156 | mov esi, [ebp+kernel_init_data.exe_base] |
||
157 | call init_module_struct |
||
6614 | clevermous | 158 | ; 2f. Copy rest of init struct and free memory. |
159 | ; Parse command line to argc/argv here and move arguments to the heap |
||
160 | ; in order to save memory: init struct and heap use different pages, |
||
161 | ; but typically data from init struct are far from the entire page, |
||
162 | ; so moving it to heap does not increase actual physical heap size |
||
163 | ; and allows to free init struct. |
||
164 | mov eax, [ebp+kernel_init_data.stack_base] |
||
165 | mov FS_STACK_MIN, eax |
||
166 | add eax, [ebp+kernel_init_data.stack_size] |
||
167 | mov FS_STACK_MAX, eax |
||
168 | mov esi, [ebp+kernel_init_data.command_line] |
||
169 | xor edx, edx |
||
170 | xor edi, edi |
||
171 | call parse_cmdline |
||
172 | inc ebx ; argv[0] = exe path |
||
173 | .argc equ dll_base |
||
174 | .argv equ reason |
||
175 | .envp equ reserved |
||
176 | mov [.argc], ebx |
||
177 | sub esi, [ebp+kernel_init_data.command_line] |
||
178 | lea esi, [esi+(ebx+1)*4] |
||
179 | stdcall malloc, esi |
||
6767 | clevermous | 180 | test eax, eax |
181 | jz .die |
||
6614 | clevermous | 182 | mov [.argv], eax |
183 | mov edx, eax |
||
6767 | clevermous | 184 | lea edi, [eax+(ebx+1)*4] |
185 | mov eax, [modules_list + MODULE.next] |
||
186 | add eax, MODULE.path |
||
187 | mov [edx], eax |
||
6614 | clevermous | 188 | add edx, 4 |
189 | mov esi, [ebp+kernel_init_data.command_line] |
||
190 | call parse_cmdline |
||
191 | and dword [edx], 0 ; argv[argc] = NULL |
||
192 | and [.envp], 0 |
||
193 | mov eax, 68 |
||
194 | mov ebx, 13 |
||
195 | mov ecx, ebp |
||
196 | call FS_SYSCALL_PTR |
||
6767 | clevermous | 197 | ; 2g. Initialize mutex for list of MODULEs. |
198 | mov ecx, modules_mutex |
||
199 | call mutex_init |
||
200 | ; 2h. For console applications, call console.dll!con_init with default parameters. |
||
201 | mov eax, [modules_list + MODULE.next] |
||
202 | mov esi, [eax+MODULE.base] |
||
203 | mov al, [esi+STRIPPED_PE_HEADER.Subsystem] |
||
204 | cmp byte [esi], 'M' |
||
205 | jnz @f |
||
206 | mov eax, [esi+3Ch] |
||
207 | mov al, byte [esi+eax+IMAGE_NT_HEADERS.OptionalHeader.Subsystem] |
||
208 | @@: |
||
209 | cmp al, IMAGE_SUBSYSTEM_WINDOWS_CUI |
||
210 | jnz .noconsole |
||
211 | stdcall dlopen, console_dll, 0 |
||
212 | test eax, eax |
||
213 | jz .noconsole |
||
214 | stdcall dlsym, eax, con_init_str |
||
215 | test eax, eax |
||
216 | jz .noconsole |
||
217 | mov edx, [modules_list + MODULE.next] |
||
218 | stdcall eax, -1, -1, -1, -1, [edx+MODULE.filename] |
||
219 | .noconsole: |
||
6614 | clevermous | 220 | ; 3. Configure modules: main EXE and possible statically linked DLLs. |
6767 | clevermous | 221 | mov eax, [modules_list + MODULE.next] |
222 | mov esi, [eax+MODULE.base] |
||
223 | add eax, MODULE.path |
||
224 | push eax |
||
6614 | clevermous | 225 | call fixup_pe_relocations |
226 | pop ecx |
||
227 | jc .die |
||
6767 | clevermous | 228 | mutex_lock modules_mutex |
229 | mov esi, [modules_list + MODULE.next] |
||
230 | call resolve_pe_imports |
||
231 | mov ebx, eax |
||
232 | mutex_unlock modules_mutex |
||
233 | test ebx, ebx |
||
234 | jnz .die |
||
6614 | clevermous | 235 | ; 4. Call exe entry point. |
6767 | clevermous | 236 | mov esi, [esi+MODULE.base] |
6614 | clevermous | 237 | mov edx, [esi+STRIPPED_PE_HEADER.AddressOfEntryPoint] |
6767 | clevermous | 238 | cmp byte [esi], 'M' |
5195 | clevermous | 239 | jnz @f |
6614 | clevermous | 240 | mov ecx, [esi+IMAGE_DOS_HEADER.e_lfanew] |
241 | add ecx, esi |
||
5195 | clevermous | 242 | mov edx, [ecx+IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint] |
243 | @@: |
||
6614 | clevermous | 244 | add edx, esi |
6767 | clevermous | 245 | pop ecx |
246 | mov [process_initialized], 1 |
||
5195 | clevermous | 247 | call edx |
248 | ; If exe entry point has returned control, die. |
||
6614 | clevermous | 249 | jmp .die |
250 | .version_mismatch: |
||
251 | lea eax, [esi + rva syscall_int40] |
||
252 | mov FS_SYSCALL_PTR, eax |
||
253 | add esi, rva msg_version_mismatch |
||
254 | call sys_msg_board_str |
||
255 | .die: |
||
256 | or eax, -1 |
||
5195 | clevermous | 257 | call FS_SYSCALL_PTR |
6614 | clevermous | 258 | .nothing: |
259 | ret |
||
260 | endp |
||
261 | |||
262 | proc sys_msg_board_str |
||
263 | push eax ebx |
||
5195 | clevermous | 264 | @@: |
6614 | clevermous | 265 | push ecx |
266 | mov cl, [ecx] |
||
5195 | clevermous | 267 | test cl, cl |
268 | jz @f |
||
6614 | clevermous | 269 | mov eax, 63 |
270 | mov ebx, 1 |
||
271 | call FS_SYSCALL_PTR |
||
272 | pop ecx |
||
273 | inc ecx |
||
5195 | clevermous | 274 | jmp @b |
275 | @@: |
||
6614 | clevermous | 276 | pop ecx ebx eax |
5195 | clevermous | 277 | ret |
278 | endp |
||
279 | |||
280 | align 4 |
||
6614 | clevermous | 281 | syscall_methods dd rva syscall_int40, rva syscall_sysenter, rva syscall_syscall |
282 | num_syscall_methods = ($ - syscall_methods) / 4 |
||
283 | |||
284 | align 4 |
||
5195 | clevermous | 285 | data export |
286 | export 'kolibri.dll' \ |
||
287 | , kercall, 'kercall' \ |
||
288 | , malloc, 'malloc' \ |
||
289 | , free, 'free' \ |
||
290 | , calloc, 'calloc' \ |
||
291 | , realloc, 'realloc' \ |
||
292 | , realloc_in_place, 'realloc_in_place' \ |
||
293 | , memalign, 'memalign' \ |
||
294 | , create_mspace, 'create_mspace' \ |
||
295 | , destroy_mspace, 'destroy_mspace' \ |
||
296 | , mspace_malloc, 'mspace_malloc' \ |
||
297 | , mspace_free, 'mspace_free' \ |
||
298 | , mspace_calloc, 'mspace_calloc' \ |
||
299 | , mspace_realloc, 'mspace_realloc' \ |
||
300 | , mspace_realloc_in_place, 'mspace_realloc_in_place' \ |
||
301 | , mspace_memalign, 'mspace_memalign' \ |
||
6767 | clevermous | 302 | , dlopen, 'dlopen' \ |
303 | , dlclose, 'dlclose' \ |
||
304 | , dlsym, 'dlsym' \ |
||
5195 | clevermous | 305 | |
306 | end data |
||
307 | |||
6767 | clevermous | 308 | kolibri_dll db '/rd/1/lib/kolibri.dll',0 |
309 | .size = $ - kolibri_dll |
||
5195 | clevermous | 310 | |
6767 | clevermous | 311 | console_dll db 'console.dll',0 |
312 | con_init_str db 'con_init',0 |
||
313 | |||
6614 | clevermous | 314 | msg_version_mismatch db 'S : Version mismatch between kernel and kolibri.dll',13,10,0 |
6767 | clevermous | 315 | msg_bad_relocation db 'Bad relocation type in ',0 |
6614 | clevermous | 316 | msg_newline db 13,10,0 |
317 | msg_relocated1 db 'S : fixups for ',0 |
||
318 | msg_relocated2 db ' applied',13,10,0 |
||
6767 | clevermous | 319 | msg_noreloc1 db 'Module ',0 |
320 | msg_noreloc2 db ' is not at preferred base and has no fixups',0 |
||
321 | loader_debugboard_prefix db 'S : ',0 |
||
322 | notify_program db '/rd/1/@notify',0 |
||
323 | msg_cannot_open db 'Cannot open ',0 |
||
324 | msg_paths_begin db ' in any of ' |
||
6614 | clevermous | 325 | |
6767 | clevermous | 326 | module_path1 db '/rd/1/lib/' |
327 | .size = $ - module_path1 |
||
328 | db ', ' |
||
329 | module_path2 db '/kolibrios/lib/' |
||
330 | .size = $ - module_path2 |
||
331 | db ', ',0 |
||
332 | msg_export_name_not_found db 'Exported function ',0 |
||
333 | msg_export_ordinal_not_found db 'Exported ordinal #',0 |
||
334 | msg_export_not_found db ' not found in module ',0 |
||
335 | msg_unknown db ' |
||
336 | |||
337 | section '.data' data readable writable |
||
5195 | clevermous | 338 | if FOOTERS |
339 | malloc_magic dd ? |
||
340 | end if |
||
6767 | clevermous | 341 | default_heap dd ? |
342 | modules_list rd 2 |
||
343 | modules_mutex MUTEX |
||
344 | process_initialized db ? |