def decodeKernelAddress(self, cpu, virt): ''' not yet working? ''' pg_dir_ptr_table_base_addr = (self.PML4_entry * 8) + self.cr3[cpu] pdpte_offset = memUtils.bitRange(virt, 30, 38) pdpte_addr = pg_dir_ptr_table_base_addr + (pdpte_offset * memUtils.MACHINE_WORD_SIZE) self.lgr.debug('watchKernel, decode virt 0x%x ' % (virt)) self.lgr.debug( 'watchKernel, decode cr3 is %x pg_dir_ptr_table_base_addr 0x%x ' % (self.cr3[cpu], pg_dir_ptr_table_base_addr)) self.lgr.debug('watchKernel, decode pdpte_offset: %x addr: %x' % (pdpte_offset, pdpte_addr)) page_dir_base = self.get40(cpu, pdpte_addr) pd_offset = memUtils.bitRange(virt, 21, 29) page_dir_address = page_dir_base + (pd_offset * memUtils.MACHINE_WORD_SIZE) self.lgr.debug('watchKernel, decode pd_offset: %x addr: %x' % (pd_offset, page_dir_address)) page_table_base = self.get40(cpu, page_dir_address) pt_offset = memUtils.bitRange(virt, 12, 20) page_table_addr = page_table_base + (pt_offset * memUtils.MACHINE_WORD_SIZE) self.lgr.debug('watchKernel, decode pt_offset: %x addr: %x' % (pt_offset, page_table_addr)) page_table_entry = self.get40(cpu, page_table_addr) pg_offset = memUtils.bitRange(virt, 0, 11) retval = page_table_entry + pg_offset self.lgr.debug('watchKernel, decode offsest 0x%x to 0x%x' % (pg_offset, retval)) return retval
def findPageTable(cpu, addr, lgr, use_sld=None): if cpu.architecture == 'arm': return findPageTableArm(cpu, addr, lgr, use_sld) elif isIA32E(cpu): lgr.debug('findPageTable is IA32E') return findPageTableIA32E(cpu, addr, lgr) else: #lgr.debug('findPageTable not IA32E') ptable_info = PtableInfo() reg_num = cpu.iface.int_register.get_number("cr3") cr3 = cpu.iface.int_register.read(reg_num) reg_num = cpu.iface.int_register.get_number("cr4") cr4 = cpu.iface.int_register.read(reg_num) ''' determine if PAE being used ''' addr_extend = memUtils.testBit(cr4, 5) #print('addr_extend is %d' % addr_extend) if addr_extend == 0: ''' Traditional page table. ''' offset = memUtils.bitRange(addr, 0, 11) ptable = memUtils.bitRange(addr, 12, 21) pdir = memUtils.bitRange(addr, 22, 31) #lgr.debug('traditional paging addr 0x%x pdir: 0x%x ptable: 0x%x offset 0x%x ' % (addr, pdir, ptable, offset)) pdir_entry_addr = cr3 + (pdir * 4) #lgr.debug('cr3: 0x%x pdir_entry_addr: 0x%x' % (cr3, pdir_entry_addr)) ptable_info.pdir_addr = pdir_entry_addr pdir_entry = SIM_read_phys_memory(cpu, pdir_entry_addr, 4) if pdir_entry == 0: return ptable_info ptable_info.ptable_protect = memUtils.testBit(pdir_entry, 2) ptable_info.ptable_exists = True pdir_entry_20 = memUtils.bitRange(pdir_entry, 12, 31) ptable_base = pdir_entry_20 * PAGE_SIZE #lgr.debug('pdir_entry: 0x%x 20 0x%x ptable_base: 0x%x' % (pdir_entry, pdir_entry_20, ptable_base)) ptable_entry_addr = ptable_base + (4 * ptable) ptable_info.ptable_addr = ptable_entry_addr if use_sld is not None: entry = use_sld else: entry = SIM_read_phys_memory(cpu, ptable_entry_addr, 4) #lgr.debug('ptable_entry_addr is 0x%x, page table entry contains 0x%x' % (ptable_entry_addr, entry)) if entry == 0: return ptable_info ptable_info.page_protect = memUtils.testBit(entry, 2) ptable_info.page_exists = True entry_20 = memUtils.bitRange(entry, 12, 31) page_base = entry_20 * PAGE_SIZE paddr = page_base + offset ptable_info.page_addr = paddr #lgr.debug('phys addr is 0x%x' % paddr) return ptable_info else: #lgr.debug('call findPageTableExtend') return findPageTableExtended(cpu, addr, lgr)
def findPageTableExtended(cpu, addr, lgr): WORD_SIZE = 8 mask64 = 0x000ffffffffff000 ptable_info = PtableInfo() ptable_info.entry_size = WORD_SIZE reg_num = cpu.iface.int_register.get_number("cr3") cr3 = cpu.iface.int_register.read(reg_num) reg_num = cpu.iface.int_register.get_number("cr4") cr4 = cpu.iface.int_register.read(reg_num) ''' determine if PAE being used ''' addr_extend = memUtils.testBit(cr4, 5) #print('addr_extend is %d' % addr_extend) if addr_extend != 0: ''' Extended page table. ''' offset = memUtils.bitRange(addr, 0,11) ptable = memUtils.bitRange(addr, 12,20) pdir = memUtils.bitRange(addr, 21,29) pdir_pointer_table = memUtils.bitRange(addr, 30,31) dir_ptr_entry_addr = cr3 + WORD_SIZE * pdir_pointer_table dir_ptr_entry = SIM_read_phys_memory(cpu, dir_ptr_entry_addr, WORD_SIZE) dir_ptr_entry_addr = dir_ptr_entry & mask64 pdir_entry_addr = dir_ptr_entry_addr + (pdir * WORD_SIZE) ptable_info.pdir_addr = pdir_entry_addr pdir_entry = SIM_read_phys_memory(cpu, pdir_entry_addr, WORD_SIZE) if pdir_entry == 0: return ptable_info ptable_info.ptable_protect = memUtils.testBit(pdir_entry, 2) ptable_info.ptable_exists = True pdir_entry_24 = pdir_entry & mask64 ptable_base = pdir_entry_24 lgr.debug('pdir_entry: 0x%x 24 0x%x ptable_base: 0x%x' % (pdir_entry, pdir_entry_24, ptable_base)) ptable_entry_addr = ptable_base + (WORD_SIZE*ptable) lgr.debug('ptable_entry_addr 0x%x ptable 0x%x' % (ptable_entry_addr, ptable_base)) ptable_info.ptable_addr = ptable_entry_addr entry = SIM_read_phys_memory(cpu, ptable_entry_addr, WORD_SIZE) lgr.debug('ptable_entry_addr is 0x%x, page table entry contains 0x%x' % (ptable_entry_addr, entry)) if entry == 0: return ptable_info ptable_info.page_protect = memUtils.testBit(entry, 2) ptable_info.page_exists = True entry_24 = entry & mask64 page_base = entry_24 paddr = page_base + offset ptable_info.page_addr = paddr #lgr.debug('phys addr is 0x%x' % paddr) return ptable_info else: lgr.error('addr_extended is zero?')
def findPageTableIA32E(cpu, addr, lgr): ''' IA32E: CR3 is base address of the PML4 table, which is 512 entries, of 64bits per entry. Bits 47:39 of an address select the entry in the PML4 table. ''' ptable_info = PtableInfo() #lgr.debug('findPageTableIA32E addr 0x%x' % addr) reg_num = cpu.iface.int_register.get_number("cr3") cr3 = cpu.iface.int_register.read(reg_num) pml4_entry = memUtils.bitRange(addr, 39, 47) cr3_40 = memUtils.bitRange(cr3, 12, 50) << 12 #lgr.debug('cr3 is 0x%x cr3_40 0x%x pl4_entry %d' % (cr3, cr3_40, pml4_entry)) dir_ptr_base_addr = (pml4_entry * 8) + cr3_40 #lgr.debug('dir_ptr_base_addr 0x%x' % dir_ptr_base_addr) dir_ptr_base, present, page_size = get40(cpu, dir_ptr_base_addr, lgr) #lgr.debug('dir_ptr_base is 0x%x present %d page_size 0x%x' % (dir_ptr_base, present, page_size)) dir_ptr_entry = memUtils.bitRange(addr, 30, 38) #lgr.debug('dir_ptr_entry is %d' % dir_ptr_entry) dir_base_addr = dir_ptr_base + (dir_ptr_entry * 8) #lgr.debug('dir_base_addr 0x%x' % dir_base_addr) ptable_info.pdir_addr = dir_base_addr dir_base, present, page_size = get40(cpu, dir_base_addr, lgr) #lgr.debug('dir_base 0x%x present %d page_size 0x%x' % (dir_base, present, page_size)) if dir_base == 0: return ptable_info else: dir_entry = memUtils.bitRange(addr, 21, 29) lgr.debug('dir_entry %d' % dir_entry) table_base_addr = dir_base + (dir_entry * 8) #lgr.debug('table_base_addr 0x%x' % table_base_addr) ptable_info.table_addr = table_base_addr table_base, present, page_size = get40(cpu, table_base_addr, lgr) if table_base == 0: #lgr.debug('table_base could not be read from 0x%x' % table_base_addr) return ptable_info else: #lgr.debug('table_base 0x%x' % table_base) ptable_info.ptable_exists = present table_entry = memUtils.bitRange(addr, 12, 20) page_base_addr = table_base + (table_entry * 8) #lgr.debug('page_base_addr 0x%x ' % (page_base_addr)) page_base, present, page_size = get40(cpu, page_base_addr, lgr) #lgr.debug('page_base 0x%x present %d' % (page_base, present)) ptable_info.page_addr = page_base_addr ptable_info.page_exists = present return ptable_info
def get40(self, cpu, addr): try: value = SIM_read_phys_memory(cpu, addr, 8) except: self.lgr.error('nothing mapped at 0x%x' % addr) return 0 retval = memUtils.bitRange(value, 0, 39) return retval
def get40(cpu, addr, lgr): try: value = SIM_read_phys_memory(cpu, addr, 8) except: lgr.debug('nothing mapped at 0x%x' % addr) return 0, 0, 0 retval = memUtils.bitRange(value, 12, 50) << 12 page_size = memUtils.testBit(value, 7) present = memUtils.testBit(value, 0) return retval, present, page_size
def initPageDirIA32E(self, cpu, cr3): ''' IA32E: CR3 is base address of the PML4 table, which is 512 entries, of 64bits per entry. Bits 47:39 of an address select the entry in the PML4 table. ''' cell_name = self.top.getTopComponentName(cpu) kbase = self.param[cell_name].kernel_base self.PML4_entry = memUtils.bitRange(kbase, 39, 47) self.lgr.debug('initPageDirIA3E, PML4_entry is %x from kbase 0x%x' % (self.PML4_entry, kbase))
def getPageBasesExtended(cpu, lgr, kernel_base): ENTRIES_PER_TABLE = 512 WORD_SIZE = 8 retval = [] reg_num = cpu.iface.int_register.get_number("cr3") cr3 = cpu.iface.int_register.read(reg_num) page_table_directory = cr3 pdir_index = 0 for pdir_table_index in range(4): pdir_entry_addr = SIM_read_phys_memory(cpu, page_table_directory, 8) for i in range(ENTRIES_PER_TABLE): pdir_entry = SIM_read_phys_memory(cpu, pdir_entry_addr, WORD_SIZE) pdir_entry_20 = memUtils.bitRange(pdir_entry, 12, 31) ptable_base = pdir_entry_20 * PAGE_SIZE if pdir_entry != 0: ptable_entry_addr = ptable_base ptable_index = 0 for j in range(ENTRIES_PER_TABLE): ptable_entry = SIM_read_phys_memory( cpu, ptable_entry_addr, WORD_SIZE) present = memUtils.testBit(ptable_entry, 0) if present: entry_20 = memUtils.bitRange(ptable_entry, 12, 31) page_base = entry_20 * PAGE_SIZE logical = 0 logical = memUtils.setBitRange(logical, pdir_index, 22) #lgr.debug('logical now 0x%x from index %d' % (logical, pdir_index)) logical = memUtils.setBitRange(logical, ptable_index, 12) if logical >= kernel_base: break #lgr.debug('logical now 0x%x from ptable index %d' % (logical, ptable_index)) addr_info = PageAddrInfo(logical, page_base, ptable_entry) retval.append(addr_info) ptable_entry_addr += WORD_SIZE ptable_index += 1 pdir_entry_addr += WORD_SIZE pdir_index += 1 page_table_directory += WORD_SIZE return retval
def findPageTableArm(cpu, va, lgr, use_sld=None): ptable_info = PtableInfo() ttbr = cpu.translation_table_base0 base = memUtils.bitRange(ttbr, 14, 31) base_shifted = base << 14 first_index = memUtils.bitRange(va, 20, 31) first_shifted = first_index << 2 first_addr = base_shifted | first_shifted ptable_info.pdir_addr = first_addr #lgr.debug('findPageTableArm first_index 0x%x ndex_shifted 0x%x addr 0x%x' % (first_index, first_shifted, first_addr)) fld = SIM_read_phys_memory(cpu, first_addr, 4) if fld == 0: return ptable_info #ptable_info.ptable_protect = memUtils.testBit(fld, 2) ptable_info.ptable_exists = True pta = memUtils.bitRange(fld, 10, 31) pta_shifted = pta << 10 #print('fld 0x%x pta 0x%x pta_shift 0x%x' % (fld, pta, pta_shifted)) second_index = memUtils.bitRange(va, 12, 19) second_shifted = second_index << 2 second_addr = pta_shifted | second_shifted ptable_info.ptable_addr = second_addr sld = SIM_read_phys_memory(cpu, second_addr, 4) #print('sld 0x%x second_index 0x%x second_shifted 0x%x second_addr 0x%x' % (sld, second_index, second_shifted, second_addr)) if use_sld is None: if sld == 0: return ptable_info else: sld = use_sld #ptable_info.page_protect = memUtils.testBit(sld, 2) ptable_info.page_exists = True small_page_base = memUtils.bitRange(sld, 12, 31) s_shifted = small_page_base << 12 ptable_info.page_addr = s_shifted ptable_info.nx = memUtils.testBit(sld, 0) ptable_info.entry = sld return ptable_info
def __init__(self, entry, arch): if arch != 'arm': self.writable = memUtils.testBit(entry, 1) self.accessed = memUtils.testBit(entry, 5) else: self.nx = memUtils.testBit(entry, 0) ap = memUtils.bitRange(entry, 4, 5) self.accessed = True self.writable = False if ap == 1 or ap == 0: self.accessed = False self.writable = False if ap == 3: self.writable = True
def getPageBases(cpu, lgr, kernel_base): if cpu.architecture == 'arm': return getPageBasesArm(cpu, lgr, kernel_base) ENTRIES_PER_TABLE = 1024 retval = [] reg_num = cpu.iface.int_register.get_number("cr3") cr3 = cpu.iface.int_register.read(reg_num) pdir_entry_addr = cr3 pdir_index = 0 for i in range(ENTRIES_PER_TABLE): pdir_entry = SIM_read_phys_memory(cpu, pdir_entry_addr, 4) pdir_entry_20 = memUtils.bitRange(pdir_entry, 12, 31) ptable_base = pdir_entry_20 * PAGE_SIZE if pdir_entry != 0: ptable_entry_addr = ptable_base ptable_index = 0 for j in range(ENTRIES_PER_TABLE): ptable_entry = SIM_read_phys_memory(cpu, ptable_entry_addr, 4) present = memUtils.testBit(ptable_entry, 0) if present: entry_20 = memUtils.bitRange(ptable_entry, 12, 31) page_base = entry_20 * PAGE_SIZE logical = 0 logical = memUtils.setBitRange(logical, pdir_index, 22) #lgr.debug('logical now 0x%x from index %d' % (logical, pdir_index)) logical = memUtils.setBitRange(logical, ptable_index, 12) if logical >= kernel_base: break #lgr.debug('logical now 0x%x from ptable index %d' % (logical, ptable_index)) addr_info = PageAddrInfo(logical, page_base, ptable_entry) retval.append(addr_info) ptable_entry_addr += 4 ptable_index += 1 pdir_entry_addr += 4 pdir_index += 1 return retval
def getPageBasesArm(cpu, lgr, kernel_base): retval = [] ttbr = cpu.translation_table_base0 #print('ttbr is 0x%x' % ttbr) base = memUtils.bitRange(ttbr, 14, 31) base_shifted = base << 14 #print('base is 0x%x, shifted 0x%x' % (base, base_shifted)) NUM_FIRST = 4096 NUM_SECOND = 256 first_index = 0 kernel_base = 0xc0000000 for i in range(NUM_FIRST): first_addr = base_shifted | first_index * 4 fld = SIM_read_phys_memory(cpu, first_addr, 4) if fld != 0: pta = memUtils.bitRange(fld, 10, 31) pta_shifted = pta << 10 second_index = 0 for j in range(NUM_SECOND): va = first_index << 20 va = va | (second_index << 12) if va > kernel_base: break second_addr = pta_shifted | second_index * 4 sld = SIM_read_phys_memory(cpu, second_addr, 4) db = memUtils.bitRange(sld, 0, 1) if db != 0: pbase = memUtils.bitRange(sld, 12, 31) pbase_shifted = pbase << 12 #print('va: 0x%x page base 0x%x' % (va, pbase_shifted)) addr_info = PageAddrInfo(va, pbase_shifted, sld) retval.append(addr_info) second_index += 1 first_index += 1 return retval