Minor Update: vmlinux-to-elf updated
Signed-off-by: rokibhasansagar <rokibhasansagar2014@outlook.com>
This commit is contained in:
parent
3721b32cc8
commit
e63053f84f
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue