Minor Update: vmlinux-to-elf updated

Signed-off-by: rokibhasansagar <rokibhasansagar2014@outlook.com>
This commit is contained in:
rokibhasansagar 2020-11-06 21:51:20 +06:00
parent 3721b32cc8
commit e63053f84f
No known key found for this signature in database
GPG Key ID: 2A43163956D6C2A7
12 changed files with 53 additions and 43 deletions

View File

@ -7,7 +7,7 @@ from argparse import Namespace
from enum import IntEnum
from io import BytesIO
from time import time
import logging
"""
Guess the architecture of a given binary.
@ -189,6 +189,6 @@ def guess_architecture(binary : bytes) -> ArchitectureName:
if not architecture_guess:
raise ArchitectureGuessError('The architecture could not be guessed successfully')
print('[+] Guessed architecture: %s successfully in %.2f seconds' % (architecture_guess.name, time() - begin_time))
logging.info('[+] Guessed architecture: %s successfully in %.2f seconds' % (architecture_guess.name, time() - begin_time))
return architecture_guess

View File

@ -3,7 +3,7 @@
from re import search, IGNORECASE
from argparse import Namespace
from io import BytesIO
import logging
"""
The ElfSymbolizer class, defined in this file, gathers information from
@ -198,7 +198,7 @@ class ElfSymbolizer():
kernel.serialize(fd)
print('[+] Successfully wrote the new ELF kernel to %s' % output_file)
logging.info('[+] Successfully wrote the new ELF kernel to %s' % output_file)

View File

