def hook_ReadSection(ql, address, params): guid = str(ql.os.read_guid(params["NameGuid"])) section_type = params["SectionType"] & 0xFF fw_file = get_firmware_file(ql, guid) if not fw_file: return EFI_NOT_FOUND section = get_section(fw_file, section_type, params["SectionInstance"]) if not section: return EFI_NOT_FOUND buffer = read_int64(ql, params["Buffer"]) if buffer == 0: # The output buffer is to be allocated by ReadSection() buffer = ql.os.heap.alloc(len(section.data)) ql.mem.write(buffer, section.data) write_int64(ql, params["BufferSize"], len(section.data)) write_int64(ql, params["Buffer"], buffer) return EFI_SUCCESS # The output buffer is caller allocated, ... buffer_size = read_int64(ql, params["BufferSize"]) if buffer_size < len(section.data): # But is not big enough write_int64(ql, params["BufferSize"], len(section.data)) return EFI_BUFFER_TOO_SMALL # And is big enough write_int64(ql, params["BufferSize"], len(section.data)) ql.mem.write(buffer, section.data) return EFI_SUCCESS
def GetVariable_propagate_taint(ql, address, params): """ Taint propagation for GetVariable(). We initially assume that all NVRAM variables are fully initialized, so the target buffer becomes untainted. """ begin = params['Data'] end = begin + read_int64(ql, params['DataSize']) ql.tainters['uninitialized'].set_taint_range(begin, end, False)
def AllocatePool_propagate_taint(ql, address, params): """ Taint propagation for AllocatePool(). We know that all pool memory is initially uninitialized, so we taint it. """ begin = read_int64(ql, params['Buffer']) end = begin + params['Size'] set_taint_range(ql, begin, end, True)
def InstallProtocolInterface(context, params): handle = read_int64(context.ql, params["Handle"]) if handle == 0: handle = context.heap.alloc(1) dic = context.protocols.get(handle, {}) dic[params["Protocol"]] = params["Interface"] context.protocols[handle] = dic write_int64(context.ql, params["Handle"], handle) context.notify_protocol(params['Handle'], params['Protocol'], params['Interface'], True) return EFI_SUCCESS
def LocateHandle(context, params): buffer_size, handles = LocateHandles(context, params) if len(handles) == 0: return EFI_NOT_FOUND ret = EFI_BUFFER_TOO_SMALL if read_int64(context.ql, params["BufferSize"]) >= buffer_size: ptr = params["Buffer"] for handle in handles: write_int64(context.ql, ptr, handle) ptr += pointer_size ret = EFI_SUCCESS write_int64(context.ql, params["BufferSize"], buffer_size) return ret
def InstallProtocolInterface(context, params): handle = read_int64(context.ql, params["Handle"]) if handle == 0: handle = context.heap.alloc(1) dic = context.protocols.get(handle, {}) dic[params["Protocol"]] = params["Interface"] context.protocols[handle] = dic for (event_id, event_dic) in context.ql.loader.events.items(): if event_dic['Guid'] == params['Protocol']: # The event was previously registered by 'RegisterProtocolNotify'. signal_event(context.ql, event_id) check_and_notify_protocols(context.ql) write_int64(context.ql, params["Handle"], handle) return EFI_SUCCESS
def nitems(self) -> int: addr = self.system_table + self.__nitems_off return utils.read_int64(self.ql, addr) # UINTN
def baseptr(self) -> int: addr = self.system_table + self.__arrptr_off return utils.read_int64(self.ql, addr)
def validate_read_section(ql, address, params): buffer_size = read_int64(ql, params['BufferSize']) buffer = ql.mem.read(read_int64(ql, params['Buffer']), buffer_size) assert buffer.decode('utf-16').strip('\x00') == 'DxeMain.efi' return (address, params)