[docs] Replace cyrillic 'с' with latin 'c' in register names
[kolibrios.git] / programs / emulator / kwine / kwine.asm
blobe85ed39be27a0be2e26d798bf49b83800f0681d4
1 ; ------------------------------------------------------------- ;
2 ; KWINE is a fork of program PELoad written by 0CodErr
3 ; author of fork - rgimad
4 ; ------------------------------------------------------------- ;
5 ORG 0
6 BITS 32
7 ; ------------------------------------------------------------- ;
8 PATH_SIZE equ 4096
9 PARAMS_SIZE equ 4096
10 STACK_SIZE equ 4096
11 END_ equ IMAGE_BASE - (PATH_SIZE + PARAMS_SIZE + STACK_SIZE)
12 ; ------------------------------------------------------------- ;
13 IMAGE_BASE equ 400000H
14 ; ------------------------------------------------------------- ;
15 MENUET01 db 'MENUET01'
16 version dd 1
17 program.start dd start_
18 program.end dd END_
19 program.memory dd END_ + PATH_SIZE + PARAMS_SIZE + STACK_SIZE
20 program.stack dd END_ + PATH_SIZE + PARAMS_SIZE + STACK_SIZE
21 program.params dd END_ + PATH_SIZE
22 program.path dd END_
23 ; ------------------------------------------------------------- ;
24 load.library:
25 mov eax, 68
26 mov ebx, 19
27 mov ecx, [esp + 4]
28 int 64
29 ret 4
30 ; ------------------------------------------------------------- ;
31 getprocaddress:
32 mov edx, [esp + 8]
33 xor eax, eax
34 test edx, edx
35 jz .end
36 .next:
37 xor eax, eax
38 cmp [edx], dword 0
39 jz .end
40 mov esi, [edx]
41 mov edi, [esp + 4]
42 .next_:
43 lodsb
44 scasb
45 jne .fail
46 or al, al
47 jnz .next_
48 jmp .ok
49 .fail:
50 add edx, 8
51 jmp .next
52 .ok:
53 mov eax, [edx + 4]
54 .end:
55 ret 8
56 ; ------------------------------------------------------------- ;
57 realloc.app.mem:
58 mov eax, 64
59 mov ebx, 1
60 mov ecx, [esp + 4]
61 int 64
62 ret 4
63 ; ------------------------------------------------------------- ;
64 set.current.directory:
65 mov eax, 30
66 mov ebx, 1
67 mov ecx, [esp + 4]
68 int 64
69 ret 4
70 ; ------------------------------------------------------------- ;
71 %if 0 ; comment
72 int2str:
73 %define number [esp + 8 + 8 * 4]
74 %define buffer [esp + 4 + 8 * 4]
75 pushad
76 mov edi, buffer
77 mov eax, " " ; 4 spaces
78 stosd
79 stosd
80 stosw
81 xor al, al
82 stosb
83 dec edi
84 dec edi
85 mov ecx, 10
86 mov eax, number
87 .next:
88 xor edx, edx
89 div ecx ; ecx = 10
90 add edx, 48 ; edx = (eax MOD ecx) + 48
91 mov [edi], dl
92 dec edi
93 test eax, eax
94 jnz .next
95 popad
96 ret 8
97 %undef number
98 %undef buffer
99 %endif ; endcomment
100 ; ------------------------------------------------------------- ;
101 ; test_file_path db "/hd3/1/mntest.exe",0
102 ; complex
103 ; address
104 ; data
105 ; hello
106 ; numbers +-
107 ; proc
108 ; sptrim
109 ; se
110 ; clear
111 ; locals +-
112 ; tokenise -
113 ; mntest
114 file_path dd 0
115 lib_name dd 0
116 lib dd 0
117 func dd 0
118 func_name dd 0
119 ; ------------------------------------------------------------- ;
120 sz_pe_load db "KWINE",0
121 ; ------------------------------------------------------------- ;
122 con_init dd 0
123 con_write_asciiz dd 0
124 con_exit dd 0
125 console dd 0
126 sz_con_init db "con_init",0
127 sz_con_write_asciiz db "con_write_asciiz",0
128 sz_con_exit db "con_exit",0
129 sz_console db "/sys/lib/console.obj",0
130 ; ------------------------------------------------------------- ;
131 MZ dw 0
132 PE dw 0
133 lfa_new dd 0
134 NumberOfSections dd 0
135 SizeOfOptionalHeader dd 0
136 EntryPoint dd 0
137 SizeOfImage dd 0
138 SizeOfHeaders dd 0
139 DataDirectories dd 0
140 SectionsTable dd 0
141 Import dd 0
142 ; ------------------------------------------------------------- ;
143 ERROR_MESSAGE dd 0
144 err_params db "Parameters error",0
145 err_file_path db "No input file path",0
146 err_read_file db "Read file error",0
147 err_mz_not_found db "No DOS signature found",0
148 err_pe_not_found db "No PE signature found",0
149 err_load_library db "Error load library: ",0
150 err_func_not_found db "Not found function: ",0
152 ; ------------------------------------------------------------- ;
153 %if 0 ; comment
154 msg_buffer resb 256
155 sz_new_line db 10,0
156 sz_space db " ",0
157 sz_space_colon_space db " : ",0
158 %endif ; endcomment
159 sz_empty db "",0
162 start_:
163 ; ------------------------------------------------------------- ;
164 ; find params and file path
165 ; mov eax, test_file_path
166 mov eax, [program.params]
167 cmp [eax], byte 34 ; quote
168 jne .no_quote
169 inc eax
170 mov edi, eax
171 .find_quote_or_zero:
172 cmp [edi], byte 0
173 je .found
174 cmp [edi], byte 34 ; quote
175 je .found
176 inc edi
177 jmp .find_quote_or_zero
178 .no_quote:
179 mov edi, eax
180 .find_space_or_zero:
181 cmp [edi], byte 0
182 je .found
183 cmp [edi], byte 32 ; space
184 je .found
185 inc edi
186 jmp .find_space_or_zero
187 .found:
188 mov [edi], byte 0
189 mov [file_path], eax
190 ; check file path
191 mov eax, [file_path]
192 mov al, [eax]
193 test al, al
194 jne file_path_ok
195 mov [ERROR_MESSAGE], dword err_file_path
196 jmp ERROR
197 file_path_ok:
198 ; check MZ signature (IMAGE_DOS_HEADER.e_magic)
199 push dword [file_path];filepath
200 dec esp
201 mov [esp], byte 0
202 push dword MZ;buffer
203 push dword 2;count
204 push dword 0
205 push dword 0;position
206 push dword 0
207 mov ebx, esp
208 mov eax, 70
209 int 64
210 test eax, eax
211 je read_ok
212 mov [ERROR_MESSAGE], dword err_read_file
213 jmp ERROR
214 read_ok:
215 cmp word [MZ], "MZ"
216 je MZ_exists
217 mov [ERROR_MESSAGE], dword err_mz_not_found
218 jmp ERROR
219 MZ_exists:
220 ; get lfa_new (IMAGE_DOS_HEADER.e_lfanew)
221 push dword [file_path];filepath
222 dec esp
223 mov [esp], byte 0
224 push dword lfa_new;buffer
225 push dword 4;count
226 push dword 0
227 push dword 60;position
228 push dword 0
229 mov ebx, esp
230 mov eax, 70
231 int 64
232 ; check PE signature (IMAGE_OPTIONAL_HEADER.Magic)
233 push dword [file_path];filepath
234 dec esp
235 mov [esp], byte 0
236 push dword PE;buffer
237 push dword 2;count
238 push dword 0
239 push dword [lfa_new];position
240 push dword 0
241 mov ebx, esp
242 mov eax, 70
243 int 64
244 cmp word [PE], "PE"
245 je PE_exists
246 mov [ERROR_MESSAGE], dword err_pe_not_found
247 jmp ERROR
248 PE_exists:
249 ; get size of headers (IMAGE_OPTIONAL_HEADER.SizeOfHeaders)
250 push dword [file_path];filepath
251 dec esp
252 mov [esp], byte 0
253 push dword SizeOfHeaders;buffer
254 push dword 4;count
255 push dword 0
256 mov eax, [lfa_new]
257 add eax, 84
258 push eax;position
259 push dword 0
260 mov ebx, esp
261 mov eax, 70
262 int 64
263 ; resize app memory and load headers
264 mov eax, IMAGE_BASE
265 add eax, [SizeOfHeaders]
266 push eax
267 call realloc.app.mem
269 push dword [file_path];filepath
270 dec esp
271 mov [esp], byte 0
272 push dword IMAGE_BASE;buffer
273 push dword [SizeOfHeaders];count
274 push dword 0
275 push dword 0;position
276 push dword 0
277 mov ebx, esp
278 mov eax, 70
279 int 64
281 add esp, (25 * 5) ; restore our stack top
283 mov edx, [lfa_new]
284 ; get SizeOfImage (IMAGE_OPTIONAL_HEADER.SizeOfImage)
285 mov eax, [IMAGE_BASE + edx + 80]
286 mov [SizeOfImage], eax
287 ; get EntryPoint (IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint)
288 mov eax, [IMAGE_BASE + edx + 40]
289 mov [EntryPoint], eax
290 ; get DataDirectories (IMAGE_OPTIONAL_HEADER.DataDirectory)
291 lea eax, [edx + 120]
292 mov [DataDirectories], eax
293 ; get SizeOfOptionalHeader (IMAGE_FILE_HEADER.SizeOfOptionalHeader)
294 movzx eax, word [IMAGE_BASE + edx + 20]
295 mov [SizeOfOptionalHeader], ax
296 ; get SectionsTable
297 lea eax, [edx + 24]
298 add ax, [SizeOfOptionalHeader]
299 mov [SectionsTable], eax
300 ; get Import
301 mov eax, IMAGE_BASE
302 add eax, [DataDirectories]
303 add eax, 1 * 8
304 mov eax, [eax]
305 mov [Import], eax
306 ; get NumberOfSections (IMAGE_FILE_HEADER.NumberOfSections)
307 movzx eax, word [IMAGE_BASE + edx + 6]
308 mov [NumberOfSections], eax
309 ; resize app memory and load sections to their virtual address
310 mov eax, IMAGE_BASE
311 add eax, [SizeOfImage]
312 push eax
313 call realloc.app.mem
315 mov ecx, [NumberOfSections]
316 next_section:
317 lea eax, [ecx - 1]
318 lea eax, [eax * 4 + eax]
319 lea eax, [eax * 8]
320 add eax, IMAGE_BASE
321 add eax, [SectionsTable]
323 push dword [file_path] ; filepath
324 dec esp
325 mov [esp], byte 0
326 mov edx, [eax + 12]
327 add edx, IMAGE_BASE
328 push edx ; buffer (IMAGE_SECTION_HEADER.VirtualAddress)
329 push dword [eax + 16] ; count (IMAGE_SECTION_HEADER.SizeOfRawData)
330 push dword 0
331 push dword [eax + 20] ; position (IMAGE_SECTION_HEADER.PointerToRawData)
332 push dword 0
333 mov ebx, esp
334 mov eax, 70
335 int 64
337 dec ecx
338 jnz next_section
340 mov eax, [NumberOfSections]
341 lea eax, [eax * 4 + eax]
342 lea eax, [eax * 4 + eax]
343 add esp, eax ; restore our stack top
348 ; ==========================================================
349 %if 0 ; comment
350 push sz_console
351 call load.library
352 ; mov [console], eax
353 mov ecx, eax
354 mov ebx, getprocaddress
355 push ecx
356 push sz_con_init
357 call ebx
358 mov [con_init], eax
359 push ecx
360 push sz_con_write_asciiz
361 call ebx
362 mov [con_write_asciiz], eax
363 push ecx
364 push sz_con_exit
365 call ebx
366 mov [con_exit], eax
367 push sz_pe_load
368 push -1
369 push -1
370 push -1
371 push -1
372 call [con_init]
374 mov ecx, [NumberOfSections]
375 next_sect:
376 lea eax, [ecx - 1]
377 lea eax, [eax * 4 + eax]
378 lea eax, [eax * 8]
379 add eax, IMAGE_BASE
380 add eax, [SectionsTable]
381 push eax
383 push eax
384 call [con_write_asciiz]
385 push sz_space_colon_space
386 call [con_write_asciiz]
389 pop eax
390 add eax, 20
391 mov eax, [eax]
392 push eax
393 push msg_buffer
394 call int2str
395 push msg_buffer
396 call [con_write_asciiz]
398 push sz_new_line
399 call [con_write_asciiz]
402 dec ecx
403 jnz next_sect
404 %endif ; endcomment
405 ; ==============================================
406 ; program.path = program.path_without_filename & "lib/"
407 mov edi, [program.path]
408 xor al, al
409 xor ecx, ecx
410 dec ecx
411 repne scasb
413 mov al, "/"
414 repne scasb
416 inc edi
417 inc edi
418 mov eax, "lib/"
419 stosd
421 mov [lib_name], edi
423 xor ecx, ecx
424 next_descriptor:
425 lea eax, [ecx * 4 + ecx]
426 lea eax, [eax * 4]
427 add eax, IMAGE_BASE
428 add eax, [Import]
429 mov edx, [eax + 12]
430 add edx, IMAGE_BASE
432 %if 0 ; comment
433 pushad
434 push edx
435 call [con_write_asciiz]
436 push sz_new_line
437 call [con_write_asciiz]
438 popad
439 %endif ; endcomment
441 pushad
442 ; concatenate (program.path_without_filename & "lib/") & lib_name
443 mov esi, edx
444 mov edi, [lib_name]
445 .copy_lib_name:
446 lodsb
447 stosb
448 test al, al
449 jnz .copy_lib_name
450 ; try to load library
451 push dword [program.path]
452 call load.library
453 test eax, eax
454 jnz .lib_loaded
455 ; concatenate "Error load library: " & lib_name
456 sub edi, [lib_name]
457 mov esi, edi
458 mov edi, err_load_library
459 xor al, al
460 xor ecx, ecx
461 dec ecx
462 repne scasb
463 dec edi
464 mov ecx, esi
465 mov esi, edx
466 rep movsb
468 popad
469 mov [ERROR_MESSAGE], dword err_load_library
470 jmp ERROR
471 .lib_loaded:
472 mov [lib], eax
473 popad
474 xor ebx, ebx
475 next_function:
476 mov edx, [eax + 16]
477 lea esi, [edx + ebx * 4 + IMAGE_BASE]
478 mov [func], esi
479 mov edx, [esi]
480 test edx, edx
481 jz .done
482 inc edx
483 inc edx
484 add edx, IMAGE_BASE
486 %if 0 ; comment
487 pushad
488 push edx
489 call [con_write_asciiz]
490 push sz_new_line
491 call [con_write_asciiz]
492 popad
493 %endif ; endcomment
495 pushad
496 mov [func_name], edx
497 ; look for address of imported function
498 push dword [lib]
499 push edx
500 call getprocaddress
501 test eax, eax
502 jnz .func_found
503 popad
504 ; concatenate "Not found function: " & name of function
505 mov edi, err_func_not_found
506 xor al, al
507 xor ecx, ecx
508 dec ecx
509 repne scasb
510 dec edi
511 mov esi, edx
512 .copy_func_name:
513 lodsb
514 stosb
515 test al, al
516 jnz .copy_func_name
518 dec edi
519 mov eax, " in "
520 stosd
522 mov esi, [lib_name]
523 .copy_lib_name:
524 lodsb
525 stosb
526 test al, al
527 jnz .copy_lib_name
529 mov [ERROR_MESSAGE], dword err_func_not_found
530 jmp ERROR
531 .func_found:
532 mov edx, [func]
533 mov [edx], eax
534 popad
535 inc ebx
536 jmp next_function
537 .done:
539 inc ecx
540 lea eax, [ecx * 4 + ecx]
541 lea eax, [eax * 4]
542 add eax, IMAGE_BASE
543 add eax, [Import]
544 mov eax, [eax + 12]
545 cmp eax, dword 0
546 jnz next_descriptor
549 ; set.current.directory
550 mov edi, [file_path]
551 xor al, al
552 xor ecx, ecx
553 dec ecx
554 repne scasb
556 mov al, "/"
557 repne scasb
559 mov [edi + 1], byte 0
560 push dword [file_path]
561 call set.current.directory
562 mov [edi + 1], byte "/" ; restore full file_path
564 ; ---------------------- ;
565 ; call load_console_lib ;
566 ; ---------------------- ;
568 ; go to EntryPoint
569 mov eax, [EntryPoint]
570 add eax, IMAGE_BASE
571 jmp eax
574 ; push dword [EntryPoint]
575 ; push msg_buffer
576 ; call int2str
577 ; push msg_buffer
578 ; call [con_write_asciiz]
580 %if 0 ; comment
581 push 0
582 call [con_exit]
583 %endif ; endcomment
585 %if 0 ; comment
586 ; dump ---------------------------------------
587 push dword dump_path;filepath
588 dec esp
589 mov [esp], byte 0
590 push dword 0 ;buffer
591 mov eax, IMAGE_BASE
592 add eax, [SizeOfImage]
593 push eax;count
594 push dword 0
595 push dword 0;position
596 push dword 2
597 mov ebx, esp
598 mov eax, 70
599 int 64
602 xor eax, eax
603 dec eax
604 int 64
606 dump_path db "/hd3/1/dump.bin",0
607 %endif ; endcomment
608 ; ==========================================================
611 ERROR:
613 push sz_console
614 call load.library
615 ; mov [console], eax
616 mov ecx, eax
617 mov ebx, getprocaddress
618 push ecx
619 push sz_con_init
620 call ebx
621 mov [con_init], eax
622 push ecx
623 push sz_con_write_asciiz
624 call ebx
625 mov [con_write_asciiz], eax
626 push ecx
627 push sz_con_exit
628 call ebx
629 mov [con_exit], eax
631 push sz_pe_load
632 push -1
633 push -1
634 push -1
635 push -1
636 call [con_init]
637 push dword [ERROR_MESSAGE]
638 call [con_write_asciiz]
639 push 0
640 call [con_exit]
642 xor eax, eax
643 dec eax
644 int 64
648 ; load_console_lib:
649 ; push sz_console
650 ; call load.library
652 ; push eax
653 ; push sz_con_init
654 ; call getprocaddress
655 ; mov [con_init], eax
657 ; push sz_empty
658 ; push -1
659 ; push -1
660 ; push -1
661 ; push -1
662 ; call [con_init]
664 ; ret