Rev 3805 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1906 | serge | 1 | |
2 | #include |
||
3 | #include |
||
4 | #include |
||
5 | #include |
||
6 | #include |
||
7 | #include |
||
8 | |||
9 | |||
3805 | Serge | 10 | |
1906 | serge | 11 | |
12 | #include "pe.h" |
||
13 | |||
14 | |||
15 | |||
16 | |||
17 | |||
18 | |||
19 | |||
20 | |||
21 | |||
3809 | Serge | 22 | void* create_image(void *raw); |
23 | int link_image(void *img_base, PIMAGE_IMPORT_DESCRIPTOR imp); |
||
24 | |||
1906 | serge | 25 | |
26 | extern int __appenv_size; |
||
27 | |||
28 | |||
29 | |||
30 | |||
31 | { |
||
32 | char banner[8]; |
||
33 | int version; |
||
34 | int start; |
||
35 | int iend; |
||
36 | int memsize; |
||
37 | int stacktop; |
||
38 | char *cmdline; |
||
39 | char *path; |
||
40 | int reserved; |
||
3805 | Serge | 41 | void *__idata_start; |
42 | void *__idata_end; |
||
43 | void (*main)(int argc, char **argv, char **envp); |
||
44 | }; |
||
1906 | serge | 45 | |
46 | |||
47 | { |
||
48 | struct list_head list; |
||
49 | |||
50 | |||
51 | char *img_path; |
||
52 | |||
53 | |||
54 | |||
55 | |||
56 | uint32_t end; |
||
57 | |||
58 | |||
59 | |||
60 | |||
61 | PIMAGE_SECTION_HEADER img_sec; |
||
62 | PIMAGE_EXPORT_DIRECTORY img_exp; |
||
63 | }; |
||
64 | |||
65 | |||
66 | { |
||
67 | struct list_head list; |
||
68 | char *path; |
||
69 | int path_len; |
||
70 | }dll_path_t; |
||
71 | |||
72 | |||
73 | |||
74 | |||
75 | |||
76 | |||
77 | static char libc_name[] = "libc.dll"; |
||
78 | static char libc_path[] = "/KolibriOS/lib/libc.dll"; |
||
3805 | Serge | 79 | |
1906 | serge | 80 | |
81 | { |
||
82 | if(val == 0) |
||
83 | return 0; |
||
84 | return (val & (val - 1)) == 0; |
||
85 | } |
||
86 | |||
87 | |||
88 | |||
89 | { |
||
90 | PIMAGE_DOS_HEADER dos; |
||
91 | PIMAGE_NT_HEADERS32 nt; |
||
92 | |||
93 | |||
94 | |||
95 | |||
96 | return 0; |
||
97 | |||
98 | |||
99 | return 0; |
||
100 | |||
101 | |||
102 | |||
103 | |||
104 | return 0; |
||
105 | |||
106 | |||
107 | return 0; |
||
108 | |||
109 | |||
110 | return 0; |
||
111 | |||
112 | |||
113 | return 0; |
||
114 | |||
115 | |||
116 | return 0; |
||
117 | |||
118 | |||
119 | return 0; |
||
120 | |||
121 | |||
122 | { |
||
123 | if(nt->OptionalHeader.FileAlignment != nt->OptionalHeader.SectionAlignment) |
||
124 | return 0; |
||
125 | } |
||
126 | else if(nt->OptionalHeader.SectionAlignment < nt->OptionalHeader.FileAlignment) |
||
127 | return 0; |
||
128 | |||
129 | |||
130 | !IsPowerOf2(nt->OptionalHeader.FileAlignment)) |
||
131 | return 0; |
||
132 | |||
133 | |||
134 | return 0; |
||
135 | |||
136 | |||
137 | } |
||
138 | |||
139 | |||
140 | |||
3805 | Serge | 141 | { |
1906 | serge | 142 | |
143 | |||
144 | PIMAGE_NT_HEADERS32 nt; |
||
145 | PIMAGE_EXPORT_DIRECTORY exp; |
||
146 | |||
147 | |||
3809 | Serge | 148 | dll_path_t *path; |
149 | |||
150 | |||
3805 | Serge | 151 | dll_path_t *path; |
1906 | serge | 152 | int len; |
153 | char *p; |
||
154 | |||
155 | |||
156 | { |
||
157 | char *env; |
||
158 | env = envz_get(__appenv, __appenv_size, "PATH"); |
||
159 | if( env ) |
||
160 | { |
||
161 | while( *env ) |
||
162 | { |
||
163 | p = env; |
||
164 | while(*p) |
||
165 | { |
||
166 | if( *p == 0x0D) |
||
167 | break; |
||
168 | else if( *p == 0x0A) |
||
169 | break; |
||
170 | else if( *p == ':') |
||
171 | break; |
||
172 | p++; |
||
173 | }; |
||
174 | len = p-env; |
||
175 | if(len) |
||
176 | { |
||
177 | char *p1; |
||
178 | |||
179 | |||
180 | memcpy(p1, env, len); |
||
181 | p1[len]=0; |
||
182 | |||
183 | |||
184 | INIT_LIST_HEAD(&path->list); |
||
185 | path->path = p1; |
||
186 | path->path_len = len; |
||
187 | DBG("add libraries path %s\n", path->path); |
||
188 | list_add_tail(&path->list, &path_list); |
||
189 | }; |
||
190 | if(*p == ':') |
||
191 | { |
||
192 | env = p+1; |
||
193 | continue; |
||
194 | } |
||
195 | else break; |
||
196 | }; |
||
197 | }; |
||
198 | }; |
||
199 | |||
200 | |||
201 | |||
202 | |||
203 | p = (char*)malloc(len+1); |
||
204 | memcpy(p, header->path, len); |
||
205 | p[len]=0; |
||
206 | |||
207 | |||
208 | INIT_LIST_HEAD(&path->list); |
||
209 | path->path = p; |
||
210 | path->path_len = len; |
||
211 | DBG("add libraries path %s\n", path->path); |
||
212 | list_add_tail(&path->list, &path_list); |
||
213 | |||
214 | |||
3809 | Serge | 215 | |
1906 | serge | 216 | |
217 | INIT_LIST_HEAD(&path->list); |
||
218 | path->path = "/kolibrios/lib/"; |
||
3809 | Serge | 219 | path->path_len = 15; /* FIXME */ |
220 | DBG("add libraries path %s\n", path->path); |
||
1906 | serge | 221 | list_add_tail(&path->list, &path_list); |
222 | |||
223 | |||
224 | |||
225 | |||
226 | libc_dll.img_path = libc_path; |
||
227 | |||
228 | |||
229 | |||
230 | |||
231 | nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); |
||
232 | exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, libc_image, |
||
233 | nt->OptionalHeader.DataDirectory[0].VirtualAddress); |
||
234 | |||
235 | |||
236 | libc_dll.end = MakePtr(uint32_t,libc_image, nt->OptionalHeader.SizeOfImage); |
||
237 | |||
238 | |||
239 | libc_dll.img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32)); |
||
240 | libc_dll.img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY,libc_image, |
||
241 | nt->OptionalHeader.DataDirectory[0].VirtualAddress); |
||
242 | |||
243 | |||
244 | |||
245 | |||
246 | { |
||
247 | module_t* mod = &libc_dll; |
||
3805 | Serge | 248 | |
1906 | serge | 249 | |
3805 | Serge | 250 | { |
1906 | serge | 251 | if( !strncmp(name, mod->img_name, 16)) |
252 | return mod; |
||
253 | mod = (module_t*)mod->list.next; |
||
3805 | Serge | 254 | }while(mod != &libc_dll); |
255 | |||
1906 | serge | 256 | |
257 | }; |
||
258 | |||
259 | |||
260 | { |
||
261 | __asm__ __volatile__ ( |
||
262 | "shrl $2, %%ecx \n\t" |
||
263 | "rep movsl" |
||
264 | : |
||
265 | :"c"(len),"S"(src),"D"(dst) |
||
266 | :"cc"); |
||
267 | __asm__ __volatile__ ( |
||
268 | "" |
||
269 | :::"ecx","esi","edi"); |
||
270 | }; |
||
271 | |||
272 | |||
273 | |||
3809 | Serge | 274 | { |
1906 | serge | 275 | PIMAGE_DOS_HEADER dos; |
276 | PIMAGE_NT_HEADERS32 nt; |
||
277 | PIMAGE_SECTION_HEADER img_sec; |
||
278 | |||
279 | |||
280 | uint32_t sec_align; |
||
281 | int i; |
||
282 | |||
283 | |||
284 | nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); |
||
285 | |||
286 | |||
287 | |||
288 | |||
289 | return 0; |
||
290 | |||
291 | |||
292 | |||
293 | |||
294 | |||
295 | |||
296 | |||
297 | |||
298 | { |
||
299 | void *src_ptr; |
||
300 | void *dest_ptr; |
||
301 | size_t sec_size; |
||
302 | |||
303 | |||
304 | { |
||
305 | src_ptr = MakePtr(void*, raw, img_sec->PointerToRawData); |
||
306 | dest_ptr = MakePtr(void*, img_base, img_sec->VirtualAddress); |
||
307 | sec_copy(dest_ptr, src_ptr, img_sec->SizeOfRawData); |
||
308 | }; |
||
309 | |||
310 | |||
311 | }; |
||
312 | |||
313 | |||
314 | { |
||
315 | PIMAGE_BASE_RELOCATION reloc; |
||
316 | |||
317 | |||
318 | |||
319 | |||
320 | nt->OptionalHeader.DataDirectory[5].VirtualAddress); |
||
321 | |||
322 | |||
323 | { |
||
324 | uint32_t cnt; |
||
325 | uint16_t *entry; |
||
326 | uint16_t reltype; |
||
327 | uint32_t offs; |
||
328 | |||
329 | |||
330 | entry = MakePtr( uint16_t*, reloc, sizeof(*reloc) ); |
||
331 | |||
332 | |||
333 | { |
||
334 | uint16_t *p16; |
||
335 | uint32_t *p32; |
||
336 | |||
337 | |||
338 | offs = (*entry & 0x0FFF) + reloc->VirtualAddress; |
||
339 | switch(reltype) |
||
340 | { |
||
341 | case 1: |
||
342 | p16 = MakePtr(uint16_t*, img_base, offs); |
||
343 | *p16+= (uint16_t)(delta>>16); |
||
344 | break; |
||
345 | case 2: |
||
346 | p16 = MakePtr(uint16_t*, img_base, offs); |
||
347 | *p16+= (uint16_t)delta; |
||
348 | break; |
||
349 | case 3: |
||
350 | p32 = MakePtr(uint32_t*, img_base, offs); |
||
351 | *p32+= delta; |
||
352 | } |
||
353 | entry++; |
||
354 | } |
||
355 | reloc = MakePtr(PIMAGE_BASE_RELOCATION, reloc,reloc->SizeOfBlock); |
||
356 | } |
||
357 | }; |
||
358 | return img_base; |
||
359 | }; |
||
360 | |||
361 | |||
3809 | Serge | 362 | //static loader_recursion; |
363 | |||
3805 | Serge | 364 | |
3809 | Serge | 365 | { |
1906 | serge | 366 | static jmp_buf loader_env; |
367 | static recursion = -1; |
||
368 | int warn = 0; |
||
369 | |||
370 | |||
371 | if( !recursion ) |
||
372 | { |
||
373 | if( unlikely(setjmp(loader_env) != 0)) |
||
374 | { |
||
375 | recursion = -1; |
||
376 | return 0; |
||
377 | }; |
||
378 | }; |
||
379 | |||
380 | |||
3805 | Serge | 381 | { |
382 | PIMAGE_DOS_HEADER expdos; |
||
383 | PIMAGE_NT_HEADERS32 expnt; |
||
384 | PIMAGE_EXPORT_DIRECTORY exp; |
||
385 | PIMAGE_THUNK_DATA32 thunk; |
||
386 | |||
387 | |||
388 | char *libname; |
||
389 | uint32_t *exp_functions; |
||
390 | uint16_t *exp_ordinals; |
||
391 | char **exp_names; |
||
392 | |||
393 | |||
394 | |||
395 | |||
3809 | Serge | 396 | |
3805 | Serge | 397 | |
398 | |||
399 | |||
400 | if(unlikely(api == NULL)) |
||
401 | { |
||
402 | printf("library %s not found\n", libname); |
||
403 | longjmp(loader_env, 1); |
||
404 | } |
||
405 | |||
406 | |||
3809 | Serge | 407 | |
3805 | Serge | 408 | |
409 | { |
||
410 | thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->OriginalFirstThunk, img_base); |
||
3809 | Serge | 411 | } |
3805 | Serge | 412 | else |
413 | { |
||
414 | thunk = MakePtr(PIMAGE_THUNK_DATA32,imp->FirstThunk, img_base); |
||
3809 | Serge | 415 | }; |
3805 | Serge | 416 | |
417 | |||
418 | |||
419 | |||
420 | exp_ordinals = MakePtr(uint16_t*, exp->AddressOfNameOrdinals,api->start); |
||
421 | exp_names = MakePtr(char**, exp->AddressOfNames,api->start); |
||
422 | |||
423 | |||
424 | { |
||
425 | PIMAGE_IMPORT_BY_NAME imp_name; |
||
426 | |||
427 | |||
428 | { |
||
429 | // ordinal = (*func_list) & 0x7fffffff; |
||
430 | // *ImportAddressList = LdrGetExportByOrdinal(ImportedModule->DllBase, Ordinal); |
||
431 | // if ((*ImportAddressList) == NULL) |
||
432 | // { |
||
433 | // DPRINT1("Failed to import #%ld from %wZ\n", Ordinal, &ImportedModule->FullDllName); |
||
434 | // RtlpRaiseImportNotFound(NULL, Ordinal, &ImportedModule->FullDllName); |
||
435 | // return STATUS_ENTRYPOINT_NOT_FOUND; |
||
436 | // } |
||
437 | } |
||
438 | else |
||
439 | { |
||
440 | char *export_name; |
||
441 | uint16_t ordinal; |
||
442 | void *function; |
||
443 | uint32_t minn; |
||
444 | uint32_t maxn; |
||
445 | |||
446 | |||
447 | thunk->u1.AddressOfData, img_base); |
||
3809 | Serge | 448 | *iat = NULL; |
3805 | Serge | 449 | |
450 | |||
451 | |||
452 | |||
453 | { |
||
454 | export_name = MakePtr(char*,exp_names[imp_name->Hint], |
||
455 | api->start); |
||
456 | if(strcmp(imp_name->Name, export_name) == 0) |
||
457 | { |
||
458 | ordinal = exp_ordinals[imp_name->Hint]; |
||
459 | function = MakePtr(void*,exp_functions[ordinal], api->start); |
||
460 | if((uint32_t)function >= (uint32_t)exp) |
||
461 | { |
||
462 | printf("forward %s\n", function); |
||
463 | warn=1; |
||
464 | } |
||
465 | else |
||
466 | { |
||
467 | DBG(" \t\tat %x\n", function); |
||
468 | *iat = function; |
||
469 | }; |
||
470 | thunk++; // Advance to next thunk |
||
471 | iat++; |
||
472 | continue; |
||
473 | }; |
||
474 | }; |
||
475 | |||
476 | |||
477 | |||
478 | maxn = exp->NumberOfNames - 1; |
||
479 | while (minn <= maxn) |
||
480 | { |
||
481 | int mid; |
||
482 | int res; |
||
483 | |||
484 | |||
485 | |||
486 | |||
487 | |||
488 | |||
489 | if (res == 0) |
||
490 | { |
||
491 | ordinal = exp_ordinals[mid]; |
||
492 | function = MakePtr(void*,exp_functions[ordinal], api->start); |
||
493 | |||
494 | |||
495 | { |
||
496 | printf("forward %s\n", function); |
||
3809 | Serge | 497 | warn=1; |
3805 | Serge | 498 | } |
499 | else |
||
500 | { |
||
501 | DBG(" \t\tat %x\n", function); |
||
502 | *iat = function; |
||
503 | }; |
||
504 | break; |
||
505 | } |
||
506 | else if (minn == maxn) |
||
507 | { |
||
508 | printf(" unresolved %s\n",imp_name->Name); |
||
509 | warn=1; |
||
510 | break; |
||
511 | } |
||
512 | else if (res > 0) |
||
513 | { |
||
514 | maxn = mid - 1; |
||
515 | } |
||
516 | else |
||
517 | { |
||
518 | minn = mid + 1; |
||
519 | } |
||
520 | }; |
||
521 | }; |
||
522 | thunk++; // Advance to next thunk |
||
523 | iat++; |
||
524 | } |
||
525 | imp++; // advance to next IMAGE_IMPORT_DESCRIPTOR |
||
526 | }; |
||
527 | |||
528 | |||
3809 | Serge | 529 | |
530 | |||
3805 | Serge | 531 | return 1; |
532 | else |
||
533 | return 0; |
||
534 | } |
||
535 | |||
536 | |||
3809 | Serge | 537 | { |
538 | struct app_hdr *header = NULL; |
||
539 | PIMAGE_IMPORT_DESCRIPTOR imp; |
||
540 | |||
3805 | Serge | 541 | |
3809 | Serge | 542 | |
3805 | Serge | 543 | |
3809 | Serge | 544 | |
545 | |||
546 | |||
547 | |||
548 | |||
1906 | serge | 549 | { |
550 | PIMAGE_DOS_HEADER dos; |
||
551 | PIMAGE_NT_HEADERS32 nt; |
||
552 | |||
553 | |||
554 | nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); |
||
555 | |||
556 | |||
557 | }; |
||
2040 | serge | 558 | |
1906 | serge | 559 | |
560 | |||
2040 | serge | 561 | { |
562 | |||
563 | |||
564 | PIMAGE_NT_HEADERS32 expnt; |
||
565 | PIMAGE_EXPORT_DIRECTORY exp; |
||
566 | |||
567 | |||
568 | uint16_t *exp_ordinals; |
||
569 | char **exp_names; |
||
570 | |||
571 | |||
572 | char *export_name; |
||
573 | uint16_t ordinal; |
||
574 | void *function=NULL; |
||
575 | |||
576 | |||
577 | |||
578 | |||
579 | exp_ordinals = MakePtr(uint16_t*, exp->AddressOfNameOrdinals,module->start); |
||
580 | exp_names = MakePtr(char**, exp->AddressOfNames,module->start); |
||
581 | |||
582 | |||
583 | maxn = exp->NumberOfNames - 1; |
||
584 | while (minn <= maxn) |
||
585 | { |
||
586 | int mid; |
||
587 | int res; |
||
588 | |||
589 | |||
590 | |||
591 | |||
592 | |||
593 | |||
594 | if (res == 0) |
||
595 | { |
||
596 | ordinal = exp_ordinals[mid]; |
||
597 | function = MakePtr(void*,exp_functions[ordinal], module->start); |
||
598 | |||
599 | |||
600 | { |
||
601 | printf("forward %s\n", function); |
||
602 | } |
||
603 | else |
||
604 | { |
||
605 | DBG(" \t\tat %x\n", function); |
||
606 | }; |
||
607 | break; |
||
608 | } |
||
609 | else if (minn == maxn) |
||
610 | { |
||
611 | DBG(" unresolved %s\n",proc_name); |
||
612 | break; |
||
613 | } |
||
614 | else if (res > 0) |
||
615 | { |
||
616 | maxn = mid - 1; |
||
617 | } |
||
618 | else |
||
619 | { |
||
620 | minn = mid + 1; |
||
621 | } |
||
622 | }; |
||
623 | |||
624 | |||
625 | }; |
||
626 | |||
627 | |||
628 | |||
1906 | serge | 629 | { |
630 | dll_path_t *dllpath; |
||
3809 | Serge | 631 | |
1906 | serge | 632 | |
3809 | Serge | 633 | int len; |
634 | |||
635 | |||
1906 | serge | 636 | |
637 | |||
638 | { |
||
639 | PIMAGE_DOS_HEADER dos; |
||
640 | PIMAGE_NT_HEADERS32 nt; |
||
641 | PIMAGE_EXPORT_DIRECTORY exp; |
||
642 | |||
643 | |||
644 | ufile_t uf; |
||
3809 | Serge | 645 | void *raw_img; |
1906 | serge | 646 | size_t raw_size; |
647 | void *img_base; |
||
648 | |||
649 | |||
650 | memcpy(path, dllpath->path, dllpath->path_len); |
||
651 | |||
652 | |||
653 | path[len+dllpath->path_len]=0; |
||
654 | |||
655 | |||
3809 | Serge | 656 | |
657 | |||
658 | raw_img = uf.data; |
||
659 | raw_size = uf.size; |
||
660 | |||
661 | |||
1906 | serge | 662 | continue; |
663 | |||
664 | |||
3809 | Serge | 665 | |
1906 | serge | 666 | { |
667 | printf("invalide module %s\n", path); |
||
668 | user_free(raw_img); |
||
669 | continue; |
||
670 | }; |
||
671 | |||
672 | |||
673 | user_free(raw_img); |
||
674 | |||
675 | |||
676 | { |
||
677 | printf("cannot create image %s\n",path); |
||
678 | continue; |
||
679 | }; |
||
680 | |||
681 | |||
682 | |||
683 | |||
684 | { |
||
685 | printf("%s epic fail: no enough memory\n",__FUNCTION__); |
||
686 | user_free(img_base); |
||
687 | return NULL; |
||
3809 | Serge | 688 | } |
1906 | serge | 689 | |
690 | |||
691 | |||
692 | |||
693 | module->img_path = strdup(path); |
||
694 | module->start = img_base; |
||
695 | module->entry = get_entry_point(img_base); |
||
696 | module->refcount = 1; |
||
697 | |||
698 | |||
699 | nt = MakePtr( PIMAGE_NT_HEADERS32, dos, dos->e_lfanew); |
||
700 | exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base, |
||
701 | nt->OptionalHeader.DataDirectory[0].VirtualAddress); |
||
702 | |||
703 | |||
704 | |||
705 | |||
706 | module->img_sec = MakePtr(PIMAGE_SECTION_HEADER,nt, sizeof(IMAGE_NT_HEADERS32)); |
||
707 | module->img_exp = MakePtr(PIMAGE_EXPORT_DIRECTORY, img_base, |
||
708 | nt->OptionalHeader.DataDirectory[0].VirtualAddress); |
||
709 | |||
710 | |||
3805 | Serge | 711 | |
1906 | serge | 712 | |
3809 | Serge | 713 | { |
2040 | serge | 714 | PIMAGE_IMPORT_DESCRIPTOR imp; |
3809 | Serge | 715 | int (*dll_startup)(module_t *mod, uint32_t reason); |
2040 | serge | 716 | |
717 | |||
3809 | Serge | 718 | nt->OptionalHeader.DataDirectory[1].VirtualAddress); |
719 | |||
720 | |||
721 | return NULL; |
||
722 | |||
723 | |||
2040 | serge | 724 | if( dll_startup ) |
725 | if( 0 == dll_startup(module, 1)) |
||
726 | return NULL; |
||
3809 | Serge | 727 | }; |
2040 | serge | 728 | return module; |
3809 | Serge | 729 | }; |
1906 | serge | 730 | return NULL; |
731 | };=>=>>>>>>>=>> |
||
732 |