Subversion Repositories Kolibri OS

Rev

Rev 6536 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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