1#------------------------------------------------------------------------------ 2# elftools tests 3# 4# Maxim Akhmedov (max42@yandex-team.ru) 5# This code is in the public domain 6#------------------------------------------------------------------------------ 7import unittest 8import os 9 10from elftools.elf.elffile import ELFFile 11from elftools.elf.segments import NoteSegment 12 13 14class TestCoreNotes(unittest.TestCase): 15 """ This test makes sure than core dump specific 16 sections are properly analyzed. 17 """ 18 @classmethod 19 def setUpClass(cls): 20 cls._core_file = open(os.path.join('test', 21 'testfiles_for_unittests', 'core_linux64.elf'), 22 'rb') 23 24 def test_core_prpsinfo(self): 25 elf = ELFFile(self._core_file) 26 for segment in elf.iter_segments(): 27 if not isinstance(segment, NoteSegment): 28 continue 29 notes = list(segment.iter_notes()) 30 for note in segment.iter_notes(): 31 if note['n_type'] != 'NT_PRPSINFO': 32 continue 33 desc = note['n_desc'] 34 self.assertEqual(desc['pr_state'], 0) 35 self.assertEqual(desc['pr_sname'], b'R') 36 self.assertEqual(desc['pr_zomb'], 0) 37 self.assertEqual(desc['pr_nice'], 0) 38 self.assertEqual(desc['pr_flag'], 0x400600) 39 self.assertEqual(desc['pr_uid'], 1000) 40 self.assertEqual(desc['pr_gid'], 1000) 41 self.assertEqual(desc['pr_pid'], 23395) 42 self.assertEqual(desc['pr_ppid'], 23187) 43 self.assertEqual(desc['pr_pgrp'], 23395) 44 self.assertEqual(desc['pr_sid'], 23187) 45 self.assertEqual( 46 desc['pr_fname'], 47 b'coredump_self\x00\x00\x00') 48 self.assertEqual( 49 desc['pr_psargs'], 50 b'./coredump_self foo bar 42 ' + b'\x00' * (80 - 27)) 51 52 def test_core_nt_file(self): 53 """ 54 Test that the parsing of the NT_FILE note within a core file is 55 correct. 56 The assertions are made against the output of eu-readelf. 57 58 eu-readelf -n core_linux64.elf 59 ... 60 CORE 621 FILE 61 10 files: 62 00400000-00401000 00000000 4096 63 /home/max42/pyelftools/test/coredump_self 64 00600000-00601000 00000000 4096 65 /home/max42/pyelftools/test/coredump_self 66 00601000-00602000 00001000 4096 67 /home/max42/pyelftools/test/coredump_self 68 7fa4593ae000-7fa45956d000 00000000 1830912 69 /lib/x86_64-linux-gnu/libc-2.23.so 70 7fa45956d000-7fa45976d000 001bf000 2097152 71 /lib/x86_64-linux-gnu/libc-2.23.so 72 7fa45976d000-7fa459771000 001bf000 16384 73 /lib/x86_64-linux-gnu/libc-2.23.so 74 7fa459771000-7fa459773000 001c3000 8192 75 /lib/x86_64-linux-gnu/libc-2.23.so 76 7fa459777000-7fa45979d000 00000000 155648 77 /lib/x86_64-linux-gnu/ld-2.23.so 78 7fa45999c000-7fa45999d000 00025000 4096 79 /lib/x86_64-linux-gnu/ld-2.23.so 80 7fa45999d000-7fa45999e000 00026000 4096 81 /lib/x86_64-linux-gnu/ld-2.23.so 82 ... 83 """ 84 elf = ELFFile(self._core_file) 85 nt_file_found = False 86 for segment in elf.iter_segments(): 87 if not isinstance(segment, NoteSegment): 88 continue 89 for note in segment.iter_notes(): 90 if note['n_type'] != 'NT_FILE': 91 continue 92 nt_file_found = True 93 desc = note['n_desc'] 94 self.assertEqual(desc['num_map_entries'], 10) 95 self.assertEqual(desc['page_size'], 4096) 96 self.assertEqual(len(desc['Elf_Nt_File_Entry']), 10) 97 self.assertEqual(len(desc['filename']), 10) 98 99 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][0], 100 desc['page_size'], 101 0x00400000, 102 0x00401000, 103 0x00000000) 104 self.assertEqual(desc['filename'][0], 105 b"/home/max42/pyelftools/test/coredump_self") 106 107 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][1], 108 desc['page_size'], 109 0x00600000, 110 0x00601000, 111 0x00000000) 112 self.assertEqual(desc['filename'][1], 113 b"/home/max42/pyelftools/test/coredump_self") 114 115 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][2], 116 desc['page_size'], 117 0x00601000, 118 0x00602000, 119 0x00001000) 120 self.assertEqual(desc['filename'][2], 121 b"/home/max42/pyelftools/test/coredump_self") 122 123 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][3], 124 desc['page_size'], 125 0x7fa4593ae000, 126 0x7fa45956d000, 127 0x00000000) 128 self.assertEqual(desc['filename'][3], 129 b"/lib/x86_64-linux-gnu/libc-2.23.so") 130 131 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][4], 132 desc['page_size'], 133 0x7fa45956d000, 134 0x7fa45976d000, 135 0x001bf000) 136 self.assertEqual(desc['filename'][4], 137 b"/lib/x86_64-linux-gnu/libc-2.23.so") 138 139 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][5], 140 desc['page_size'], 141 0x7fa45976d000, 142 0x7fa459771000, 143 0x001bf000) 144 self.assertEqual(desc['filename'][5], 145 b"/lib/x86_64-linux-gnu/libc-2.23.so") 146 147 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][6], 148 desc['page_size'], 149 0x7fa459771000, 150 0x7fa459773000, 151 0x001c3000) 152 self.assertEqual(desc['filename'][6], 153 b"/lib/x86_64-linux-gnu/libc-2.23.so") 154 155 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][7], 156 desc['page_size'], 157 0x7fa459777000, 158 0x7fa45979d000, 159 0x00000000) 160 self.assertEqual(desc['filename'][7], 161 b"/lib/x86_64-linux-gnu/ld-2.23.so") 162 163 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][8], 164 desc['page_size'], 165 0x7fa45999c000, 166 0x7fa45999d000, 167 0x00025000) 168 self.assertEqual(desc['filename'][8], 169 b"/lib/x86_64-linux-gnu/ld-2.23.so") 170 171 self.validate_nt_file_entry(desc['Elf_Nt_File_Entry'][9], 172 desc['page_size'], 173 0x7fa45999d000, 174 0x7fa45999e000, 175 0x00026000) 176 self.assertEqual(desc['filename'][9], 177 b"/lib/x86_64-linux-gnu/ld-2.23.so") 178 self.assertTrue(nt_file_found) 179 180 def validate_nt_file_entry(self, 181 entry, 182 page_size, 183 expected_vm_start, 184 expected_vm_end, 185 expected_page_offset): 186 self.assertEqual(entry.vm_start, expected_vm_start) 187 self.assertEqual(entry.vm_end, expected_vm_end) 188 self.assertEqual(entry.page_offset * page_size, expected_page_offset) 189 190 @classmethod 191 def tearDownClass(cls): 192 cls._core_file.close() 193