@ -7,8 +7,8 @@ from typing import List, Dict, Tuple
from argparse import ArgumentParser
from io import BytesIO
from enum import Enum
from sys import argv
from sys import argv, stdout
import logging
try:
from architecture_detecter import guess_architecture, ArchitectureName, architecture_name_to_elf_machine_and_is64bits_and_isbigendian, ArchitectureGuessError
@ -226,9 +226,9 @@ class KallsymsFinder:
self.version_string = regex_match.group(0).decode('ascii')
self.version_number = regex_match.group(1).decode('ascii')
print('[+] Version string:', self.version_string)
#print('[+] Other related strings containing the version number:', findall(b'[ -~]*%s[ -~]*' % regex_match.group(1), self.kernel_img))
#print('[+] Architecture string:', search(b'mod_unload[ -~]+', self.kernel_img).group(0))
logging.info('[+] Version string: {0:s}'.format(self.version_string))
#logging.info('[+] Other related strings containing the version number: {0:s}'.format(findall(b'[ -~]*%s[ -~]*' % regex_match.group(1), self.kernel_img)))
#logging.info('[+] Architecture string: {0:s}'.format(search(b'mod_unload[ -~]+', self.kernel_img).group(0)))
def guess_architecture(self):
@ -291,13 +291,13 @@ class KallsymsFinder:
possible_offset = offset - 1
while possible_offset % 8 != 0: # Find a pointer-aligned r_info entry
possible_offset = self.kernel_img.rfind(R_AARCH64_RELATIVE.to_bytes(8, 'little'), 8, possible_offset - rela64_size)
possible_offset = self.kernel_img.rfind(R_AARCH64_RELATIVE.to_bytes(8, 'little'), 8, possible_offset - rela64_size + 1)
if possible_offset == -1:
offset = 0
break
if possible_offset != -1:
offset = possible_offset + 8
offset = possible_offset - 8
continue
@ -313,8 +313,8 @@ class KallsymsFinder:
self.kernel_text_candidate = kernel_text_candidate
self.elf64_rela = elf64_rela
print('[+] Found relocations table at file offset 0x%04x (count=%d)' % (offset, count))
print('[+] Found kernel text candidate: 0x%08x' % (kernel_text_candidate))
logging.info('[+] Found relocations table at file offset 0x%04x (count=%d)' % (offset, count))
logging.info('[+] Found kernel text candidate: 0x%08x' % (kernel_text_candidate))
return True
def apply_elf64_rela(self) -> bool:
@ -337,8 +337,8 @@ class KallsymsFinder:
r_offset, r_info, r_addend = rela
offset = (r_offset - kernel_base)
if offset < 0 or offset > offset_max:
print('WARNING! bad rela offset %08x' % (r_offset))
if offset < 0 or offset >= offset_max:
logging.warn('WARNING! bad rela offset %08x' % (r_offset))
continue
value, = unpack_from('<Q', self.kernel_img, offset)
@ -353,11 +353,13 @@ class KallsymsFinder:
# BUG: Probably 'r_addend' can represent offset from kernel_base. Need further investigation.
value += r_addend
value &= (1 << 64) - 1
img[offset:offset+8] = pack('<Q', value)
count += 1
self.kernel_img = bytes(img)
print('[+] Successfully applied %d relocations.' % count)
logging.info('[+] Successfully applied %d relocations.' % count)
return True
@ -440,7 +442,7 @@ class KallsymsFinder:
self.kallsyms_token_table__offset = position
print('[+] Found kallsyms_token_table at file offset 0x%08x' % self.kallsyms_token_table__offset)
logging.info('[+] Found kallsyms_token_table at file offset 0x%08x' % self.kallsyms_token_table__offset)
def find_kallsyms_token_index(self):
@ -505,7 +507,7 @@ class KallsymsFinder:
self.kallsyms_token_index__offset = position + found_position_for_be_value
print('[+] Found kallsyms_token_index at file offset 0x%08x' % self.kallsyms_token_index__offset)
logging.info('[+] Found kallsyms_token_index at file offset 0x%08x' % self.kallsyms_token_index__offset)
def find_kallsyms_names_uncompressed(self):
@ -552,9 +554,9 @@ class KallsymsFinder:
raise KallsymsNotFoundException('No embedded symbol table found in this kernel')
print('[+] Kernel symbol names found at file offset', hex(ksymtab_match.start(0)))
logging.info('[+] Kernel symbol names found at file offset 0x%08x' % ksymtab_match.start(0))
print('[+] Found %d uncompressed kernel symbols (end at 0x%08x)' % (self.number_of_symbols, position))
logging.info('[+] Found %d uncompressed kernel symbols (end at 0x%08x)' % (self.number_of_symbols, position))
self.end_of_kallsyms_names_uncompressed = position
@ -645,7 +647,7 @@ class KallsymsFinder:
self.kallsyms_markers__offset = position
print('[+] Found kallsyms_markers at file offset 0x%08x' % position)
logging.info('[+] Found kallsyms_markers at file offset 0x%08x' % position)
def find_kallsyms_markers(self):
@ -734,7 +736,7 @@ class KallsymsFinder:
self.kallsyms_markers__offset = position
print('[+] Found kallsyms_markers at file offset 0x%08x' % position)
logging.info('[+] Found kallsyms_markers at file offset 0x%08x' % position)
def find_kallsyms_names(self):
@ -826,14 +828,14 @@ class KallsymsFinder:
else:
raise ValueError('Could not find kallsyms_names')
print('[+] Found kallsyms_names at file offset 0x%08x' % self.kallsyms_names__offset)
logging.info('[+] Found kallsyms_names at file offset 0x%08x' % self.kallsyms_names__offset)
position = (self.kallsyms_names__offset - MAX_ALIGNMENT - 20) + needle
self.kallsyms_num_syms__offset = position
print('[+] Found kallsyms_num_syms at file offset 0x%08x' % position)
logging.info('[+] Found kallsyms_num_syms at file offset 0x%08x' % position)
"""
This method defines self.kallsyms_addresses_or_offsets__offset,
@ -949,7 +951,7 @@ class KallsymsFinder:
if self.has_base_relative:
number_of_negative_items = len([offset for offset in tentative_addresses_or_offsets if offset < 0])
print('[i] Negative offsets overall: %g %%' % (number_of_negative_items / len(tentative_addresses_or_offsets) * 100))
logging.info('[i] Negative offsets overall: %g %%' % (number_of_negative_items / len(tentative_addresses_or_offsets) * 100))
if number_of_negative_items / len(tentative_addresses_or_offsets) >= 0.5: # Non-absolute symbols are negative with CONFIG_KALLSYMS_ABSOLUTE_PERCPU
self.has_absolute_percpu = True
@ -964,7 +966,7 @@ class KallsymsFinder:
number_of_null_items = len([address for address in tentative_addresses_or_offsets if address == 0])
print('[i] Null addresses overall: %g %%' % (number_of_null_items / len(tentative_addresses_or_offsets) * 100))
logging.info('[i] Null addresses overall: %g %%' % (number_of_null_items / len(tentative_addresses_or_offsets) * 100))
if number_of_null_items / len(tentative_addresses_or_offsets) >= 0.2: # If there are too much null symbols we have likely tried to parse the wrong integer size
@ -972,7 +974,7 @@ class KallsymsFinder:
continue
print('[+] Found %s at file offset 0x%08x' % ('kallsyms_offsets' if self.has_base_relative else 'kallsyms_addresses', position))
logging.info('[+] Found %s at file offset 0x%08x' % ('kallsyms_offsets' if self.has_base_relative else 'kallsyms_addresses', position))
self.kernel_addresses = tentative_addresses_or_offsets
@ -1067,24 +1069,25 @@ class KallsymsFinder:
symbol_types.add(symbol_name[0])
print('Symbol types', '=>', sorted(symbol_types))
print()
logging.info('Symbol types => %r' % sorted(symbol_types))
logging.info('')
# Print symbols, in a fashion similar to /proc/kallsyms
for symbol_address, symbol_name in zip(self.kernel_addresses, self.symbol_names):
print(
'%016x' % symbol_address if self.is_64_bits
else '%08x' % symbol_address,
logging.info( "{0:s} {1:s} {2:s}".format(
'%016x' % symbol_address if self.is_64_bits else '%08x' % symbol_address,
symbol_name[0], # The symbol type
symbol_name[1:] # The symbol name itself
)
))
if __name__ == '__main__':
logging.basicConfig(stream=stdout, level=logging.INFO, format='%(message)s')
args = ArgumentParser(description = "Find the kernel's embedded symbol table from a raw " +
"or stripped ELF kernel file, and print these to the standard output with their " +
"addresses")

View File

@ -4,8 +4,8 @@ from __future__ import absolute_import
from __future__ import print_function
from argparse import ArgumentParser
from io import BytesIO
from sys import argv
from sys import argv, stdout
import logging
try:
from vmlinuz_decompressor import obtain_raw_kernel_from_file
@ -18,6 +18,8 @@ except ImportError:
from vmlinux_to_elf.architecture_detecter import ArchitectureGuessError
if __name__ == '__main__':
logging.basicConfig(stream=stdout, level=logging.INFO, format='%(message)s')
args = ArgumentParser(description = 'Turn a raw or compressed kernel binary, ' +
'or a kernel ELF without symbols, into a fully analyzable ELF whose ' +
@ -49,7 +51,7 @@ if __name__ == '__main__':
if ((args.e_machine is not None and args.bit_size is None) or
(args.e_machine is None and args.bit_size is not None)):
print('[!] Please specify both an addressing bit size ' +
logging.error('[!] Please specify both an addressing bit size ' +
'and the ELF "e_machine" field, or neither for ' +
'auto-detection')

View File

@ -28,6 +28,8 @@ from os.path import dirname, realpath, exists
from traceback import print_exc
from os import makedirs
from re import sub
from sys import stdout
import logging
SCRIPT_DIR = dirname(realpath(__file__))
TEST_KERNELS_PATH = realpath(SCRIPT_DIR + '/test_kernels.txt')
@ -39,6 +41,8 @@ def slugify(file_path):
if __name__ == '__main__':
logging.basicConfig(stream=stdout, level=logging.INFO, format='%(message)s')
if not exists(TEST_KERNELS_PATH):
exit(('[!] In order to use this script, please ' +
@ -50,7 +54,7 @@ if __name__ == '__main__':
for file_name in filter(None, map(str.strip, open(TEST_KERNELS_PATH, 'r'))):
print('Testing ' + file_name)
logging.info('Testing ' + file_name)
with open(file_name, 'rb') as fd:
contents = fd.read()
@ -59,7 +63,7 @@ if __name__ == '__main__':
try:
ElfSymbolizer(raw_data, ELF_KERNELS_OUTPUT_PATH + '/' + slugify(file_name) + '.elf')
except Exception:
print('=> No symbols!')
logging.error('=> No symbols!')
print_exc()

0
utils/vmlinux_to_elf/utils/elf_tests/ls_arm32_le.elf Normal file → Executable file
View File

0
utils/vmlinux_to_elf/utils/elf_tests/ls_mips32_be.elf Normal file → Executable file
View File

0
utils/vmlinux_to_elf/utils/elf_tests/ls_mips32_le.elf Normal file → Executable file
View File

0
utils/vmlinux_to_elf/utils/elf_tests/ls_mips64_be.elf Normal file → Executable file
View File

0
utils/vmlinux_to_elf/utils/elf_tests/ls_renesas.elf Normal file → Executable file
View File

0
utils/vmlinux_to_elf/utils/elf_tests/ls_x64.elf Normal file → Executable file
View File

View File

@ -8,6 +8,7 @@ from struct import unpack
from typing import Union
from re import search
import importlib
import logging
"""
How to detect a vmlinuz file?
@ -133,10 +134,10 @@ def try_decompress_at(input_file : bytes, offset : int) -> bytes:
LZ4Decompressor = importlib.import_module('lz4.frame')
except ModuleNotFoundError:
print('ERROR: This kernel requres LZ4 decompression.')
print(' But "lz4" python package does not found.')
print(' Example installation command: "sudo pip3 install lz4"')
print()
logging.error('ERROR: This kernel requres LZ4 decompression.')
logging.error(' But "lz4" python package does not found.')
logging.error(' Example installation command: "sudo pip3 install lz4"')
logging.error()
return
context = LZ4Decompressor.create_decompression_context()
@ -146,7 +147,7 @@ def try_decompress_at(input_file : bytes, offset : int) -> bytes:
pass
if decoded and len(decoded) > 0x1000:
print(('[+] Kernel successfully decompressed in-memory (the offsets that ' +
logging.info(('[+] Kernel successfully decompressed in-memory (the offsets that ' +
'follow will be given relative to the decompressed binary)'))
return decoded