-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathgenerate_found_id.py
92 lines (61 loc) · 2.6 KB
/
generate_found_id.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# This tool will generate a found id header file for how an elf object should be loaded by the elf loader
# Usage: generate_found_id.py in_file cap_size num_entries
# The layout expected matches that generated by elf_loader.c.
# It is what the elf specifies, plus space for an initial TLS segment
import sys
import elftools
import hashlib
from elftools.elf.elffile import ELFFile
def main():
in_path = sys.argv[1]
cap_size = int(sys.argv[2])
found_entries = sys.argv[3]
name = in_path.split(".elf")[0].split('/')[-1] + "_elf"
define_guard = name + "_H"
sha = hashlib.sha256()
tls_seg_size = 0
virt_addr_ptr = 0
with open(in_path, 'rb') as in_file:
elffile = ELFFile(in_file)
entry = elffile.header['e_entry']
for segment in elffile.iter_segments():
seg_type = segment.header['p_type']
mem_size = segment.header['p_memsz']
if(seg_type == 'PT_LOAD'):
fil_size = segment.header['p_filesz']
virt_addr = segment.header['p_vaddr']
# Cant go backwards. Why arn't your program headers sorted?
if(virt_addr < virt_addr_ptr):
raise()
# Skip bytes
if(virt_addr > virt_addr_ptr):
sha.update(bytearray(virt_addr - virt_addr_ptr))
# Then file bytes
sha.update(segment.data())
# Then padding with zeros
if(mem_size > fil_size):
sha.update(bytearray(mem_size - fil_size))
virt_addr_ptr = virt_addr + mem_size
elif(seg_type == 'PT_TLS'):
tls_seg_size = mem_size
# Program loader adds in a tls seg size + CAP_SIZE of extra zeros
tls_seg_size += cap_size
virt_addr_ptr += tls_seg_size
# Also need to pad to a multiple of 8 bytes to be loaded in a foundation
align_bytes = (-virt_addr_ptr % 8)
virt_addr_ptr += align_bytes
sha.update(bytearray(tls_seg_size + align_bytes))
digest = sha.digest()
print ("// DO NOT EDIT. AUTO-GENERATED.")
print ("#ifndef " + define_guard)
print ("#define " + define_guard)
print ("#include \"nano/nanotypes.h\"")
print ("static const found_id_t " + name + "_id = (found_id_t){")
print (" .sha256 = {" + ",".join("0x{:02x}".format(c) for c in digest) + "},")
print (" .length = " + str(virt_addr_ptr) + ",")
print (" .e0 = " + str(entry) + ",")
print (" .nentries = " + found_entries)
print ("};")
print ("#endif // " + define_guard)
if __name__== "__main__":
main()