1
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "pe.h"
6
7
8 #ifndef SEEK_SET
9 #define SEEK_SET 0
10 #define SEEK_CUR 1
11 #define SEEK_END 2
12 #endif
13
14
15
new_PEFILE(PEFILE * self,FILE * fp)16 int new_PEFILE(PEFILE *self, FILE *fp)
17 {
18 int r = 0;
19 size_t optsz;
20 long rec = ftell(fp);
21 long m_off;
22
23 if (!self) return -1;
24 new_MZFILE(&self->super, fp);
25 self->super.open_resdir = pe_open_resdir;
26 m_off = mz_check_ne(&self->super);
27
28 self->m_hdr_offs = 0;
29 if (rec >= 0 && m_off >= 0 && fseek(fp, m_off, SEEK_CUR) >= 0)
30 {
31 /* Load PE header */
32 if (fread(self->m_magic, 1, 4, fp) == 4 &&
33 self->m_magic[0] == 'P' &&
34 self->m_magic[1] == 'E')
35 {
36 r = 0;
37 self->m_hdr_offs = ftell(fp) - 4;
38 if (fread(self->m_ihdr, 1, 20, fp) < 20) r = -1;
39 optsz = PEEK16(self->m_ihdr, 16);
40 if (optsz > 240) optsz = 240;
41 if (fread(self->m_ohdr, 1, optsz, fp) < optsz) r = -1;
42 self->m_hdr_end = ftell(fp);
43 }
44 }
45 if (rec >= 0) fseek(fp, rec, SEEK_SET);
46 return r;
47 }
48
49
pe_load_resdir(PEFILE * self,long offs)50 RESDIR *pe_load_resdir(PEFILE *self, long offs)
51 {
52 byte data[16];
53 RESDIR32 *rdir;
54
55 if (fseek(self->super.m_fp, offs, SEEK_SET)) return NULL;
56 if (fread(data, 1, 16, self->super.m_fp) < 16) return NULL;
57
58 rdir = malloc(sizeof(RESDIR32));
59 if (!rdir) return NULL;
60 new_RESDIR32(rdir, self, data, offs);
61 return (RESDIR *)rdir;
62 }
63
64
pe_open_resdir(MZFILE * s)65 RESDIR *pe_open_resdir(MZFILE *s)
66 {
67 int count;
68 byte sechdr[40];
69 long pos = -1;
70 RESDIR32 *rdir;
71 PEFILE *self = (PEFILE *)s;
72
73 if (fseek(s->m_fp, self->m_hdr_end, SEEK_SET)) return NULL;
74
75 count = PEEK16(self->m_ihdr, 2);
76 /* No. of sections in section dir */
77
78 while (count)
79 {
80 if (fread(sechdr, 1, 40, s->m_fp) < 40) return NULL;
81
82 if (!strcmp((char *)sechdr, ".rsrc"))
83 {
84 pos = PEEK32(sechdr, 20);
85 if (fseek(s->m_fp, pos, SEEK_SET)) return NULL;
86
87 rdir = (RESDIR32 *)pe_load_resdir(self, pos);
88
89 rdir->rsc_org = pos;
90 rdir->rva_base = PEEK32(sechdr, 12) - pos;
91 rdir->m_parent = NULL;
92 return (RESDIR *)rdir;
93 }
94 --count;
95 }
96 return NULL;
97 }
98
99
100
101
102