def getPointer(addr, off): [tpath, offset] = art.getOffset(addr, memList) g = open(tpath, 'rb') g.seek(offset + off) newAddr = hex(unpack_addr(g)) g.close() return newAddr
def getPointer(addr, off): [tpath, offset] = art.getOffset(addr, memList) g = art.getFhandle(tpath) g.seek(offset+off) newAddr = hex(unpack_int(g.read(4))[0]) g.close() return newAddr
def printRefs(refs, lstList, mapList): [start, end] = art.getSE(lstList) if refs: for ref in refs: [aPath, offset] = art.getOffset(ref, mapList) addr = art.getFhandle(aPath) dumpRefs(ref, addr, ref, offset)
def getObjects(self, addrStart, objCount, jvm, lstList, mapList, bitmap_size_, heapBegin_): #heapBegin_ = int(heapBegin_, 16) [start, end] = art.getSE(lstList) objCount = int(objCount) [aPath, offset] = art.getOffset(addrStart, mapList) addr = open(aPath, 'rb') addr.seek(offset) #obj = int(addrStart, 16) while (objCount>0): #self.get_open_fds() try: oClass = hex(unpack_uint(addr)) if (start <= int(oClass, 16) <= end): # validating class pointer needs to edit #if (self.hasAddress(obj+offset, bitmap_size_, heapBegin_)): Validating object pointer to ensure its within heap boundary off = addr.tell()-4 address = hex(start+off) objSize = jvm.dumpRefs(oClass, addr, address, off) if (objSize%8!=0): objSize = 8*(int(objSize / 8) + (objSize % 8 > 0)) if (objSize==0): objSize =8 offset+=objSize addr.seek(offset) else: objSize=8 offset+=objSize addr.seek(offset) except: objSize=8 offset+=objSize addr.seek(offset) objCount=objCount-1 addr.close()
def getObjects(self, addrStart, objCount, jvm, lstList, mapList, bitmap_size_, heapBegin_): #heapBegin_ = int(heapBegin_, 16) [start, end] = art.getSE(lstList) objCount = int(objCount) [aPath, offset] = art.getOffset(addrStart, mapList) addr = art.getFhandle(aPath) addr.seek(offset) #obj = int(addrStart, 16) while (objCount > 0): oClass = hex(unpack_int(addr.read(4))[0]) if (art.validateAddr( int(oClass, 16), start, end)): # validating class pointer needs to edit #if (self.hasAddress(obj+offset, bitmap_size_, heapBegin_)): Validating object pointer to ensure its within heap boundary off = addr.tell() - 4 address = hex(start + off) objSize = jvm.dumpRefs(oClass, addr, address, off) if (objSize % 8 != 0): objSize = 8 * (int(objSize / 8) + (objSize % 8 > 0)) if (objSize == 0): objSize = 8 offset += objSize addr.seek(offset) objCount = objCount - 1 else: objSize = 8 offset += objSize addr.seek(offset) addr.close()
def getThreads(self, tList, memList): threads = OrderedDict() opeer = [] for t in tList: [tpath, offset] = art.getOffset(t, memList) with open(tpath, 'rb') as g: tls32Index = types.art_types.get('Thread')[1].get('tls32_')[0] tidIndex = types.art_types.get('struct_tls32_')[1].get( 'tid')[0] + tls32Index g.seek(offset + tidIndex) tid = unpack_dec(g.read(4))[0] tlsPtrIndex = types.art_types.get('Thread')[1].get( 'tlsPtr_')[0] nameIndex = tlsPtrIndex + types.art_types.get( 'struct_tlsPtr_')[1].get('name')[0] g.seek(offset + nameIndex) strPointer = hex(unpack_int(g.read(4))[0]) sIndex = tlsPtrIndex + types.art_types.get( 'struct_tlsPtr_')[1].get('opeer')[0] g.seek(offset + sIndex) tInstance = hex(unpack_int(g.read(4))[0]) dPointer = art.getNames(strPointer, memList) threads.update({t: [tid, dPointer, strPointer]}) opeer.append(tInstance) g.close() return [threads, opeer]
def getThreads(self, tList, memList): threads = OrderedDict() opeer = [] tls32_index = get_index('Thread', 'tls32_') thread_id_index = get_index('tls_32bit_sized_values', 'tid') tlsPtr_index = get_index('Thread', 'tlsPtr_') name_index = get_index('tls_ptr_sized_values', 'name') s_index = get_index('tls_ptr_sized_values', 'opeer') for t in tList: [tpath, offset] = art.getOffset(t, memList) with open(tpath, 'rb') as g: g.seek(offset + tls32_index + thread_id_index) tid = unpack_uint(g) g.seek(offset + tlsPtr_index + name_index) strPointer = hex(unpack_addr(g)) g.seek(offset + tlsPtr_index + s_index) tInstance = hex(unpack_addr(g)) if VERSION == '8.0' and ARCH == 64: dPointer = 'To Fix' else: dPointer = art.getNames(strPointer, memList) threads.update({t: [tid, dPointer, strPointer]}) opeer.append(tInstance) g.close() return [threads, opeer]
def procThread(self, listAddr, memList): [npath, offset] = art.getOffset(listAddr, memList) with open(npath, 'rb') as g: g.seek(offset) p1 = hex(unpack_int(g.read(4))[0]) p2 = hex(unpack_int(g.read(4))[0]) p3 = hex(unpack_int(g.read(4))[0]) g.close() return [p1, p2, p3]
def getObject(self, addrStart, jvm2, lstList, mapList): [start, end] = art.getSE(lstList) [aPath, offset] = art.getOffset(addrStart, mapList) addr = art.getFhandle(aPath) addr.seek(offset) oClass = hex(struct.unpack("<I", addr.read(4))[0]) if (art.validateAddr(int(oClass, 16), start, end)): off = addr.tell() - 4 objSize = jvm2.dumpRefs(oClass, addr, off, start)
def getLocal(key, tName, ref): jni = getJNI(key) [tpath, offset] = art.getOffset(jni, memList) [segment_state, table_begin] = getLocals(tpath, offset) refs = art.getRefs(table_begin, segment_state) if ref in refs: return tName else: return None
def printRefs(refs, lstList, mapList): [start, end] = art.getSE(lstList) if refs: for ref in refs: [klass, monitor, refFile, refOff] = cls.getOKlass(ref, mapList) name = cls.resolveName(klass, mapList) if not name in notList: #print ref [aPath, offset] = art.getOffset(ref, mapList) addr = art.getFhandle(aPath) dumpRefs(ref, addr, ref, offset)
def fromMon(self, mAddr, mapList, memList): tList = [] [mPath, offset] = art.getOffset(mAddr, mapList) print mPath, offset with open(mPath, 'rb') as g: t = types.art_types.get('Monitor')[1].get('owner')[0] print t tList.append(t) threads = self.getThreads(tList, memList) mPath.close() return threads
def getObject(self, addrStart, jvm2, lstList, mapList, bitmap_size_, heapBegin_): ret =[] [start, end] = art.getSE(lstList) [aPath, offset] = art.getOffset(addrStart, mapList) addr = open(aPath, 'rb') addr.seek(offset) oClass = hex(unpack_uint(addr)) if (start <= int(oClass, 16) <= end): off = addr.tell()-4 objSize, ret = jvm2.dumpRefs(oClass, addr, off) addr.close() return ret
def getRegion(self, nPath, rAddr, memList): [heapPath, offset] = self.getHeap(nPath, rAddr, memList) regionSpace = self.readPointer(heapPath, offset, 460) print "RegionSpace Offset " + regionSpace [regionSPath, offset] = art.getOffset(regionSpace, memList) mark_bitmap = self.readPointer(regionSPath, offset, 164) num_regions_ = self.readInt(regionSPath, offset, 100) num_non_free_regions_ = self.readInt(regionSPath, offset, 104) regionAddr = self.readPointer(regionSPath, offset, 108) print "Number of Regions " + str(num_regions_) print "Number of Non Free Regions " + str(num_non_free_regions_) print "Region Array Offset " + str(regionAddr) return [regionAddr, num_regions_]
def getTLAB(self, t, memList): [tpath, offset] = art.getOffset(t, memList) with open(tpath, 'rb') as g: tlsIndex = types.art_types.get('Thread')[1].get('tlsPtr_')[0] tidIndex = types.art_types.get('struct_tlsPtr_')[1].get( 'thread_local_start')[0] + tlsIndex g.seek(offset + tidIndex) TLAB_str = hex(struct.unpack("<I", g.read(4))[0]) TLAB_top = hex(struct.unpack("<I", g.read(4))[0]) TLAB_end = hex(struct.unpack("<I", g.read(4))[0]) TLAB_lmt = hex(struct.unpack("<I", g.read(4))[0]) TLAB_ObjCount = struct.unpack("<i", g.read(4))[0] return [TLAB_str, TLAB_top, TLAB_end, TLAB_ObjCount]
def getObject(self, addrStart, jvm2, lstList, mapList, bitmap_size_, heapBegin_): ret = [] [start, end] = art.getSE(lstList) [aPath, offset] = art.getOffset(addrStart, mapList) addr = art.getFhandle(aPath) addr.seek(offset) oClass = hex(unpack_int(addr.read(4))[0]) if (art.validateAddr(int(oClass, 16), start, end)): off = addr.tell() - 4 objSize, ret = jvm2.dumpRefs(oClass, addr, off) addr.close() return ret
def getTLAB(self, t,memList): [tpath, offset] = art.getOffset(t, memList) with open(tpath, 'rb') as g: tlsIndex = get_index('Thread', 'tlsPtr_') tidIndex = get_index('tls_ptr_sized_values', 'thread_local_start') + tlsIndex g.seek(offset+tidIndex) TLAB_str = hex(unpack_addr(g)) TLAB_top = hex(unpack_addr(g)) TLAB_end = hex(unpack_addr(g)) TLAB_lmt = hex(unpack_addr(g)) TLAB_ObjCount = unpack_addr(g) g.close() return [TLAB_str, TLAB_top,TLAB_end, TLAB_ObjCount]
def getSuperClass(super_class_,fDict, ret): superC = True while superC: [sPath, sOffset] = art.getOffset(super_class_, mapList) sAddr = art.getFhandle(sPath) [name, classFlag, primType, ifields_,methods_, sfields_, dexCache, objSize, refSize, super_class_] = cls.getClassMembers(super_class_, sAddr, sOffset, mapList) sAddr.close() if (name =="java.lang.Object" or super_class_ == None): superC = False elif ifields_!="0x0": ret.append("Super Class Offset " + name) fields = fld.getFields(ifields_, mapList) for key, values in fields.items(): fieldIdx = values[2] cl,type ,name = dx.getMeta(dexCache,fieldIdx,mapList, memList) fDict[values[3]] = [name,type]
def regionHdr(self, regionAddr, num_regions_, memList): [regPath, offset] = art.getOffset(regionAddr, memList) g = art.getFhandle(regPath) g.seek(offset) count = 0 TLAB = [] NonTLAB = [] while (count < num_regions_): regBegin = g.tell() g.seek(regBegin + 16) state_ = struct.unpack("<B", g.read(1))[0] if (state_ > 0): g.seek(regBegin + 33) is_a_tlab_ = struct.unpack("<?", g.read(1))[0] if (is_a_tlab_ == True): g.seek(regBegin) idx = struct.unpack("<i", g.read(4))[0] begin_ = hex(struct.unpack("<I", g.read(4))[0]) top_ = hex(struct.unpack("<I", g.read(4))[0]) end_ = hex(struct.unpack("<I", g.read(4))[0]) #g.seek(regBegin+28) #liveBytes = struct.unpack("<i", g.read(4))[0] #print "Tlab "+str(liveBytes) g.seek(regBegin + 36) thread = hex(struct.unpack("<I", g.read(4))[0]) TLAB.append( str(idx) + "\t" + begin_ + "\t" + top_ + "\t" + end_ + "\t" + thread) else: g.seek(regBegin) idx = struct.unpack("<i", g.read(4))[0] begin_ = hex(struct.unpack("<I", g.read(4))[0]) top_ = hex(struct.unpack("<I", g.read(4))[0]) end_ = hex(struct.unpack("<I", g.read(4))[0]) g.seek(regBegin + 20) objAlloc = struct.unpack("<i", g.read(4))[0] #g.seek(regBegin+28) #liveBytes = struct.unpack("<i", g.read(4))[0] #print "NonTlab "+str(liveBytes) NonTLAB.append( str(idx) + "\t" + begin_ + "\t" + top_ + "\t" + end_ + "\t" + str(objAlloc)) g.seek(regBegin + 40) else: g.seek(regBegin + 40) count = count + 1 return [TLAB, NonTLAB]
def getBitmap(self, regionSPath, offset, memList): mark_bitmap = self.readPointer( regionSPath, offset, 164) #GetLiveBitmap for region space returns mark_bitmap #print "live_bitmap " + mark_bitmap #GetLiveBitmap for region space returns mark_bitmap [bitmapPath, offset] = art.getOffset(mark_bitmap, memList) g = art.getFhandle(bitmapPath) g.seek(offset) memmap = hex(unpack_int(g.read(4))[0]) begin_ = hex(unpack_int(g.read(4))[0]) bitmap_size_ = unpack_dec(g.read(4))[0] #print "Bitmap size = "+ str(bitmap_size_) heapBegin_ = hex(unpack_int(g.read(4))[0]) name_ = art.getNames(hex(int(mark_bitmap, 16) + 16), memList) #print memmap, begin_, bitmap_size_, heapBegin_, name_ g.close() return [bitmap_size_, heapBegin_]
def getBitmap(self, regionSPath, offset, memList): mark_bitmap_index = get_index('RegionSpace', 'mark_bitmap_') mark_bitmap = self.readPointer(regionSPath, offset,mark_bitmap_index) #GetLiveBitmap for region space returns mark_bitmap #print "live_bitmap " + mark_bitmap #GetLiveBitmap for region space returns mark_bitmap [bitmapPath, offset] = art.getOffset(mark_bitmap, memList) g = open(bitmapPath, 'rb') g.seek(offset) ########## GET indexes in SpaceBitmap structure memmap = hex(unpack_addr(g)) begin_ = hex(unpack_addr(g)) bitmap_size_ = unpack_addr(g) #print "Bitmap size = "+ str(bitmap_size_) heapBegin_ = hex(unpack_addr(g)) # name_index = get_index('SpaceBitmap', 'name_') # name_ = art.getNames(hex(int(mark_bitmap, 16)+name_index), memList) #print memmap, begin_, bitmap_size_, heapBegin_, name_ g.close() return [bitmap_size_, heapBegin_]
def getRegion(self, nPath, rAddr, memList): [heapPath, offset] = self.getHeap(nPath, rAddr, memList) regionSpace = self.readPointer(heapPath, offset, 460) #print "RegionSpace Offset "+ regionSpace [regionSPath, offset] = art.getOffset(regionSpace, memList) #live_bitmap = self.readPointer(regionSPath, offset,40) #Don't use always zero #print "live_bitmap" + live_bitmap #mark_bitmap = self.readPointer(regionSPath, offset,164) #GetLiveBitmap for region space returns mark_bitmap #print "mark_bitmap" + mark_bitmap num_regions_ = self.readInt(regionSPath, offset, 100) num_non_free_regions_ = self.readInt(regionSPath, offset, 104) #print "Number of regions = "+ str(num_non_free_regions_) regionAddr = self.readPointer(regionSPath, offset, 108) #print "Number of Regions "+str(num_regions_) #print "Number of Non Free Regions "+ str(num_non_free_regions_) #print "Region Array Offset "+str(regionAddr) #print "Region live_bitmap Offset "+str(mark_bitmap) [bitmap_size_, heapBegin_] = self.getBitmap(regionSPath, offset, memList) return [regionAddr, num_regions_, bitmap_size_, heapBegin_]
def getObjects(self, addrStart, objCount, jvm, lstList, mapList): [start, end] = art.getSE(lstList) objCount = int(objCount) [aPath, offset] = art.getOffset(addrStart, mapList) addr = art.getFhandle(aPath) addr.seek(offset) while (objCount > 0): oClass = hex(struct.unpack("<I", addr.read(4))[0]) if (art.validateAddr(int(oClass, 16), start, end)): off = addr.tell() - 4 objSize = jvm.dumpRefs(oClass, addr, off, start) if (objSize % 8 != 0): objSize = 8 * (int(objSize / 8) + (objSize % 8 > 0)) if (objSize == 0): objSize = 8 offset += objSize addr.seek(offset) objCount = objCount - 1 else: objSize = 8 offset += objSize addr.seek(offset)
def getPointer(addr, off): [tpath, offset] = art.getOffset(addr, memList) g = art.getFhandle(tpath) g.seek(offset + off) newAddr = hex(struct.unpack("<I", g.read(4))[0]) return newAddr
def getHeap(self, nPath, rAddr, memList): index = get_index('Runtime', 'heap_') heapAddr = self.readPointer(nPath, rAddr,index) #print "Heap Offset "+ heapAddr [heapPath, offset] = art.getOffset(heapAddr, memList) return [heapPath, offset]
def regionHdr(self, regionAddr, num_regions_, memList): [regPath, offset] = art.getOffset(regionAddr, memList) g = open(regPath, 'rb') g.seek(offset) count = 0 TLAB = [] NonTLAB =[] oCount=0 state_index = get_index('Region', 'state_') isTLAB_index = get_index('Region', 'is_a_tlab_') begin_index = get_index('Region', 'begin_') top_index = get_index('Region', 'top_') end_index = get_index('Region', 'end_') livebytes_index = get_index('Region', 'live_bytes_') threadpos_index = get_index('Region', 'thread_') objalloc_index = get_index('Region', 'objects_allocated_') region_sz = get_class_size('Region') while (count<num_regions_): regBegin = g.tell() g.seek(regBegin + state_index) state_ = unpack_b(g) #g.seek(regBegin+17) #type = struct.unpack("<B", g.read(1))[0] #print "Region Type "+str(type) if(state_ > 0): # non-free region state_=1 means kRegionStateAllocated, our none-free regions are type = 3 (kRegionTypeToSpace), 4 (kRegionTypeNone) g.seek(regBegin + isTLAB_index) is_a_tlab_ = unpack_bool(g) g.seek(regBegin) idx = unpack_addr(g) # size_t g.seek(regBegin + begin_index) begin_ = hex(unpack_addr(g)) g.seek(regBegin + top_index) top_ = hex(unpack_addr(g)) g.seek(regBegin + end_index) end_ = hex(unpack_addr(g)) #for debug to be removed #Android 8 /art/runtime/gc/space/region_space-inl.h line 249 g.seek(regBegin + livebytes_index) liveBytes = unpack_addr(g) diff = int(top_, 16) - int(begin_, 16) need_bitmap = liveBytes != -1 and liveBytes != diff if is_a_tlab_: #print "Tlab "+str(need_bitmap) #end debug g.seek(regBegin + threadpos_index) thread = hex(unpack_addr(g)) TLAB.append(str(idx) + "\t"+begin_+"\t"+top_+"\t"+end_+"\t"+str(need_bitmap)+"("+str(liveBytes)+" "+str(diff)+")"+"\t\t\t"+thread) else: g.seek(regBegin + objalloc_index) objAlloc = unpack_addr(g) oCount=oCount+objAlloc #print "NonTlab "+str(need_bitmap) #end debug NonTLAB.append(str(idx) + "\t"+begin_+"\t"+top_+"\t"+end_+"\t"+str(objAlloc)+"\t"+str(need_bitmap)+"("+str(liveBytes)+" "+str(diff)+")") g.seek(regBegin + region_sz) count += 1 g.close() print "NonTlab Total "+str(oCount) return [TLAB, NonTLAB]
def getJVM(jvm, memList): [vmPath, offset] = art.getOffset(jvm, memList) return [vmPath, offset]
def regionHdr(self, regionAddr, num_regions_, memList): [regPath, offset] = art.getOffset(regionAddr, memList) g = art.getFhandle(regPath) g.seek(offset) count = 0 TLAB = [] NonTLAB = [] oCount = 0 while (count < num_regions_): regBegin = g.tell() g.seek(regBegin + 16) state_ = struct.unpack("<B", g.read(1))[0] #g.seek(regBegin+17) #type = struct.unpack("<B", g.read(1))[0] #print "Region Type "+str(type) if ( state_ > 0 ): # non-free region state_=1 means kRegionStateAllocated, our none-free regions are type = 3 (kRegionTypeToSpace), 4 (kRegionTypeNone) g.seek(regBegin + 33) is_a_tlab_ = struct.unpack("<?", g.read(1))[0] if (is_a_tlab_ == True): g.seek(regBegin) idx = unpack_dec(g.read(4))[0] begin_ = hex(unpack_int(g.read(4))[0]) top_ = hex(unpack_int(g.read(4))[0]) end_ = hex(unpack_int(g.read(4))[0]) #for debug to be removed #Android 8 /art/runtime/gc/space/region_space-inl.h line 249 g.seek(regBegin + 28) liveBytes = unpack_dec(g.read(4))[0] diff = int(top_, 16) - int(begin_, 16) need_bitmap = liveBytes != -1 and liveBytes != diff #print "Tlab "+str(need_bitmap) #end debug g.seek(regBegin + 36) thread = hex(unpack_int(g.read(4))[0]) TLAB.append( str(idx) + "\t" + begin_ + "\t" + top_ + "\t" + end_ + "\t" + str(need_bitmap) + "(" + str(liveBytes) + " " + str(diff) + ")" + "\t\t\t" + thread) else: g.seek(regBegin) idx = unpack_dec(g.read(4))[0] begin_ = hex(unpack_int(g.read(4))[0]) top_ = hex(unpack_int(g.read(4))[0]) end_ = hex(unpack_int(g.read(4))[0]) g.seek(regBegin + 20) objAlloc = unpack_dec(g.read(4))[0] oCount = oCount + objAlloc #for debug to be removed g.seek(regBegin + 28) liveBytes = unpack_dec(g.read(4))[0] diff = int(top_, 16) - int(begin_, 16) need_bitmap = liveBytes != -1 and liveBytes != diff #print "NonTlab "+str(need_bitmap) #end debug NonTLAB.append( str(idx) + "\t" + begin_ + "\t" + top_ + "\t" + end_ + "\t" + str(objAlloc) + "\t" + str(need_bitmap) + "(" + str(liveBytes) + " " + str(diff) + ")") g.seek(regBegin + 40) else: g.seek(regBegin + 40) count = count + 1 g.close() print "NonTlab Total " + str(oCount) return [TLAB, NonTLAB]