[Wisp-cvs] wisp/users/dig make-pe-exe.py,1.67,1.68
Status: Alpha
Brought to you by:
digg
From: <di...@us...> - 2003-05-16 17:07:19
|
Update of /cvsroot/wisp/wisp/users/dig In directory sc8-pr-cvs1:/tmp/cvs-serv29613 Modified Files: make-pe-exe.py Log Message: extracted make_pe_executable from the body of make-pe-exe.py Index: make-pe-exe.py =================================================================== RCS file: /cvsroot/wisp/wisp/users/dig/make-pe-exe.py,v retrieving revision 1.67 retrieving revision 1.68 diff -u -d -r1.67 -r1.68 --- make-pe-exe.py 16 May 2003 16:47:06 -0000 1.67 +++ make-pe-exe.py 16 May 2003 17:07:15 -0000 1.68 @@ -43,153 +43,158 @@ imports = Linkie('<') -sections = {'.text': text, '.data': data, '.bss': bss, '.imports': imports} -sectnames = ['.text', '.data', '.bss', '.imports'] - -e = Linkie('<'); -e.glue(0, make_pe_mz_stub('OS too broken'), 0x100) -if e.memsz() < 0x80: e.align(0x80) # attempt to create a file(1)-friendly exe -e.align(8) # PE header must be aligned to 8 -e.place_symbol('!pe') -e.emit_string('PE\0\0') -e.glue(e.memsz(), make_coff_header(), None) -e.glue(e.memsz(), make_pe_aout_header(), None) -for s in sectnames: - e.glue(e.memsz(), make_pe_section_header(s), None) - e.place_symbol('!' + s + '/reloc', 0) - e.place_symbol('!' + s + '/lineno', 0) - e.place_symbol('#' + s + '/reloc', 0) - e.place_symbol('#' + s + '/lineno', 0) -e.place_symbol('#.text/flags', 0x60000020) -e.place_symbol('#.data/flags', 0xc0000040) -e.place_symbol('#.bss/flags', 0xc0000080) -e.place_symbol('#.imports/flags', 0xc0000040) -e.align(512) -e.place_symbol('!aout/header-end') -## generate import structures -# gather names of import functions -imports_by_dlls = {} -for s in sectnames: - for ofs, typ, nam in sections[s].get_notes(): - if nam[0] != '&': continue - at = nam.find('@') - if at == -1: continue - name = nam[1:at] - dll = nam[at + 1:].lower() - if not imports_by_dlls.has_key(dll): - imports_by_dlls[dll] = {} - imports_by_dlls[dll][name] = None -# emit import table root -imports.align(4) -import_table_start = imports.memsz() -for dll in imports_by_dlls.keys(): - imports[::4] = '&.imports/%s/hint-name #rva' % dll - imports[::4] = 0 # timestamp - imports[::4] = '#.imports/%s/forwarder-chain' % dll - imports[::4] = '&.imports/%s/dll-name #rva' % dll - imports[::4] = '&.imports/%s/first-thunk #rva' % dll - imports.place_symbol('#.imports/' + dll + '/forwarder-chain', 0) -imports.emit_string('\0' * 20) -# emit hint/name lists -for dll in imports_by_dlls.keys(): - imports.align(4) - imports.place_symbol('&.imports/%s/hint-name' % dll) - for sym in imports_by_dlls[dll].keys(): - imports[::4] = '&.imports/thunk/%s@%s #rva' % (sym, dll) - imports.emit_tetra(0) -# emit thunk lists -for dll in imports_by_dlls.keys(): +def make_pe_executable (text = None, data = None, bss = None, + base_address = 0x00400000): + e = Linkie('<'); + e.glue(0, make_pe_mz_stub('OS too broken'), 0x100) + if e.memsz() < 0x80: + e.align(0x80) # attempt to create a file(1)-friendly exe + e.align(8) # PE header must be aligned to 8 + e.place_symbol('!pe') + e.emit_string('PE\0\0') + e.glue(e.memsz(), make_coff_header(), None) + e.glue(e.memsz(), make_pe_aout_header(), None) + text = text.copy() # so we won't add import stubs to the original linkie + sectnames = ['.text', '.data', '.bss', '.imports'] + sections = {'.text': text, '.data': data, '.bss': bss, '.imports': imports} + for s in sectnames: + e.glue(e.memsz(), make_pe_section_header(s), None) + e.place_symbol('!' + s + '/reloc', 0) + e.place_symbol('!' + s + '/lineno', 0) + e.place_symbol('#' + s + '/reloc', 0) + e.place_symbol('#' + s + '/lineno', 0) + e.place_symbol('#.text/flags', 0x60000020) + e.place_symbol('#.data/flags', 0xc0000040) + e.place_symbol('#.bss/flags', 0xc0000080) + e.place_symbol('#.imports/flags', 0xc0000040) + e.align(512) + e.place_symbol('!aout/header-end') + ## generate import structures + # gather names of import functions + imports_by_dlls = {} + for s in sectnames: + for ofs, typ, nam in sections[s].get_notes(): + if nam[0] != '&': continue + at = nam.find('@') + if at == -1: continue + name = nam[1:at] + dll = nam[at + 1:].lower() + if not imports_by_dlls.has_key(dll): + imports_by_dlls[dll] = {} + imports_by_dlls[dll][name] = None + # emit import table root imports.align(4) - imports.place_symbol('&.imports/%s/first-thunk' % dll) - for sym in imports_by_dlls[dll].keys(): - imports.place_symbol('&.imports/slot/' + sym + '@' + dll) - imports[::4] = '&.imports/thunk/%s@%s #rva' % (sym, dll) - imports.emit_tetra(0) -# emit thunk structures -for dll in imports_by_dlls.keys(): - for sym in imports_by_dlls[dll].keys(): - imports.place_symbol('&.imports/thunk/%s@%s' % (sym, dll)) - imports.align(2) - imports[::2] = 0 # ordinal - imports.emit_string(sym) + import_table_start = imports.memsz() + for dll in imports_by_dlls.keys(): + imports[::4] = '&.imports/%s/hint-name #rva' % dll + imports[::4] = 0 # timestamp + imports[::4] = '#.imports/%s/forwarder-chain' % dll + imports[::4] = '&.imports/%s/dll-name #rva' % dll + imports[::4] = '&.imports/%s/first-thunk #rva' % dll + imports.place_symbol('#.imports/' + dll + '/forwarder-chain', 0) + imports.emit_string('\0' * 20) + # emit hint/name lists + for dll in imports_by_dlls.keys(): + imports.align(4) + imports.place_symbol('&.imports/%s/hint-name' % dll) + for sym in imports_by_dlls[dll].keys(): + imports[::4] = '&.imports/thunk/%s@%s #rva' % (sym, dll) + imports.emit_tetra(0) + # emit thunk lists + for dll in imports_by_dlls.keys(): + imports.align(4) + imports.place_symbol('&.imports/%s/first-thunk' % dll) + for sym in imports_by_dlls[dll].keys(): + imports.place_symbol('&.imports/slot/' + sym + '@' + dll) + imports[::4] = '&.imports/thunk/%s@%s #rva' % (sym, dll) + imports.emit_tetra(0) + # emit thunk structures + for dll in imports_by_dlls.keys(): + for sym in imports_by_dlls[dll].keys(): + imports.place_symbol('&.imports/thunk/%s@%s' % (sym, dll)) + imports.align(2) + imports[::2] = 0 # ordinal + imports.emit_string(sym) + imports[::1] = 0 + # emit DLL names + for dll in imports_by_dlls.keys(): + imports.place_symbol('&.imports/%s/dll-name' % dll) + imports.emit_string(dll + '.dll') imports[::1] = 0 -# emit DLL names -for dll in imports_by_dlls.keys(): - imports.place_symbol('&.imports/%s/dll-name' % dll) - imports.emit_string(dll + '.dll') - imports[::1] = 0 -# generate stub procedures -for dll in imports_by_dlls.keys(): - for sym in imports_by_dlls[dll].keys(): - text.align(8) - text.place_symbol('&' + sym + '@' + dll) - text[::1] = 0xFF, 0x25 - text.emit_tetra_sum(['&.imports/slot/' + sym + '@' + dll]) + # generate stub procedures + for dll in imports_by_dlls.keys(): + for sym in imports_by_dlls[dll].keys(): + text.align(8) + text.place_symbol('&' + sym + '@' + dll) + text[::1] = 0xFF, 0x25 + text.emit_tetra_sum(['&.imports/slot/' + sym + '@' + dll]) -# paste sections together -e.align(512) -base_address = 0x00400000 -base_address = roundup(base_address, 0x1000) # to page boundary -memory_boundary = base_address -memory_boundary += 0x1000 # skip the first page -for s in sectnames: - # file alignment + # paste sections together e.align(512) - # memory alignment - memory_boundary = roundup(memory_boundary, \ - max(0x1000, sections[s].get_alignment())) - # establish origin symbols - e.place_symbol('!' + s) - e.place_symbol('&' + s, memory_boundary) - # process sizes - e.place_symbol('#' + s + '/memsz', sections[s].memsz()) - e.place_symbol('#' + s + '/filesz', roundup(sections[s].filesz(), 0x200)) - # paste bits - e.glue(e.memsz(), sections[s], memory_boundary) - # increase memory_boundary - memory_boundary = roundup(memory_boundary + sections[s].memsz(), 4096) + base_address = roundup(base_address, 0x1000) # to page boundary + memory_boundary = base_address + memory_boundary += 0x1000 # skip the first page + for s in sectnames: + # file alignment + e.align(512) + # memory alignment + memory_boundary = roundup(memory_boundary, \ + max(0x1000, sections[s].get_alignment())) + # establish origin symbols + e.place_symbol('!' + s) + e.place_symbol('&' + s, memory_boundary) + # process sizes + e.place_symbol('#' + s + '/memsz', sections[s].memsz()) + e.place_symbol('#' + s + '/filesz', roundup(sections[s].filesz(), 0x200)) + # paste bits + e.glue(e.memsz(), sections[s], memory_boundary) + # increase memory_boundary + memory_boundary = roundup(memory_boundary + sections[s].memsz(), 4096) -e.place_symbol('&aout/image-end', memory_boundary) + e.place_symbol('&aout/image-end', memory_boundary) -e.place_symbol('#coff/magic', 0x014C) # I386MAGIC -e.place_symbol('#coff/nscns', len(sectnames)) -e.place_symbol('#coff/timdat', int(time.time())) -e.place_symbol('!coff/symptr', 0) -e.place_symbol('#coff/nsyms', 0) -e.place_symbol('#coff/opthdr', 0x00E0) -e.place_symbol('#coff/flags', 0x020F) -e.place_symbol('#aout/magic', 0x010B) # PE32 -e.place_symbol('#aout/linker-version-major', 0) -e.place_symbol('#aout/linker-version-minor', 1) -e.place_symbol('#aout/text-size', roundup(text.memsz(), 0x200)) -e.place_symbol('#aout/data-size', roundup(data.memsz(), 0x200)) -e.place_symbol('#aout/bss-size', roundup(bss.memsz(), 0x200)) -e.place_symbol('#aout/image-base', 0x00400000) -e.place_symbol('#rva', -0x00400000) # adding this to an address will yield RVA -e.place_symbol('#aout/memory-align', 4096) -e.place_symbol('#aout/file-align', 512) -# 4.0 = MSW95 -e.place_symbol('#aout/os-version-major', 4) -e.place_symbol('#aout/os-version-minor', 0) -# -e.place_symbol('#aout/image-version-major', 0) -e.place_symbol('#aout/image-version-minor', 1) -# 4.0 = MSW95 -e.place_symbol('#aout/subsys-version-major', 4) -e.place_symbol('#aout/subsys-version-minor', 0) -e.place_symbol('#aout/subsys', PE_SUBSYS.WINDOWS_CHAR) -e.place_symbol('#aout/dll-flags', 0) -e.place_symbol('#aout/stack-reserve-size', 1024 * 1024) # one megabyte -e.place_symbol('#aout/stack-commit-size', 0x1000) # one page -e.place_symbol('#aout/heap-reserve-size', 1024 * 1024) # one megabyte -e.place_symbol('#aout/heap-commit-size', 0x1000) # one page + e.place_symbol('#coff/magic', 0x014C) # I386MAGIC + e.place_symbol('#coff/nscns', len(sectnames)) + e.place_symbol('#coff/timdat', int(time.time())) + e.place_symbol('!coff/symptr', 0) + e.place_symbol('#coff/nsyms', 0) + e.place_symbol('#coff/opthdr', 0x00E0) + e.place_symbol('#coff/flags', 0x020F) + e.place_symbol('#aout/magic', 0x010B) # PE32 + e.place_symbol('#aout/linker-version-major', 0) + e.place_symbol('#aout/linker-version-minor', 1) + e.place_symbol('#aout/text-size', roundup(text.memsz(), 0x200)) + e.place_symbol('#aout/data-size', roundup(data.memsz(), 0x200)) + e.place_symbol('#aout/bss-size', roundup(bss.memsz(), 0x200)) + e.place_symbol('#aout/image-base', 0x00400000) + e.place_symbol('#rva', -0x00400000) # adding this to an address will yield RVA + e.place_symbol('#aout/memory-align', 4096) + e.place_symbol('#aout/file-align', 512) + # 4.0 = MSW95 + e.place_symbol('#aout/os-version-major', 4) + e.place_symbol('#aout/os-version-minor', 0) + # + e.place_symbol('#aout/image-version-major', 0) + e.place_symbol('#aout/image-version-minor', 1) + # 4.0 = MSW95 + e.place_symbol('#aout/subsys-version-major', 4) + e.place_symbol('#aout/subsys-version-minor', 0) + e.place_symbol('#aout/subsys', PE_SUBSYS.WINDOWS_CHAR) + e.place_symbol('#aout/dll-flags', 0) + e.place_symbol('#aout/stack-reserve-size', 1024 * 1024) # one megabyte + e.place_symbol('#aout/stack-commit-size', 0x1000) # one page + e.place_symbol('#aout/heap-reserve-size', 1024 * 1024) # one megabyte + e.place_symbol('#aout/heap-commit-size', 0x1000) # one page -# Note that null RVAs are those that equal base_address -e.place_symbol('#aout/dict-entry-count', 16) -populate_pe_directories(e, base_address) -e.align(512) + # Note that null RVAs are those that equal base_address + e.place_symbol('#aout/dict-entry-count', 16) + populate_pe_directories(e, base_address) + e.align(512) -e.link() + e.link() + return e + +e = make_pe_executable(text = text, data = data, bss = bss) e.dump() e.get_file().tofile(open('pehello.exe', 'w')) |