diff --git a/linux-ramdump-parser-v2/ramdump.py b/linux-ramdump-parser-v2/ramdump.py index 34bb0a087028fdd34a29657d8f0ca8865851efca..afc974ca585b7180f3a2a83b6e24c6ed0e1faa33 100644 --- a/linux-ramdump-parser-v2/ramdump.py +++ b/linux-ramdump-parser-v2/ramdump.py @@ -1263,13 +1263,33 @@ class RamDump(): symbols = stream.readlines() kaslr = self.get_kaslr_offset() + # The beginning and ending of kernel image, from vmlinux.lds.S + _text = self.address_of('_text') + if _text is None: + _text = 0 + + _end = self.address_of('_end') + if _end is None: + _end = 0xFFFFFFFFFFFFFFFF + for line in symbols: s = line.split(' ') - if len(s) == 3: - self.lookup_table.append((int(s[0], 16) + kaslr, - s[2].rstrip())) + if len(s) != 3: + continue + + entry = (int(s[0], 16) + kaslr, s[2].rstrip()) + + # The symbol file contains many artificial symbols which we don't care about. + if entry[0] < _text or entry[0] >= _end: + continue + + self.lookup_table.append(entry) stream.close() + if not len(self.lookup_table): + print_out_str('!!! Unable to retrieve symbols... Exiting') + sys.exit(1) + def retrieve_modules(self): mod_list = self.address_of('modules') next_offset = self.field_offset('struct list_head', 'next') @@ -1398,36 +1418,49 @@ class RamDump(): pass def unwind_lookup(self, addr, symbol_size=0): - if (addr is None): - return ('(Invalid address)', 0x0) + """ + Returns closest symbols <= addr and either the relative offset + or the symbol size. + + The loop constant is: + table[low] <= addr <= table[high] + """ + table = self.lookup_table low = 0 - high = len(self.lookup_table) - # Python now complains about division producing floats - mid = (low + high) >> 1 - premid = 0 + high = len(self.lookup_table) - 1 - while(not(addr >= self.lookup_table[mid][0] and addr < self.lookup_table[mid + 1][0])): + if addr is None or addr < table[low][0] or addr > table[high][0]: + return None - if(addr < self.lookup_table[mid][0]): - high = mid - 1 + while(True): + # Python now complains about division producing floats + mid = (high + low) >> 1 - if(addr > self.lookup_table[mid][0]): - low = mid + 1 + if mid == low or mid == high: + break - mid = (high + low) >> 1 + if addr <= table[mid][0]: + high = mid + elif addr >= table[mid][0]: + low = mid - if(mid == premid): - return None - if (mid + 1) >= len(self.lookup_table) or mid < 0: - return None + if addr == table[low][0]: + high = low + elif addr == table[high][0]: + low = high - premid = mid + offset = addr - table[low][0] + #how to calculate size for the last symbol? + if low == len(self.lookup_table) - 1: + size = 0 + else: + size = table[low + 1][0] - table[low][0] if symbol_size == 0: - return (self.lookup_table[mid][1], addr - self.lookup_table[mid][0]) + return (table[low][1], offset) else: - return (self.lookup_table[mid][1], self.lookup_table[mid + 1][0] - self.lookup_table[mid][0]) + return (table[low][1], size) def read_physical(self, addr, length): if self.minidump: