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