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