Subversion Repositories Kolibri OS

Rev

Rev 1906 | 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
 
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 %s\n",imp_name->Name);
1907 serge 526
                            warn=1;
1906 serge 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