58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
import struct, sys, shutil, os
|
|
|
|
|
|
def align(x, a):
|
|
return (x + a - 1) // a * a
|
|
|
|
|
|
def main():
|
|
src, dst = sys.argv[1], sys.argv[2]
|
|
size = int(sys.argv[3], 0) if len(sys.argv) > 3 else 0x300000
|
|
secname = sys.argv[4] if len(sys.argv) > 4 else ".cjk"
|
|
data = bytearray(open(src, "rb").read())
|
|
|
|
e_lfanew = struct.unpack_from("<I", data, 0x3C)[0]
|
|
coff = e_lfanew + 4
|
|
nsec = struct.unpack_from("<H", data, coff + 2)[0]
|
|
optsize = struct.unpack_from("<H", data, coff + 16)[0]
|
|
opt = coff + 20
|
|
imagebase = struct.unpack_from("<I", data, opt + 28)[0]
|
|
sect_align = struct.unpack_from("<I", data, opt + 32)[0]
|
|
file_align = struct.unpack_from("<I", data, opt + 36)[0]
|
|
size_image = struct.unpack_from("<I", data, opt + 56)[0]
|
|
so = opt + optsize
|
|
|
|
secs = []
|
|
for i in range(nsec):
|
|
o = so + i * 40
|
|
vs, va, rs, rp = struct.unpack_from("<IIII", data, o + 8)
|
|
secs.append((va, vs, rp, rs, o))
|
|
last_va, last_vs = secs[-1][0], secs[-1][1]
|
|
new_va = align(last_va + last_vs, sect_align)
|
|
new_raw = align(len(data), file_align)
|
|
|
|
if so + (nsec + 1) * 40 > secs[0][2]:
|
|
print("no room for new section header", file=sys.stderr)
|
|
sys.exit(3)
|
|
|
|
hdr = so + nsec * 40
|
|
name = secname.encode("ascii")[:8].ljust(8, b"\x00")
|
|
struct.pack_into("<8sIIII", data, hdr, name, size, new_va, align(size, file_align), new_raw)
|
|
struct.pack_into("<IIHH", data, hdr + 36, 0xE0000020, 0, 0, 0)
|
|
# characteristics: CNT_CODE|CNT_INITIALIZED_DATA|MEM_EXECUTE|MEM_READ|MEM_WRITE = 0xE0000020
|
|
|
|
struct.pack_into("<H", data, coff + 2, nsec + 1)
|
|
struct.pack_into("<I", data, opt + 56, align(new_va + size, sect_align))
|
|
|
|
if len(data) < new_raw:
|
|
data += b"\x00" * (new_raw - len(data))
|
|
data += b"\x00" * align(size, file_align)
|
|
|
|
open(dst, "wb").write(data)
|
|
print("added %s VA=0x%x raw=0x%x size=0x%x -> %s (%d bytes)" % (secname, new_va, new_raw, size, dst, len(data)))
|
|
print("section VA (absolute, imagebase 0x%x): 0x%x" % (imagebase, imagebase + new_va))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|