Skip to content

Instantly share code, notes, and snippets.

@thewisenerd
Created September 29, 2018 23:32
Show Gist options
  • Save thewisenerd/7d47f24c8957c497daf0928ebafcf73f to your computer and use it in GitHub Desktop.
Save thewisenerd/7d47f24c8957c497daf0928ebafcf73f to your computer and use it in GitHub Desktop.
extract kernel builtin_fw
#!/usr/bin/env python3
import argparse
import mmap
import os
parser = argparse.ArgumentParser(description='extract builtin_fw')
parser.add_argument('image', metavar='IMAGE', type=str,
help='kernel image file')
parser.add_argument('kallsyms', metavar='KALLSYMS', type=str,
help='kallsyms out file')
parser.add_argument('--start', dest='kstart', type=int, default=0xffffffc000000000,
help='kallsyms out file')
# kernel logical memory map
# <5>[ 0.000000] Virtual kernel memory layout:
# <5>[ 0.000000] vmalloc : 0xffffff8000000000 - 0xffffffbbffff0000 (245759 MB)
# <5>[ 0.000000] vmemmap : 0xffffffbc02000000 - 0xffffffbc04000000 ( 32 MB)
# <5>[ 0.000000] modules : 0xffffffbffc000000 - 0xffffffc000000000 ( 64 MB)
# <5>[ 0.000000] memory : 0xffffffc000000000 - 0xffffffc080000000 ( 2048 MB) <-- look for this line
# <5>[ 0.000000] .init : 0xffffffc0010c9000 - 0xffffffc0011348c0 ( 431 kB)
# <5>[ 0.000000] .text : 0xffffffc000080000 - 0xffffffc0010c8fd4 ( 16676 kB)
# <5>[ 0.000000] .data : 0xffffffc001135000 - 0xffffffc0012cded8 ( 1636 kB)
def process_kallsyms(kallsyms):
with open(kallsyms, 'r') as fd:
fw = {}
for e in fd.readlines():
split = e.strip().split()
if len(split) < 3:
continue
if split[2] == '__start_builtin_fw':
fw['start'] = split[0]
if split[2] == '__end_builtin_fw':
fw['end'] = split[0]
for k in ['start', 'end']:
if k not in fw.keys():
print('could not find __{}_builtin_fw; exit'.format(k))
exit(1)
return int(fw['start'], 16), int(fw['end'], 16)
def extract(kernel, start, fw_start, fw_end):
# struct builtin_fw {
# char *name; // 8
# void *data; // 8
# unsigned long size; // 8
# };
offsetb = kernel[8:16]
offset = int.from_bytes(offsetb, byteorder='little')
for b_fw_a in range(fw_start, fw_end, 24):
b_fw_a_f = b_fw_a - start - offset
b_fw = kernel[b_fw_a_f:b_fw_a_f+24]
na = int.from_bytes(b_fw[0:8], byteorder='little')
da = int.from_bytes(b_fw[8:16], byteorder='little')
sz = int.from_bytes(b_fw[16:24], byteorder='little')
name = ''
na_f = na - start - offset;
while kernel[na_f] != 0:
name += chr(kernel[na_f])
na_f = na_f + 1
da_f = da - start - offset
with open(name, 'wb') as fw_fd:
fw_fd.write(kernel[da_f:da_f+sz])
fw_fd.close()
print('{} : {} bytes'.format(name, sz))
def main(image, kallsyms, kstart):
(fw_start, fw_end) = process_kallsyms(kallsyms)
with open(image, "rb") as fd:
map = mmap.mmap(fd.fileno(), 0, access=mmap.ACCESS_READ)
extract(map, kstart, fw_start, fw_end)
map.close()
if __name__ == '__main__':
args = parser.parse_args()
main(args.image, args.kallsyms, args.kstart)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment