def findFixupTarget(FI): FI.derefVal = struct.unpack(fmt[FI.derefSz], sectionData[FI.offset:FI.offset + FI.derefSz])[0] FI.refTo = FI.VA + FI.derefSz + util.toSigned32(FI.derefVal) if FI.isRela else FI.derefVal FI.refBB = self.CI.getBBlByVA(FI.refTo) if FI.refBB: FI.target = "BB#%3s" % str(FI.refBB.idx) else: FI.target = self.elfParser.getSectionByVA(FI.refTo)
def _processRefs(self): """ Compute fixup derefVals and refTos from the given section """ def findFixupTarget(FI): FI.derefVal = struct.unpack( fmt[FI.derefSz], sectionData[FI.offset:FI.offset + FI.derefSz])[0] FI.refTo = FI.VA + FI.derefSz + util.toSigned32( FI.derefVal) if FI.isRela else FI.derefVal FI.refBB = self.CI.getBBlByVA(FI.refTo) if FI.refBB: FI.target = "BB#%3s" % str(FI.refBB.idx) else: FI.target = self.elfParser.getSectionByVA(FI.refTo) sectionData = self.elfParser.elf.get_section_by_name( self.sectionName).data() fmt = {1: "<b", 2: "<h", 4: "<i", 8: "<q"} for FI in self.FixupsLayout: FI.derefVal = struct.unpack( fmt[FI.derefSz], sectionData[FI.offset:FI.offset + FI.derefSz])[0] # In the small/medium ABI model, it is safe to assume that # all FixupRefValues are the signed 32-bit integers # FIXME : Handle the large model (64-bit offset) in need - we do not care for now FI.refTo = FI.VA + FI.derefSz + util.toSigned32( FI.derefVal) if FI.isRela else FI.derefVal # binpang. Comment it FI.refBB = self.CI.getBBlByVA(FI.refTo) if FI.refBB: FI.target = "BB#%3s" % str(FI.refBB.idx) if FI.parent: FI.parent.refFroms.append(FI.refBB) ''' # [NEW] We only trace CFG of the function (i.e., cross reference) # iff a fixup points to the region within .text section if self.sectionName == C.SEC_TEXT and FI.type == C.FT_C2C: fixupFunc, refBBFunc = FI.parent.parent, FI.refBB.parent if fixupFunc.idx != refBBFunc.idx: # For direct references (either by calls or jump families) # For indirect references using JT, see updateFixupRefs1() in reorderEngine fixupFunc.refTos.add(refBBFunc) refBBFunc.refFroms.add(fixupFunc) ''' else: FI.target = self.elfParser.getSectionByVA(FI.refTo) nopBytes = util.countRefToNops(sectionData, FI) if FI.target == C.SEC_TEXT and nopBytes > 0: FI.refBB = self.CI.getBBlByVA(FI.refTo + nopBytes) logging.warning( "\tFound the Fixup that points to a NOP block: refBBL adjusted to the next BBL" ) if FI.refBB: FI.target = "BB#%3s" % str(FI.refBB.idx) # Since we do not have BBL information for special sections, # a) Find the corresponding BBL here # b) Patching fixup should be done in patchCodeSection() in a binaryBuilder class if self.hasSpecialSection(): for FI in self.FixupsLayoutSpecial: findFixupTarget(FI) if self.hasOrphanFixups(): for FI in self.FixupsLayoutOrphan: findFixupTarget(FI) logging.info("Orphan Fixup (maybe -cfi-icall?): %s" % (FI))