1 /*
2 * ReactOS log2lines
3 * Written by Jan Roeloffzen
4 *
5 * - Image functions for symbol info
6 */
7
8 #include <errno.h>
9 #include <string.h>
10 #include <rsym.h>
11
12 #include "compat.h"
13 #include "util.h"
14 #include "options.h"
15 #include "log2lines.h"
16 #include <sys/types.h>
17
18 static PIMAGE_SECTION_HEADER
find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader,PIMAGE_SECTION_HEADER PESectionHeaders)19 find_rossym_section(PIMAGE_FILE_HEADER PEFileHeader, PIMAGE_SECTION_HEADER PESectionHeaders)
20 {
21 size_t i;
22 for (i = 0; i < PEFileHeader->NumberOfSections; i++)
23 {
24 if (0 == strcmp((char *)PESectionHeaders[i].Name, ".rossym"))
25 return &PESectionHeaders[i];
26 }
27 return NULL;
28 }
29
30 size_t
fixup_offset(size_t ImageBase,size_t offset)31 fixup_offset(size_t ImageBase, size_t offset)
32 {
33 if (offset > ABS_TRESHOLD)
34 offset -= ImageBase;
35 return offset;
36 }
37
38 PROSSYM_ENTRY
find_offset(void * data,size_t offset)39 find_offset(void *data, size_t offset)
40 {
41 PSYMBOLFILE_HEADER RosSymHeader = (PSYMBOLFILE_HEADER)data;
42 PROSSYM_ENTRY Entries = (PROSSYM_ENTRY)((char *)data + RosSymHeader->SymbolsOffset);
43 size_t symbols = RosSymHeader->SymbolsLength / sizeof(ROSSYM_ENTRY);
44 size_t i;
45
46 for (i = 0; i < symbols; i++)
47 {
48 if (Entries[i].Address > offset)
49 {
50 if (!i--)
51 return NULL;
52 else
53 return &Entries[i];
54 }
55 }
56 return NULL;
57 }
58
59 PIMAGE_SECTION_HEADER
get_sectionheader(const void * FileData)60 get_sectionheader(const void *FileData)
61 {
62 PIMAGE_DOS_HEADER PEDosHeader;
63 PIMAGE_FILE_HEADER PEFileHeader;
64 PIMAGE_OPTIONAL_HEADER PEOptHeader;
65 PIMAGE_SECTION_HEADER PESectionHeaders;
66 PIMAGE_SECTION_HEADER PERosSymSectionHeader;
67 size_t ImageBase;
68
69 /* Check if MZ header exists */
70 PEDosHeader = (PIMAGE_DOS_HEADER)FileData;
71 if (PEDosHeader->e_magic != IMAGE_DOS_MAGIC || PEDosHeader->e_lfanew == 0L)
72 {
73 l2l_dbg(0, "Input file is not a PE image.\n");
74 summ.offset_errors++;
75 return NULL;
76 }
77
78 /* Locate PE file header */
79 /* sizeof(ULONG) = sizeof(MAGIC) */
80 PEFileHeader = (PIMAGE_FILE_HEADER)((char *)FileData + PEDosHeader->e_lfanew + sizeof(ULONG));
81
82 /* Locate optional header */
83 PEOptHeader = (PIMAGE_OPTIONAL_HEADER)(PEFileHeader + 1);
84 ImageBase = PEOptHeader->ImageBase;
85
86 /* Locate PE section headers */
87 PESectionHeaders = (PIMAGE_SECTION_HEADER)((char *)PEOptHeader + PEFileHeader->SizeOfOptionalHeader);
88
89 /* find rossym section */
90 PERosSymSectionHeader = find_rossym_section(PEFileHeader, PESectionHeaders);
91 if (!PERosSymSectionHeader)
92 {
93 l2l_dbg(0, "Couldn't find rossym section in executable\n");
94 summ.offset_errors++;
95 return NULL;
96 }
97
98 return PERosSymSectionHeader;
99 }
100
101 int
get_ImageBase(char * fname,size_t * ImageBase)102 get_ImageBase(char *fname, size_t *ImageBase)
103 {
104 IMAGE_DOS_HEADER PEDosHeader;
105 IMAGE_FILE_HEADER PEFileHeader;
106 IMAGE_OPTIONAL_HEADER PEOptHeader;
107
108 FILE *fr;
109 off_t readLen;
110 int res;
111
112 *ImageBase = INVALID_BASE;
113 fr = fopen(fname, "rb");
114 if (!fr)
115 {
116 l2l_dbg(3, "get_ImageBase, cannot open '%s' (%s)\n", fname, strerror(errno));
117 return 1;
118 }
119
120 readLen = fread(&PEDosHeader, sizeof(IMAGE_DOS_HEADER), 1, fr);
121 if (1 != readLen)
122 {
123 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_DOS_HEADER (%s)\n", fname, strerror(errno));
124 fclose(fr);
125 return 2;
126 }
127
128 /* Check if MZ header exists */
129 if (PEDosHeader.e_magic != IMAGE_DOS_MAGIC || PEDosHeader.e_lfanew == 0L)
130 {
131 l2l_dbg(2, "get_ImageBase %s, MZ header missing\n", fname);
132 fclose(fr);
133 return 3;
134 }
135
136 /* Locate PE file header */
137 res = fseek(fr, PEDosHeader.e_lfanew + sizeof(ULONG), SEEK_SET);
138 readLen = fread(&PEFileHeader, sizeof(IMAGE_FILE_HEADER), 1, fr);
139 if (1 != readLen)
140 {
141 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_FILE_HEADER (%s)\n", fname, strerror(errno));
142 fclose(fr);
143 return 4;
144 }
145
146 /* Locate optional header */
147 readLen = fread(&PEOptHeader, sizeof(IMAGE_OPTIONAL_HEADER), 1, fr);
148 if (1 != readLen)
149 {
150 l2l_dbg(1, "get_ImageBase %s, read error IMAGE_OPTIONAL_HEADER (%s)\n", fname, strerror(errno));
151 fclose(fr);
152 return 5;
153 }
154
155 /* Check if it's really an IMAGE_OPTIONAL_HEADER we are interested in */
156 if (PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
157 PEOptHeader.Magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC)
158 {
159 l2l_dbg(2, "get_ImageBase %s, not an IMAGE_NT_OPTIONAL_HDR 32/64 bit\n", fname);
160 fclose(fr);
161 return 6;
162 }
163
164 *ImageBase = PEOptHeader.ImageBase;
165 fclose(fr);
166 return 0;
167 }
168
169 /* EOF */
170