def _get_protocol_guids(self) -> List[UefiProtocolGuid]: protocol_guids = [] target_sections = [".data"] for section in self.sections: if section["name"] in target_sections: self._r2.cmd("s {:#x}".format(section["vaddr"])) section_data = bytes( self._r2.cmdj("xj {:#d}".format(section["vsize"]))) # find guids in section data: for i in range(len(section_data) - 15): chunk = section_data[i:i + 16] guid = GUID_FROM_BYTES.get(chunk) if not guid: continue if guid.value in ["00000000-0000-0000-0000000000000000"]: continue protocol_guids.append( UefiProtocolGuid( address=section["vaddr"] + i, name=guid.name, value=guid.value, )) return protocol_guids
def _get_protocols_x64(self) -> List[UefiProtocol]: protocols = [] for bs in self.boot_services_protocols: block_insns = self._r2.cmdj("pdbj @{:#x}".format(bs.address)) for insn in block_insns: if "esil" in insn: esil = insn["esil"].split(",") if ((insn["type"] == "lea") and (esil[-1] == "=") and (esil[-2] == BS_PROTOCOLS_INFO_X64[bs.name]["reg"]) and (esil[-3] == "+")): if "ptr" in insn: p_guid_addr = insn["ptr"] self._r2.cmd("s {:#x}".format(p_guid_addr)) p_guid_b = bytes(self._r2.cmdj("xj 16")) # look up in known list guid = GUID_FROM_BYTES.get(p_guid_b) if not guid: guid = UefiGuid( value=str(uuid.UUID(bytes_le=p_guid_b)), name="proprietary_protocol", ) protocols.append( UefiProtocol( name=guid.name, value=guid.value, guid_address=p_guid_addr, address=insn["offset"], service=bs.name, )) return protocols
def _get_ppi_list(self) -> List[UefiProtocol]: ppi_list: List[UefiProtocol] = list() for pei_service in self.pei_services: if pei_service.name != "LocatePpi": continue block_insns = self._rz.cmdj("pdj -16 @ {:#x}".format( pei_service.address)) for index in range(len(block_insns) - 1, -1, -1): esil = block_insns[index]["esil"].split(",") if not (esil[-1] == "-=" and esil[-2] == "esp" and esil[-3] == "4"): continue if "ptr" not in block_insns[index]: continue current_block = block_insns[index] p_guid_addr = current_block["ptr"] baddr = self.info["bin"]["baddr"] if p_guid_addr < baddr: continue # wrong addresses in r2 in case of TE p_guid_addr = self._wrong_addr(p_guid_addr) self._rz.cmd("s {:#x}".format(p_guid_addr)) p_guid_b = bytes(self._rz.cmdj("xj 16")) # look up in known list guid = GUID_FROM_BYTES.get(p_guid_b) if not guid: guid = UefiGuid( value=str(uuid.UUID(bytes_le=p_guid_b)).upper(), name="proprietary_ppi", ) ppi = UefiProtocol( name=guid.name, value=guid.value, guid_address=p_guid_addr, address=block_insns[index]["offset"], service=pei_service.name, ) if ppi not in ppi_list: ppi_list.append(ppi) return ppi_list
def _get_protocols_64bit(self) -> List[UefiProtocol]: protocols = list() for bs in self.boot_services_protocols: block_insns = self._rz.cmd("pdbj @ {:#x}".format(bs.address)) try: block_insns = json.loads(block_insns) except (ValueError, KeyError, TypeError) as _: continue for insn in block_insns: if "esil" in insn: esil = insn["esil"].split(",") if not ((insn["type"] == "lea") and (esil[-1] == "=") and (esil[-2] == BS_PROTOCOLS_INFO_64_BIT[bs.name]["reg"]) and (esil[-3] == "+")): continue if "ptr" not in insn: continue p_guid_addr = insn["ptr"] self._rz.cmd("s {:#x}".format(p_guid_addr)) p_guid_b = bytes(self._rz.cmdj("xj 16")) # look up in known list guid = GUID_FROM_BYTES.get(p_guid_b) if not guid: guid = UefiGuid( value=str(uuid.UUID(bytes_le=p_guid_b)).upper(), name="proprietary_protocol", ) protocols.append( UefiProtocol( name=guid.name, value=guid.value, guid_address=p_guid_addr, address=insn["offset"], service=bs.name, )) return protocols