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