Rev 5195 | 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_PROCESS_DATA equ dword [fs:0x30] |
||
14 | FS_ERRNO equ dword [fs:0x34] |
||
15 | FS_SYSCALL_PTR equ dword [fs:0xC0] |
||
16 | |||
17 | ENOMEM = 12 |
||
18 | |||
19 | DLL_PROCESS_DETACH = 0 |
||
20 | DLL_PROCESS_ATTACH = 1 |
||
21 | DLL_THREAD_ATTACH = 2 |
||
22 | DLL_THREAD_DETACH = 3 |
||
23 | |||
24 | SYSCALL_METHOD_I40 = 1 |
||
25 | SYSCALL_METHOD_SYSENTER = 2 |
||
26 | SYSCALL_METHOD_SYSCALL = 3 |
||
27 | |||
28 | ; Pointer to this structure is passed as the third argument |
||
29 | ; to 'start' procedure by the kernel. |
||
30 | struct kernel_init_data |
||
31 | version dw ? |
||
32 | flags dw ? |
||
33 | syscall_method dd ? |
||
34 | ; either one of SYSCALL_METHOD_xxx or pointer to procedure |
||
35 | exe_base dd ? |
||
36 | stack_base dd ? |
||
37 | stack_size dd ? |
||
38 | exe_path dd ? |
||
39 | command_line dd ? |
||
6614 | clevermous | 40 | environment dd ? |
5195 | clevermous | 41 | ends |
42 | |||
43 | include 'malloc.inc' |
||
6614 | clevermous | 44 | include 'peloader.inc' |
45 | include 'cmdline.inc' |
||
5195 | clevermous | 46 | |
47 | proc syscall_int40 |
||
48 | int 0x40 |
||
49 | ret |
||
50 | endp |
||
51 | |||
6614 | clevermous | 52 | proc syscall_sysenter |
53 | push ebp |
||
54 | mov ebp, esp |
||
55 | push @f |
||
56 | sysenter |
||
57 | @@: |
||
58 | pop edx |
||
59 | pop ecx |
||
60 | ret |
||
61 | endp |
||
62 | |||
63 | proc syscall_syscall |
||
64 | push ecx |
||
65 | syscall |
||
66 | pop ecx |
||
67 | ret |
||
68 | endp |
||
69 | |||
5195 | clevermous | 70 | proc kercall |
71 | jmp FS_SYSCALL_PTR |
||
72 | endp |
||
73 | |||
74 | prologue@proc equ fpo_prologue |
||
75 | epilogue@proc equ fpo_epilogue |
||
76 | |||
77 | proc start stdcall, dll_base, reason, reserved |
||
6614 | clevermous | 78 | locals |
79 | exe_base dd ? |
||
80 | exe_path_size dd ? |
||
81 | endl |
||
5195 | clevermous | 82 | ; 1. Do nothing unless called by the kernel for DLL_PROCESS_ATTACH. |
83 | cmp [reason], DLL_PROCESS_ATTACH |
||
84 | jnz .nothing |
||
6614 | clevermous | 85 | ; 2. Initialize process. |
86 | ; 2a. Validate version of the init struct. |
||
5195 | clevermous | 87 | ; If not known, say a debug message and die. |
88 | mov ebp, [reserved] |
||
6614 | clevermous | 89 | mov esi, [dll_base] |
5195 | clevermous | 90 | cmp [ebp+kernel_init_data.version], 1 |
91 | jnz .version_mismatch |
||
6614 | clevermous | 92 | ; 2b. Get the system call code. |
93 | ; Note: relocations have not been fixed yet, |
||
94 | ; so we cannot use absolute addresses, only RVAs. |
||
5195 | clevermous | 95 | mov eax, [ebp+kernel_init_data.syscall_method] |
96 | cmp eax, 0x10000 |
||
6614 | clevermous | 97 | jae .syscall_absolute |
98 | dec eax |
||
99 | mov edx, rva syscall_int40 |
||
100 | cmp eax, num_syscall_methods |
||
5195 | clevermous | 101 | jae @f |
6614 | clevermous | 102 | mov edx, [esi+eax*4+rva syscall_methods] |
5195 | clevermous | 103 | @@: |
6614 | clevermous | 104 | lea eax, [edx+esi] |
105 | .syscall_absolute: |
||
5195 | clevermous | 106 | mov FS_SYSCALL_PTR, eax |
6614 | clevermous | 107 | ; 2c. Fixup relocations so that we can use absolute offsets instead of RVAs |
108 | ; in rest of code. |
||
109 | ; Note: this uses syscalls, so this step should be done after |
||
110 | ; configuring FS_SYSCALL_PTR at step 2b. |
||
111 | push kolibri_dll |
||
112 | call fixup_pe_relocations |
||
113 | pop ecx |
||
114 | jc .die |
||
115 | ; 2d. Allocate process data. |
||
116 | mov eax, 68 |
||
117 | mov ebx, 12 |
||
118 | mov ecx, 0x1000 |
||
119 | call FS_SYSCALL_PTR |
||
120 | mov FS_PROCESS_DATA, eax |
||
121 | ; 2e. Initialize process heap. |
||
5195 | clevermous | 122 | mov eax, [ebp+kernel_init_data.exe_base] |
6614 | clevermous | 123 | mov [exe_base], eax |
5195 | clevermous | 124 | mov edx, [eax+STRIPPED_PE_HEADER.SizeOfHeapReserve] |
125 | cmp word [eax], 'MZ' |
||
126 | jnz @f |
||
127 | add eax, [eax+IMAGE_DOS_HEADER.e_lfanew] |
||
128 | mov edx, [eax+IMAGE_NT_HEADERS.OptionalHeader.SizeOfHeapReserve] |
||
129 | @@: |
||
130 | malloc_init |
||
6614 | clevermous | 131 | ; 2f. Copy rest of init struct and free memory. |
132 | ; Parse command line to argc/argv here and move arguments to the heap |
||
133 | ; in order to save memory: init struct and heap use different pages, |
||
134 | ; but typically data from init struct are far from the entire page, |
||
135 | ; so moving it to heap does not increase actual physical heap size |
||
136 | ; and allows to free init struct. |
||
137 | mov eax, [ebp+kernel_init_data.stack_base] |
||
138 | mov FS_STACK_MIN, eax |
||
139 | add eax, [ebp+kernel_init_data.stack_size] |
||
140 | mov FS_STACK_MAX, eax |
||
141 | mov eax, [ebp+kernel_init_data.exe_path] |
||
142 | @@: |
||
143 | inc eax |
||
144 | cmp byte [eax-1], 0 |
||
145 | jnz @b |
||
146 | sub eax, [ebp+kernel_init_data.exe_path] |
||
147 | mov [exe_path_size], eax |
||
148 | mov esi, [ebp+kernel_init_data.command_line] |
||
149 | xor edx, edx |
||
150 | xor edi, edi |
||
151 | call parse_cmdline |
||
152 | inc ebx ; argv[0] = exe path |
||
153 | .argc equ dll_base |
||
154 | .argv equ reason |
||
155 | .envp equ reserved |
||
156 | mov [.argc], ebx |
||
157 | sub esi, [ebp+kernel_init_data.command_line] |
||
158 | lea esi, [esi+(ebx+1)*4] |
||
159 | add esi, [exe_path_size] |
||
160 | stdcall malloc, esi |
||
161 | mov [.argv], eax |
||
162 | mov edx, eax |
||
163 | lea edi, [eax+ebx*4] |
||
164 | mov esi, [ebp+kernel_init_data.exe_path] |
||
165 | mov [edx], edi |
||
166 | add edx, 4 |
||
167 | mov ecx, [exe_path_size] |
||
168 | rep movsb |
||
169 | mov esi, [ebp+kernel_init_data.command_line] |
||
170 | call parse_cmdline |
||
171 | and dword [edx], 0 ; argv[argc] = NULL |
||
172 | and [.envp], 0 |
||
173 | mov eax, 68 |
||
174 | mov ebx, 13 |
||
175 | mov ecx, ebp |
||
176 | call FS_SYSCALL_PTR |
||
177 | ; 3. Configure modules: main EXE and possible statically linked DLLs. |
||
178 | mov esi, [exe_base] |
||
179 | mov eax, [.argv] |
||
180 | pushd [eax] |
||
181 | call fixup_pe_relocations |
||
182 | pop ecx |
||
183 | jc .die |
||
184 | ; 4. Call exe entry point. |
||
185 | mov edx, [esi+STRIPPED_PE_HEADER.AddressOfEntryPoint] |
||
186 | cmp word [esi], 'MZ' |
||
5195 | clevermous | 187 | jnz @f |
6614 | clevermous | 188 | mov ecx, [esi+IMAGE_DOS_HEADER.e_lfanew] |
189 | add ecx, esi |
||
5195 | clevermous | 190 | mov edx, [ecx+IMAGE_NT_HEADERS.OptionalHeader.AddressOfEntryPoint] |
191 | @@: |
||
6614 | clevermous | 192 | add edx, esi |
193 | add esp, fpo_localsize+4 |
||
5195 | clevermous | 194 | call edx |
195 | ; If exe entry point has returned control, die. |
||
6614 | clevermous | 196 | jmp .die |
197 | .version_mismatch: |
||
198 | lea eax, [esi + rva syscall_int40] |
||
199 | mov FS_SYSCALL_PTR, eax |
||
200 | add esi, rva msg_version_mismatch |
||
201 | call sys_msg_board_str |
||
202 | .die: |
||
203 | or eax, -1 |
||
5195 | clevermous | 204 | call FS_SYSCALL_PTR |
6614 | clevermous | 205 | .nothing: |
206 | ret |
||
207 | endp |
||
208 | |||
209 | proc sys_msg_board_str |
||
210 | push eax ebx |
||
5195 | clevermous | 211 | @@: |
6614 | clevermous | 212 | push ecx |
213 | mov cl, [ecx] |
||
5195 | clevermous | 214 | test cl, cl |
215 | jz @f |
||
6614 | clevermous | 216 | mov eax, 63 |
217 | mov ebx, 1 |
||
218 | call FS_SYSCALL_PTR |
||
219 | pop ecx |
||
220 | inc ecx |
||
5195 | clevermous | 221 | jmp @b |
222 | @@: |
||
6614 | clevermous | 223 | pop ecx ebx eax |
5195 | clevermous | 224 | ret |
225 | endp |
||
226 | |||
227 | align 4 |
||
6614 | clevermous | 228 | syscall_methods dd rva syscall_int40, rva syscall_sysenter, rva syscall_syscall |
229 | num_syscall_methods = ($ - syscall_methods) / 4 |
||
230 | |||
231 | align 4 |
||
5195 | clevermous | 232 | data export |
233 | export 'kolibri.dll' \ |
||
234 | , kercall, 'kercall' \ |
||
235 | , malloc, 'malloc' \ |
||
236 | , free, 'free' \ |
||
237 | , calloc, 'calloc' \ |
||
238 | , realloc, 'realloc' \ |
||
239 | , realloc_in_place, 'realloc_in_place' \ |
||
240 | , memalign, 'memalign' \ |
||
241 | , create_mspace, 'create_mspace' \ |
||
242 | , destroy_mspace, 'destroy_mspace' \ |
||
243 | , mspace_malloc, 'mspace_malloc' \ |
||
244 | , mspace_free, 'mspace_free' \ |
||
245 | , mspace_calloc, 'mspace_calloc' \ |
||
246 | , mspace_realloc, 'mspace_realloc' \ |
||
247 | , mspace_realloc_in_place, 'mspace_realloc_in_place' \ |
||
248 | , mspace_memalign, 'mspace_memalign' \ |
||
249 | |||
250 | end data |
||
251 | |||
6614 | clevermous | 252 | kolibri_dll db 'kolibri.dll',0 |
5195 | clevermous | 253 | |
6614 | clevermous | 254 | msg_version_mismatch db 'S : Version mismatch between kernel and kolibri.dll',13,10,0 |
255 | msg_bad_relocation1 db 'S : Bad relocation type in ',0 |
||
256 | msg_newline db 13,10,0 |
||
257 | msg_relocated1 db 'S : fixups for ',0 |
||
258 | msg_relocated2 db ' applied',13,10,0 |
||
259 | |||
5195 | clevermous | 260 | if FOOTERS |
261 | section '.data' data readable writable |
||
262 | malloc_magic dd ? |
||
263 | end if |