| ... | ... | @@ -98,6 +98,7 @@ pub const CoffError = error{ |
| 98 | 98 | InvalidPEHeader, |
| 99 | 99 | InvalidMachine, |
| 100 | 100 | MissingCoffSection, |
| 101 | MissingStringTable, |
| 101 | 102 | }; |
| 102 | 103 | |
| 103 | 104 | // Official documentation of the format: https://docs.microsoft.com/en-us/windows/win32/debug/pe-format |
| ... | ... | @@ -162,6 +163,25 @@ pub const Coff = struct { |
| 162 | 163 | try self.loadOptionalHeader(); |
| 163 | 164 | } |
| 164 | 165 | |
| 166 | fn readStringFromTable(self: *Coff, offset: usize, buf: []u8) ![]const u8 { |
| 167 | if (self.coff_header.pointer_to_symbol_table == 0) { |
| 168 | // No symbol table therefore no string table |
| 169 | return error.MissingStringTable; |
| 170 | } |
| 171 | // The string table is at the end of the symbol table and symbols are 18 bytes long |
| 172 | const string_table_offset = self.coff_header.pointer_to_symbol_table + (self.coff_header.number_of_symbols * 18) + offset; |
| 173 | const in = self.in_file.reader(); |
| 174 | const old_pos = try self.in_file.getPos(); |
| 175 | |
| 176 | try self.in_file.seekTo(string_table_offset); |
| 177 | defer { |
| 178 | self.in_file.seekTo(old_pos) catch unreachable; |
| 179 | } |
| 180 | |
| 181 | const str = try in.readUntilDelimiterOrEof(buf, 0); |
| 182 | return str orelse ""; |
| 183 | } |
| 184 | |
| 165 | 185 | fn loadOptionalHeader(self: *Coff) !void { |
| 166 | 186 | const in = self.in_file.reader(); |
| 167 | 187 | self.pe_header.magic = try in.readIntLittle(u16); |
| ... | ... | @@ -258,11 +278,23 @@ pub const Coff = struct { |
| 258 | 278 | |
| 259 | 279 | const in = self.in_file.reader(); |
| 260 | 280 | |
| 261 | | var name: [8]u8 = undefined; |
| 281 | var name: [32]u8 = undefined; |
| 262 | 282 | |
| 263 | 283 | var i: u16 = 0; |
| 264 | 284 | while (i < self.coff_header.number_of_sections) : (i += 1) { |
| 265 | | try in.readNoEof(name[0..]); |
| 285 | try in.readNoEof(name[0..8]); |
| 286 | |
| 287 | if (name[0] == '/') { |
| 288 | // This is a long name and stored in the string table |
| 289 | const offset_len = mem.indexOfScalar(u8, name[1..], 0) orelse 7; |
| 290 | |
| 291 | const str_offset = try std.fmt.parseInt(u32, name[1 .. offset_len + 1], 10); |
| 292 | const str = try self.readStringFromTable(str_offset, &name); |
| 293 | std.mem.set(u8, name[str.len..], 0); |
| 294 | } else { |
| 295 | std.mem.set(u8, name[8..], 0); |
| 296 | } |
| 297 | |
| 266 | 298 | try self.sections.append(Section{ |
| 267 | 299 | .header = SectionHeader{ |
| 268 | 300 | .name = name, |
| ... | ... | @@ -331,7 +363,7 @@ const SectionHeader = struct { |
| 331 | 363 | virtual_size: u32, |
| 332 | 364 | }; |
| 333 | 365 | |
| 334 | | name: [8]u8, |
| 366 | name: [32]u8, |
| 335 | 367 | misc: Misc, |
| 336 | 368 | virtual_address: u32, |
| 337 | 369 | size_of_raw_data: u32, |