[Wisp-cvs] wisp/users/dig make-pe-exe.py,1.68,1.69 pe.py,1.5,1.6
Status: Alpha
Brought to you by:
digg
|
From: <di...@us...> - 2003-05-16 17:14:32
|
Update of /cvsroot/wisp/wisp/users/dig
In directory sc8-pr-cvs1:/tmp/cvs-serv32162
Modified Files:
make-pe-exe.py pe.py
Log Message:
moved make_pe_executable to pe.py
Index: make-pe-exe.py
===================================================================
RCS file: /cvsroot/wisp/wisp/users/dig/make-pe-exe.py,v
retrieving revision 1.68
retrieving revision 1.69
diff -u -d -r1.68 -r1.69
--- make-pe-exe.py 16 May 2003 17:07:15 -0000 1.68
+++ make-pe-exe.py 16 May 2003 17:14:29 -0000 1.69
@@ -10,14 +10,9 @@
from linkie import Linkie
from pe import *
-from coff import *
-import time
# This file is *very* incomplete
-def roundup (value, boundary):
- return (value + boundary - 1) & ~(boundary - 1)
-
text = Linkie('<') # ia32
text.place_symbol('&_start')
text[::1] = 0x68; text[::4] = -11 # push -11
@@ -40,160 +35,6 @@
bss = Linkie('<')
bss.place_symbol('&rckeep')
bss.skip(4)
-
-imports = Linkie('<')
-
-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)
- 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
-
- # 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 = 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('#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)
-
- e.link()
- return e
e = make_pe_executable(text = text, data = data, bss = bss)
e.dump()
Index: pe.py
===================================================================
RCS file: /cvsroot/wisp/wisp/users/dig/pe.py,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- pe.py 16 May 2003 16:47:07 -0000 1.5
+++ pe.py 16 May 2003 17:14:29 -0000 1.6
@@ -7,6 +7,11 @@
#### @(#) $Id$
from mz import *
+from coff import *
+import time
+
+def roundup (value, boundary):
+ return (value + boundary - 1) & ~(boundary - 1)
class PE_SUBSYS:
UNKNOWN = 0
@@ -167,3 +172,156 @@
for s in defaults.keys():
if given.has_key(s): linkie.place_symbol(s, given[s])
else: linkie.place_symbol(s, defaults[s])
+
+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
+ imports = 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)
+ 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
+
+ # 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 = 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('#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)
+
+ e.link()
+ return e
|