-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpe.c
89 lines (69 loc) · 2.35 KB
/
pe.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <stdio.h>
#include <stdlib.h>
#include "pe.h"
#include "global.h"
/* Parse PE header and populate PESTRUCT variable */
void parse_pe_header(void) {
BYTE *buf = (BYTE *) malloc(16 * sizeof(BYTE));
DWORD fpos = ftell(fin); // Store the current file position
// Get PE offset value from DOS stub
fseek(fin, 0x3C, SEEK_SET);
fgets(buf, 4, fin);
pe->offset = lendian(buf, 4);
// Get number of sections
fseek(fin, (pe->offset + 6), SEEK_SET);
fgets(buf, 2, fin);
pe->numsects = lendian(buf, 2);
// Get size of PE header
fseek(fin, (pe->offset + 20), SEEK_SET);
fgets(buf, 2, fin);
pe->peheadersize = lendian(buf, 2) + 24; // 24 bytes for COFF header and PE signature
// Get RVA of entry point
fseek(fin, (pe->offset + 40), SEEK_SET);
fgets(buf, 4, fin);
pe->rvaep = lendian(buf, 4);
// Get RVA of code section
fseek(fin, (pe->offset + 44), SEEK_SET);
fgets(buf, 4, fin);
pe->rvacode = lendian(buf, 4);
// Get RVA of data section
fseek(fin, (pe->offset + 48), SEEK_SET);
fgets(buf, 4, fin);
pe->rvadata = lendian(buf, 4);
// Get address of image base
fseek(fin, (pe->offset + 52), SEEK_SET);
fgets(buf, 4, fin);
pe->imagebase = lendian(buf, 4);
// Get size of code section
fseek(fin, (pe->offset + 28), SEEK_SET);
fgets(buf, 4, fin);
pe->codesize = lendian(buf, 4);
// Each section header size is 40 bytes
pe->sectheadersize = 40;
fseek(fin, fpos, SEEK_SET); // Restore the file position
free(buf);
}
/* Parse given section number and populate SECTSTRUCT variable */
void parse_section(SECTSTRUCT *sect, int n) {
BYTE *buf = (BYTE *) malloc(4 * sizeof(BYTE));
DWORD fpos = ftell(fin); // Store the current file position
// Go to beginning of section information
DWORD sect_offset = (pe->offset + pe->peheadersize + (n * pe->sectheadersize));
fseek(fin, sect_offset, SEEK_SET);
// Get section name
fgets(sect->name, 8, fin);
// Get virtual address
fseek(fin, sect_offset + 12, SEEK_SET);
fgets(buf, 4, fin);
sect->va = lendian(buf, 4);
// Get size of raw data
fseek(fin, sect_offset + 16, SEEK_SET);
fgets(buf, 4, fin);
sect->size = lendian(buf, 4);
// Get pointer to raw data
fseek(fin, sect_offset + 20, SEEK_SET);
fgets(buf, 4, fin);
sect->offset = lendian(buf, 4);
fseek(fin, fpos, SEEK_SET); // Restore the file position
free(buf);
}