#!/usr/bin/env python3 import argparse import pefile import struct from pprint import pprint def main(): pp = argparse.ArgumentParser(description='Dump FSB5 vorbis headers from a 32-bit Windows executable') pp.add_argument('file', help='path to executable file') args = pp.parse_args() pe = pefile.PE(args.file) lookup = {} base_addr = pe.OPTIONAL_HEADER.ImageBase # reimplementation of get_memory_mapped_image because pefile did not survive # the port to python 3 fully in tact... mapped_data = pe.__data__[:] for section in pe.sections: # Miscellaneous integrity tests. # Some packer will set these to bogus values to make tools go nuts. if section.Misc_VirtualSize == 0 or section.SizeOfRawData == 0: continue if section.SizeOfRawData > len(pe.__data__): continue if pe.adjust_FileAlignment( section.PointerToRawData, pe.OPTIONAL_HEADER.FileAlignment ) > len(pe.__data__): continue VirtualAddress_adj = pe.adjust_SectionAlignment( section.VirtualAddress, pe.OPTIONAL_HEADER.SectionAlignment, pe.OPTIONAL_HEADER.FileAlignment ) padding_length = VirtualAddress_adj - len(mapped_data) if padding_length>0: mapped_data += b'\0'*padding_length elif padding_length<0: mapped_data = mapped_data[:padding_length] mapped_data += section.get_data() vas = [] va = 0 while True: va = mapped_data.find(b'\x05vorbis', va) if va > 0: vas.append(base_addr + va) va += 7 else: break refs = [] for va in vas: word = struct.pack(' 0: refs.append(base_addr + ref) ref += 4 else: break refs.sort() table_addr = 0 for ref in refs: if (ref - 24 not in refs and ref - 12 not in refs) and (ref + 24 in refs or ref + 36 in refs): table_addr = ref break if table_addr == 0: raise ea = table_addr while True: ea_ofs = ea - base_addr buf1, len1, crc, buf2, ofs, len2 = struct.unpack(' 8192 or len2 > 8192: break hdr = bytearray(len1) base_buf = buf1 if buf2 != 0: base_buf = buf2 for j in range(len1): hdr[j] = mapped_data[base_buf + j - base_addr] if buf2 != 0: for j in range(len2): hdr[ofs+j] = mapped_data[buf1 + j - base_addr] lookup[crc] = bytes(hdr) ea += 24 print('lookup = ', end='') pprint(lookup) if __name__ == '__main__': main()