44. セグメントのロード
• メモリサイズの算出
memlen = max([ph.p_vaddr + ph.p_memsz for ph in phs])
ELFヘッダ
プログラムヘッダ
.interp
.hash
.dynsym
.dynstr
.rel.plt
.plt
.text
.dynamic
.got.plt
.shstrtab
セクションヘッダ
• 実行可能ページを確保
mem = VirtualAlloc(0, memlen,
MEM_COMMIT, PAGE_EXECUTE_READWRITE)
• プログラムヘッダを見てロード
pelf = cast(elf, c_void_p).value
for ph in phs:
addr = mem + ph.p_vaddr
if ph.p_type == 1: # PT_LOAD
o, sz = ph.p_offset, ph.p_memsz
memmove(addr, pelf + o, sz)
print "LOAD: %08x-%08x => %08x-%08x" % (
o, o + sz - 1, addr, addr + sz - 1)
45. .dynamic
• プログラムヘッダに.dynamicが指
定されていれば読み込む
• 最低限必要なものだけ
• type = 0 は終端
elif ph.p_type == 2: # PT_DYNAMIC
while True:
type = read32(addr)
val = read32(addr + 4)
if type == 0: break
elif type == 5: strtab = mem + val
elif type == 6: symtab = mem + val
elif type == 11: syment = val
elif type == 23: jmprel = mem + val
elif type == 2: pltrelsz = val
addr += 8
ELFヘッダ
プログラムヘッダ
.interp
.hash
.dynsym
.dynstr
.rel.plt
.plt
.text
.dynamic
.got.plt
.shstrtab
セクションヘッダ