1*c54f35caSApple OSS Distributionsfrom __future__ import absolute_import, division, print_function 2*c54f35caSApple OSS Distributions 3*c54f35caSApple OSS Distributionsfrom builtins import range 4*c54f35caSApple OSS Distributionsfrom builtins import object 5*c54f35caSApple OSS Distributions 6*c54f35caSApple OSS Distributionsimport six 7*c54f35caSApple OSS Distributionsimport struct 8*c54f35caSApple OSS Distributions 9*c54f35caSApple OSS Distributionsfrom core import ( 10*c54f35caSApple OSS Distributions gettype, 11*c54f35caSApple OSS Distributions xnu_format, 12*c54f35caSApple OSS Distributions SBValueFormatter, 13*c54f35caSApple OSS Distributions) 14*c54f35caSApple OSS Distributionsfrom core.collections import ( 15*c54f35caSApple OSS Distributions RB_HEAD, 16*c54f35caSApple OSS Distributions) 17*c54f35caSApple OSS Distributions 18*c54f35caSApple OSS Distributionsfrom .kmem import MemoryRange 19*c54f35caSApple OSS Distributionsfrom .btlog import BTLog, BTLibrary 20*c54f35caSApple OSS Distributionsfrom .whatis import * 21*c54f35caSApple OSS Distributions 22*c54f35caSApple OSS Distributions 23*c54f35caSApple OSS Distributions@SBValueFormatter.converter("vm_prot") 24*c54f35caSApple OSS Distributionsdef vm_prot_converter(prot): 25*c54f35caSApple OSS Distributions PROT_STR = "-rw?x" 26*c54f35caSApple OSS Distributions return PROT_STR[prot & 1] + PROT_STR[prot & 2] + PROT_STR[prot & 4] 27*c54f35caSApple OSS Distributions 28*c54f35caSApple OSS Distributions 29*c54f35caSApple OSS Distributionsclass VMMap(object): 30*c54f35caSApple OSS Distributions """ Helper class to manipulate a vm_map_t """ 31*c54f35caSApple OSS Distributions 32*c54f35caSApple OSS Distributions def __init__(self, vm_map): 33*c54f35caSApple OSS Distributions self.sbv = vm_map 34*c54f35caSApple OSS Distributions self.rb = RB_HEAD( 35*c54f35caSApple OSS Distributions vm_map.chkGetValueForExpressionPath(".hdr.rb_head_store"), 36*c54f35caSApple OSS Distributions "entry", 37*c54f35caSApple OSS Distributions self.entry_compare 38*c54f35caSApple OSS Distributions ) 39*c54f35caSApple OSS Distributions 40*c54f35caSApple OSS Distributions vme_type = gettype('struct vm_map_entry') 41*c54f35caSApple OSS Distributions self.to_entry = vme_type.xContainerOfTransform('store') 42*c54f35caSApple OSS Distributions 43*c54f35caSApple OSS Distributions def entry_compare(self, rb_entry, address): 44*c54f35caSApple OSS Distributions vme = self.to_entry(rb_entry) 45*c54f35caSApple OSS Distributions 46*c54f35caSApple OSS Distributions if vme.xGetScalarByPath(".links.end") <= address: 47*c54f35caSApple OSS Distributions return 1 48*c54f35caSApple OSS Distributions if address < vme.xGetScalarByPath(".links.start"): 49*c54f35caSApple OSS Distributions return -1 50*c54f35caSApple OSS Distributions return 0 51*c54f35caSApple OSS Distributions 52*c54f35caSApple OSS Distributions def find(self, address): 53*c54f35caSApple OSS Distributions ent = self.rb.find(address) 54*c54f35caSApple OSS Distributions return self.to_entry(ent) if ent else None 55*c54f35caSApple OSS Distributions 56*c54f35caSApple OSS Distributions def describe(self, verbose=False): 57*c54f35caSApple OSS Distributions fmt = ( 58*c54f35caSApple OSS Distributions "VM Map Info\n" 59*c54f35caSApple OSS Distributions " vm map : {&v:#x} \n" 60*c54f35caSApple OSS Distributions " pmap : {$v.pmap:#x} \n" 61*c54f35caSApple OSS Distributions " vm size : {$v.size|human_size} ({$v.size:,d} bytes) \n" 62*c54f35caSApple OSS Distributions " entries : {$v.hdr.nentries} \n" 63*c54f35caSApple OSS Distributions " map range : " 64*c54f35caSApple OSS Distributions "{$v.hdr.links.start:#x} - {$v.hdr.links.end:#x}\n" 65*c54f35caSApple OSS Distributions " map pgshift : {$v.hdr.page_shift}\n" 66*c54f35caSApple OSS Distributions ) 67*c54f35caSApple OSS Distributions print(xnu_format(fmt, self, v=self.sbv)) 68*c54f35caSApple OSS Distributions 69*c54f35caSApple OSS Distributions 70*c54f35caSApple OSS Distributionsclass VMMapEntry(MemoryObject): 71*c54f35caSApple OSS Distributions """ Memory Object for a kernel map memory entry """ 72*c54f35caSApple OSS Distributions 73*c54f35caSApple OSS Distributions MO_KIND = "kernel map entry" 74*c54f35caSApple OSS Distributions 75*c54f35caSApple OSS Distributions def __init__(self, kmem, address, vm_map): 76*c54f35caSApple OSS Distributions super(VMMapEntry, self).__init__(kmem, address) 77*c54f35caSApple OSS Distributions self.vm_map = vm_map 78*c54f35caSApple OSS Distributions self.sbv = vm_map.find(address) 79*c54f35caSApple OSS Distributions 80*c54f35caSApple OSS Distributions @property 81*c54f35caSApple OSS Distributions def object_range(self): 82*c54f35caSApple OSS Distributions sbv = self.sbv 83*c54f35caSApple OSS Distributions if sbv: 84*c54f35caSApple OSS Distributions return MemoryRange( 85*c54f35caSApple OSS Distributions sbv.xGetScalarByPath('.links.start'), 86*c54f35caSApple OSS Distributions sbv.xGetScalarByPath('.links.end') 87*c54f35caSApple OSS Distributions ) 88*c54f35caSApple OSS Distributions 89*c54f35caSApple OSS Distributions base = self.address & ~self.kmem.page_mask 90*c54f35caSApple OSS Distributions return MemoryRange(base, base + self.kmem.page_size) 91*c54f35caSApple OSS Distributions 92*c54f35caSApple OSS Distributions @property 93*c54f35caSApple OSS Distributions def vme_offset(self): 94*c54f35caSApple OSS Distributions return self.sbv.xGetScalarByName('vme_offset') << 12 95*c54f35caSApple OSS Distributions 96*c54f35caSApple OSS Distributions @property 97*c54f35caSApple OSS Distributions def vme_object_type(self): 98*c54f35caSApple OSS Distributions sbv = self.sbv 99*c54f35caSApple OSS Distributions if sbv.xGetScalarByName('is_sub_map'): 100*c54f35caSApple OSS Distributions return "submap" 101*c54f35caSApple OSS Distributions if sbv.xGetScalarByName('vme_kernel_object'): 102*c54f35caSApple OSS Distributions return "kobject" 103*c54f35caSApple OSS Distributions return "vm object" 104*c54f35caSApple OSS Distributions 105*c54f35caSApple OSS Distributions @property 106*c54f35caSApple OSS Distributions def vme_object(self): 107*c54f35caSApple OSS Distributions kmem = self.kmem 108*c54f35caSApple OSS Distributions sbv = self.sbv 109*c54f35caSApple OSS Distributions 110*c54f35caSApple OSS Distributions if sbv.xGetScalarByName('is_sub_map'): 111*c54f35caSApple OSS Distributions addr = sbv.xGetScalarByName('vme_submap') << 2 112*c54f35caSApple OSS Distributions return (addr, kmem.vm_map_type) 113*c54f35caSApple OSS Distributions 114*c54f35caSApple OSS Distributions if sbv.xGetScalarByName('vme_kernel_object'): 115*c54f35caSApple OSS Distributions return (kmem.vm_kobject.GetLoadAddress(), kmem.vmo_type) 116*c54f35caSApple OSS Distributions 117*c54f35caSApple OSS Distributions packed = sbv.xGetScalarByName('vme_object_or_delta') 118*c54f35caSApple OSS Distributions addr = kmem.vm_page_packing.unpack(packed) 119*c54f35caSApple OSS Distributions return (addr, kmem.vmo_type) 120*c54f35caSApple OSS Distributions 121*c54f35caSApple OSS Distributions @property 122*c54f35caSApple OSS Distributions def pages(self): 123*c54f35caSApple OSS Distributions return self.object_range.size >> self.kmem.page_shift 124*c54f35caSApple OSS Distributions 125*c54f35caSApple OSS Distributions def describe(self, verbose=False): 126*c54f35caSApple OSS Distributions 127*c54f35caSApple OSS Distributions self.vm_map.describe() 128*c54f35caSApple OSS Distributions 129*c54f35caSApple OSS Distributions if not self.sbv: 130*c54f35caSApple OSS Distributions fmt = ( 131*c54f35caSApple OSS Distributions "Kernel Map Entry Info\n" 132*c54f35caSApple OSS Distributions " No memory mapped at this address\n" 133*c54f35caSApple OSS Distributions ) 134*c54f35caSApple OSS Distributions print(xnu_format(fmt)) 135*c54f35caSApple OSS Distributions return 136*c54f35caSApple OSS Distributions 137*c54f35caSApple OSS Distributions fmt = ( 138*c54f35caSApple OSS Distributions "VM Map Entry Info\n" 139*c54f35caSApple OSS Distributions " vm entry : {&v:#x}\n" 140*c54f35caSApple OSS Distributions " start / end : " 141*c54f35caSApple OSS Distributions "{$v.links.start:#x} - {$v.links.end:#x} " 142*c54f35caSApple OSS Distributions "({0.pages:,d} pages)\n" 143*c54f35caSApple OSS Distributions " vm tag : {$v.vme_alias|vm_kern_tag}\n" 144*c54f35caSApple OSS Distributions " vm range id : {range_id}\n" 145*c54f35caSApple OSS Distributions " protection : " 146*c54f35caSApple OSS Distributions "{$v.protection|vm_prot}/{$v.max_protection|vm_prot}\n" 147*c54f35caSApple OSS Distributions " vm object : " 148*c54f35caSApple OSS Distributions "{0.vme_object_type} ({0.vme_object[0]:#x})\n" 149*c54f35caSApple OSS Distributions " entry offset : {0.vme_offset:#x}\n" 150*c54f35caSApple OSS Distributions ) 151*c54f35caSApple OSS Distributions print(xnu_format(fmt, self, v=self.sbv, 152*c54f35caSApple OSS Distributions range_id=next( 153*c54f35caSApple OSS Distributions i 154*c54f35caSApple OSS Distributions for i, r in enumerate(self.kmem.kmem_ranges) 155*c54f35caSApple OSS Distributions if r.contains(self.address) 156*c54f35caSApple OSS Distributions ) 157*c54f35caSApple OSS Distributions )) 158*c54f35caSApple OSS Distributions 159*c54f35caSApple OSS Distributions 160*c54f35caSApple OSS Distributions@whatis_provider 161*c54f35caSApple OSS Distributionsclass KernelMapWhatisProvider(WhatisProvider): 162*c54f35caSApple OSS Distributions """ 163*c54f35caSApple OSS Distributions Whatis Provider for the kernel map ranges 164*c54f35caSApple OSS Distributions """ 165*c54f35caSApple OSS Distributions 166*c54f35caSApple OSS Distributions def claims(self, address): 167*c54f35caSApple OSS Distributions return any(r.contains(address) for r in self.kmem.kmem_ranges) 168*c54f35caSApple OSS Distributions 169*c54f35caSApple OSS Distributions def lookup(self, address): 170*c54f35caSApple OSS Distributions return VMMapEntry(self.kmem, address, VMMap(self.kmem.kernel_map)) 171*c54f35caSApple OSS Distributions 172*c54f35caSApple OSS Distributions 173*c54f35caSApple OSS Distributions__all__ = [ 174*c54f35caSApple OSS Distributions VMMap.__name__, 175*c54f35caSApple OSS Distributions VMMapEntry.__name__, 176*c54f35caSApple OSS Distributions KernelMapWhatisProvider.__name__, 177*c54f35caSApple OSS Distributions] 178