예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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