# SPDX-FileCopyrightText: 2022 Andrius Štikonas # SPDX-FileCopyrightText: 2017 Jeremiah Orians # # SPDX-License-Identifier: GPL-3.0-or-later # efi_main(void *image_handle, struct efi_system_table *system) :_start 4889E5 ; COPY_RSP_to_RBP # save stack pointer 48890D %image_handle ; STORE64_from_RCX_rel32 %image_handle # save image_handle 488B42 40 ; LOAD64_into_RAX_from_Address_RDX_Immediate8 !64 # system->out 488905 %system_out ; STORE64_from_RAX_rel32 %system_out # save system->out 4C8B72 60 ; LOAD64_into_R14_from_Address_RDX_Immediate8 !96 # system->boot 31C9 ; XOR_ECX_ECX # timeout = 0 31D2 ; XOR_EDX_EDX # watchdog_code = 0 4D31C0 ; XOR_R8_R8 # data_size = 0 4D31C9 ; XOR_R9_R9 # watchdog_data = 0 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function 41FF96 F0000000 ; CALL_R14_Immediate32 %240 # system->boot->set_watchdog_timer # Open Loaded Image protocol 50 ; PUSH_RAX # allocate stack for image 4989E0 ; COPY_RSP_to_R8 # arg3 = &image 488B15 %LOADED_IMAGE_PROTOCOL_8 ; LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL_8 # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) 52 ; PUSH_RDX # push last 64 bits onto stack 488B15 %LOADED_IMAGE_PROTOCOL ; LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) 52 ; PUSH_RDX # push first 64 bits onto 4889E2 ; COPY_RSP_to_RDX # arg2 = &guid 6A 01 ; PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 6A 00 ; PUSH !0 # arg5 = NULL 4C8B0D %image_handle ; LOAD64_into_R9_rel32 %image_handle # arg4 = image_handle 4C89C9 ; COPY_R9_to_RCX # arg1 = image_handle 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function 41FF96 18010000 ; CALL_R14_Immediate32 %280 # system->boot->open_protocol(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) 488B4424 40 ; LOAD64_into_RAX_from_Address_RSP_Immediate8 !64 # get_image 488905 %image ; STORE64_from_RAX_rel32 %image # save image # Command line args 4889C1 ; COPY_RAX_to_RCX # copy image to rcx 488B58 38 ; LOAD64_into_RBX_from_Address_RAX_Immediate8 !56 # options = image->load_options # Skip application name :loop_options1 4883C3 02 ; ADDI8_RBX !2 # ++options 8A03 ; LOAD8_AL_from_Address_RBX # *options 3C 20 ; CMPI8_AL !0x20 # if *options == ' ' 74 !loop_options2 ; JE8 !loop_options2 # then jump 84C0 ; TEST_AL_AL # if options != 0 75 !loop_options1 ; JNE8 !loop_options1 # then loop # Use default file 4C8D25 %default_file ; LEA_R12_rel %default_file # Use "kaem.amd64" EB !root_fs ; JMP8 !root_fs # jump :loop_options2 4883C3 02 ; ADDI8_RBX !2 # ++options 4989DC ; COPY_RBX_to_R12 # save input file :root_fs # Get root file system 50 ; PUSH_RAX # allocate stack for rootfs 4989E0 ; COPY_RSP_to_R8 # arg3 = &rootfs 488B15 %SIMPLE_FS_PROTOCOL_8 ; LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL_8 # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (last 64 bits) 52 ; PUSH_RDX # push last 64 bits onto stack 488B15 %SIMPLE_FS_PROTOCOL ; LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (first 64 bits) 52 ; PUSH_RDX # push first 64 bits onto stack 4889E2 ; COPY_RSP_to_RDX # arg2 = &guid 6A 01 ; PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 6A 00 ; PUSH !0 # arg5 = NULL 4C8B0D %image_handle ; LOAD64_into_R9_rel32 %image_handle # arg4 = image_handle 488B49 18 ; LOAD64_into_RCX_from_Address_RCX_Immediate8 !24 # arg1 = root_device = image->device 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function 41FF96 18010000 ; CALL_R14_Immediate32 %280 # system->boot->open_protocol(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) 488B4C24 40 ; LOAD64_into_RCX_from_Address_RSP_Immediate8 !64 # get rootfs # Get root directory 52 ; PUSH_RDX # allocate stack for rootdir 4889E2 ; COPY_RSP_to_RDX # arg3 = &rootdir 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function FF51 08 ; CALL_RCX_Immediate8 !8 # rootfs->open_volume(rootfs, &rootdir) 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 415D ; POP_R13 # save &rootdir # Open file for reading 52 ; PUSH_RDX # allocate stack for fin 4889E2 ; COPY_RSP_to_RDX # arg2 = &fin 6A 01 ; PUSH !1 # arg5 = EFI_FILE_READ_ONLY 6A 01 ; PUSH !1 # prepare to set arg4 to EFI_FILE_MODE_READ 4159 ; POP_R9 # arg4 = EFI_FILE_MODE_READ 4D89E0 ; COPY_R12_to_R8 # arg3 = in 4C89E9 ; COPY_R13_to_RCX # arg1 = rootdir 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function FF51 08 ; CALL_RCX_Immediate8 !8 # rootdir->open() 85C0 ; TEST_EAX_EAX # if status != EFI_SUCCESS 0F85 %abort ; JNE32 %abort # then exit without closing file 4C8B6424 28 ; LOAD64_into_R12_from_Address_RSP_Immediate8 !40 # get fin # Allocate pool for command 52 ; PUSH_RDX # allocate stack for command 4989E0 ; COPY_RSP_to_R8 # arg3 = &command 31D2 ; XOR_EDX_EDX # zero RDX B6 10 ; LOADI8_DH !0x10 # arg2 = 4096 = 0x1000 6A 02 ; PUSH !2 59 ; POP_RCX # arg1 = EFI_LOADER_DATA 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF56 40 ; CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 4096, &commmand) 488B5C24 18 ; LOAD64_into_RBX_from_Address_RSP_Immediate8 !24 # get command :next_command 31F6 ; XOR_ESI_ESI # i = 0 4D31FF ; XOR_R15_R15 # command_length = 0 :read_command E8 %read_byte ; CALLI32 %read_byte # read another byte c 3C 0A ; CMPI8_AL !0xa # if c == '\n' 74 !read_command_done ; JE8 !read_command_done # then we are done with this command 3C 20 ; CMPI8_AL !0x20 # if c == ' ' 75 !read_command_comments ; JNE8 !read_command_comments 4D85FF ; TEST_R15_R15 # and command_length == 0 75 !read_command_comments ; JNE8 !read_command_comments 4989F7 ; COPY_RSI_to_R15 # command_length = i :read_command_comments 3C 23 ; CMPI8_AL !0x23 # if c == '#' then process comment 75 !read_command_store_char ; JNE8 !read_command_store_char # else store char :read_command_skip_comment E8 %read_byte ; CALLI32 %read_byte # get another char 3C 0A ; CMPI8_AL !0xa # if c == '\n' 75 !read_command_skip_comment ; JNE8 !read_command_skip_comment # continue reading until newline EB !next_command ; JMP8 !next_command # deal with another line :read_command_store_char 4801F3 ; ADD_RSI_to_RBX # rbx = &command[i] 668903 ; STORE16_AX_into_Address_RBX # command[i] = c 4829F3 ; SUB_RSI_from_RBX # rbx = &command[0] 4883C6 02 ; ADDI8_RSI !2 # location of the next char EB !read_command ; JMP8 !read_command # continue looping :read_command_done 4D85FF ; TEST_R15_R15 # if command_length == 0 74 !next_command ; JE8 !next_command # deal with another line 4801F3 ; ADD_RSI_to_RBX # rbx = &command[i] 66C703 0000 ; STOREI16_into_Address_RBX @0 # command[i] = 0 4829F3 ; SUB_RSI_from_RBX # rbx = &command[0] 48D1EE ; SHR_RSI # divide i by 2 to go from char to wchar length 488D15 %prefix ; LEA_RDX_rel %prefix # get prefix " +> " E8 %File_Print ; CALLI32 %File_Print # print it 4889DA ; COPY_RBX_to_RDX # get command E8 %File_Print ; CALLI32 %File_Print # print it 488D15 %suffix ; LEA_RDX_rel %suffix # get suffix "\n\r" E8 %File_Print ; CALLI32 %File_Print # print it # Remove command line options 4901DF ; ADD_RBX_to_R15 # go to the space separating command and its options 6641C707 0000 ; STOREI16_into_Address_R15 @0 # zero it to hide command line options # Open executable file for reading 52 ; PUSH_RDX # allocate stack for fcmd 4889E2 ; COPY_RSP_to_RDX # arg2 = &fcmd 6A 01 ; PUSH !1 # arg5 = EFI_FILE_READ_ONLY 6A 01 ; PUSH !1 # prepare to set arg4 to EFI_FILE_MODE_READ 4159 ; POP_R9 # arg4 = EFI_FILE_MODE_READ 4989D8 ; COPY_RBX_to_R8 # arg3 = command 4C89E9 ; COPY_R13_to_RCX # arg1 = rootdir 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function FF51 08 ; CALL_RCX_Immediate8 !8 # rootdir->open() 85C0 ; TEST_EAX_EAX # if status != EFI_SUCCESS 0F85 %print_error ; JNE32 %print_error # then exit 4883C4 28 ; ADDI8_RSP !40 # deallocate stack 5F ; POP_RDI # get fcmd # Restore command line arguments 6641C707 2000 ; STOREI16_into_Address_R15 @0x20 # restore command line options by readding ' ' # Allocate pool for file_info 52 ; PUSH_RDX # allocate stack for file_info 4989E0 ; COPY_RSP_to_R8 # arg3 = &file_info 31D2 ; XOR_EDX_EDX # zero RDX B6 10 ; LOADI8_DH !0x10 # arg2 = 4096 = 0x1000 6A 02 ; PUSH !2 59 ; POP_RCX # arg1 = EFI_LOADER_DATA 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF56 40 ; CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 4096, &commmand) 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 4159 ; POP_R9 # get file_info (arg4 for get_info) # Get file info 4151 ; PUSH_R9 # save file_info 50 ; PUSH_RAX # allocate stack for file_size 4989E0 ; COPY_RSP_to_R8 # arg3 = &file_size 49C700 00100000 ; STOREI32_into_Address_R8 %0x1000 # file_size = 0x1000 488B15 %SIMPLE_FS_PROTOCOL_8 ; LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL_8 # EFI_FILE_INFO_PROTOCOL (last 64 bits) 52 ; PUSH_RDX # push last 64 bits onto stack 488B15 %FILE_INFO_PROTOCOL ; LOAD64_rel_RDX %FILE_INFO_PROTOCOL # EFI_FILE_INFO_PROTOCOL (first 64 bits) 52 ; PUSH_RDX # push first 64 bits onto stack 4889E2 ; COPY_RSP_to_RDX # arg2 = &guid 4889F9 ; COPY_RDI_to_RCX # arg1 = fcmd 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function FF51 40 ; CALL_RCX_Immediate8 !64 # fcmd->get_info(fcmd, &guid, &file_size, file_info) 4883C4 38 ; ADDI8_RSP !56 # deallocate stack 59 ; POP_RCX # restore file_info 488B51 08 ; LOAD64_into_RDX_from_Address_RCX_Immediate8 !8 # get file_size # Free file_info pool 52 ; PUSH_RDX # save file_size onto stack 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF56 48 ; CALL_R14_Immediate8 !72 # system->boot->free_pool(file_info) 58 ; POP_RAX # deallocate stack 5A ; POP_RDX # restore file_size from stack (arg2 for allocate_pool) # Allocate pool for executable 52 ; PUSH_RDX # save file_size onto stack 52 ; PUSH_RDX # allocate stack for executable 4989E0 ; COPY_RSP_to_R8 # arg3 = &executable 6A 02 ; PUSH !2 59 ; POP_RCX # arg1 = EFI_LOADER_DATA 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF56 40 ; CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, file_size, &executable) 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 415F ; POP_R15 # get executable 5A ; POP_RDX # restore file_size # Load executable into memory 52 ; PUSH_RDX # save file_size onto stack 4D89F8 ; COPY_R15_to_R8 # arg3 = executable 4889E2 ; COPY_RSP_to_RDX # arg2 = &file_size 4889F9 ; COPY_RDI_to_RCX # arg1 = fcmd 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function FF51 20 ; CALL_RCX_Immediate8 !32 # fcmd->read(fcmd, &file_size, executable) 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack # Close fcmd 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 4889F9 ; COPY_RDI_to_RCX # arg1 = fcmd FF51 10 ; CALL_RCX_Immediate8 !16 # fcmd->close(fcmd) 58 ; POP_RAX # deallocate stack 5F ; POP_RDI # restore file_size # Allocate memory for device_path struct 52 ; PUSH_RDX # allocate stack for device_path 4989E0 ; COPY_RSP_to_R8 # arg3 = &device_path 6A 1C ; PUSH !28 # 4 + sizeof(struct efi_device_path_protocol) 5A ; POP_RDX # arg2 = 28 6A 02 ; PUSH !2 59 ; POP_RCX # arg1 = EFI_LOADER_DATA 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF56 40 ; CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 28, &device_path) 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 4158 ; POP_R8 # get device_path # Initialize struct 4C89C0 ; COPY_R8_to_RAX # Make a pointer to device_path members C600 01 ; STOREI8_into_Address_RAX !1 # device_path->type = HARDWARE_DEVICE_PATH 48FFC0 ; INC_RAX # next member C600 03 ; STOREI8_into_Address_RAX !3 # device_path->subtype = MEMORY_MAPPED 48FFC0 ; INC_RAX # next member 66C700 1800 ; STOREI16_into_Address_RAX @24 # device_path->length = 24 4883C0 02 ; ADDI8_RAX !2 # next member C700 01000000 ; STOREI32_into_Address_RAX %1 # device_path->memory_type = EFI_LOADER_CODE 4883C0 04 ; ADDI8_RAX !4 # next member 4C8938 ; STORE64_R15_into_Address_RAX # device_path->start_address = executable 4883C0 08 ; ADDI8_RAX !8 # next member 4901FF ; ADD_RDI_to_R15 # end_address = executable + file_size 4C8938 ; STORE64_R15_into_Address_RAX # device_path->end_address = end_address 4929FF ; SUB_RDI_from_R15 # restore r15 = executable 4883C0 08 ; ADDI8_RAX !8 # next member C600 7F ; STOREI8_into_Address_RAX !0x7f # device_path[1].type = END_HARDWARE_DEVICE_PATH 48FFC0 ; INC_RAX # next member C600 FF ; STOREI8_into_Address_RAX !0xff # device_path[1].subtype = END_ENTIRE_DEVICE_PATH 48FFC0 ; INC_RAX # next member 66C700 0400 ; STOREI16_into_Address_RAX @4 # device_path[1].length = 4 # Load image 4150 ; PUSH_R8 # save device_path 50 ; PUSH_RAX # allocate stack for child_ih 54 ; PUSH_RSP # arg6 = &child_ih 57 ; PUSH_RDI # arg5 = file size 4D89F9 ; COPY_R15_to_R9 # arg4 = executable # arg3 = device_path 488B15 %image_handle ; LOAD64_into_RDX_rel32 %image_handle # arg2 = image_handle 31C9 ; XOR_ECX_ECX # arg1 = 0 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function 41FF96 C8000000 ; CALL_R14_Immediate32 %200 # system->boot->load_image() 4883C4 30 ; ADDI8_RSP !48 # deallocate stack 5F ; POP_RDI # save child_ih # Free device_path pool 59 ; POP_RCX # arg1 = device_path 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF56 48 ; CALL_R14_Immediate8 !72 # system->boot->free_pool(device_path) 58 ; POP_RAX # deallocate stack # Free executable pool 4C89F9 ; COPY_R15_to_RCX # arg1 = executable 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF56 48 ; CALL_R14_Immediate8 !72 # system->boot->free_pool(executable) 58 ; POP_RAX # deallocate stack # Open Child Image 50 ; PUSH_RAX # allocate stack for child_image 4989E0 ; COPY_RSP_to_R8 # arg3 = &child_image 488B15 %LOADED_IMAGE_PROTOCOL_8 ; LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL_8 # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) 52 ; PUSH_RDX # push last 64 bits onto stack 488B15 %LOADED_IMAGE_PROTOCOL ; LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) 52 ; PUSH_RDX # push first 64 bits onto 4889E2 ; COPY_RSP_to_RDX # arg2 = &guid 6A 01 ; PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 6A 00 ; PUSH !0 # arg5 = NULL 4989F9 ; COPY_RDI_to_R9 # arg4 = child_ih 4889F9 ; COPY_RDI_to_RCX # arg1 = child_ih 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function 41FF96 18010000 ; CALL_R14_Immediate32 %280 # system->boot->open_protocol(child_ih, &guid, &child_image, child_ih, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) 4883C4 40 ; ADDI8_RSP !64 # deallocate stack 58 ; POP_RAX # get child_image 488958 38 ; STORE64_from_RBX_into_Address_RAX_Immediate8 !56 # child_image->load_options = command 488970 30 ; STORE64_from_RSI_into_Address_RAX_Immediate8 !48 # set child_image->load_options_size 488B0D %image ; LOAD64_rel_RCX %image # get image 488B49 18 ; LOAD64_into_RCX_from_Address_RCX_Immediate8 !24 # image->device 488948 18 ; STORE64_from_RCX_into_Address_RCX_Immediate8 !24 # child_image->device = image->device # Run command 4D31C0 ; XOR_R8_R8 # arg3 = 0 (ExitData) 31D2 ; XOR_EDX_EDX # arg2 = 0 (ExitData size) 4889F9 ; COPY_RDI_to_RCX # arg1 = child_ih 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF96 D0000000 ; CALL_R14_Immediate32 %208 # system->boot->start_image() 59 ; POP_RCX # deallocate stack 59 ; POP_RCX # deallocate stack 59 ; POP_RCX # deallocate stack 85C0 ; TEST_EAX_EAX # check if return code is 0 75 !print_error ; JNE8 !print_error # print error and exit E9 %next_command ; JMP32 %next_command # process another line from kaem script :print_error 50 ; PUSH_RAX # save exit code 488B15 %subprocess_error ; LOAD64_into_RDX_rel32 %subprocess_error # get error message E8 %File_Print ; CALLI32 %File_Print # print it 58 ; POP_RAX # restore exit code # Close script file and exit :terminate # Free pool 4889C3 ; COPY_RBX_to_RCX # arg1 = command 50 ; PUSH_RAX # save exit code 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 41FF56 48 ; CALL_R14_Immediate8 !72 # system->boot->free_pool(commmand) 4C89E1 ; COPY_R12_to_RCX # arg1 = fin FF51 10 ; CALL_RCX_Immediate8 !16 # fin->close(fin) 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # restore exit code # Exit without closing script file :abort 4889EC ; COPY_RBP_to_RSP # restore stack C3 ; RET :File_Print 488B0D %system_out ; LOAD64_rel_RCX %system_out # get system_out 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function FF51 08 ; CALL_RCX_Immediate8 !8 # system->out->output_string(system->out, WCHAR*) 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack C3 ; RET # read_byte function # reads a single character :read_byte 4C89E1 ; COPY_R12_to_RCX # arg1 = fin 6A 01 ; PUSH !1 # size = 1 4889E2 ; COPY_RSP_to_RDX # arg2 = &size 56 ; PUSH_RSI # allocate stack 4989E0 ; COPY_RSP_to_R8 # arg3 = &c 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function 50 ; PUSH_RAX # allocate shadow stack space for UEFI function FF51 20 ; CALL_RCX_Immediate8 !32 # fin->read() 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # deallocate stack 58 ; POP_RAX # save c to rax 59 ; POP_RCX # save size to rcx # If the file ended (0 bytes read) terminate 85C9 ; TEST_ECX_ECX # if size = 0 74 !terminate ; JE8 !terminate # then we are done C3 ; RET # return # Protocol GUIDs :LOADED_IMAGE_PROTOCOL A1 31 1B 5B ; %0x5b1b31a1:SIMPLE_FS_PROTOCOL 62 95 ; @0x9562 22 5B 4E 96 ; %0x0964e5b22 D2 11 ; @0x11d2 59 64 ; @0x6459 :LOADED_IMAGE_PROTOCOL_8 8E 3F 00 A0 C9 69 72 3B ; !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :SIMPLE_FS_PROTOCOL 22 5B 4E 96 ; %0x0964e5b22 59 64 ; @0x6459 D2 11 ; @0x11d2 :SIMPLE_FS_PROTOCOL_8 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :FILE_INFO_PROTOCOL 92 6E 57 09 ; %0x09576e92 3F 6D ; @0x6d3f D2 11 ; @0x11d2 # last 64-bits of GUID are identical to SIMPLE_FS_PROTOCOL :default_file 6B 00 61 00 65 00 6D 00 2E 00 61 00 6D 00 64 00 36 00 34 00 00 00 ; L"kaem.amd64" :prefix 20 00 2B 00 3E 00 20 00 00 00 ; L" +> " :subprocess_error 53 00 75 00 62 00 70 00 72 00 6F 00 63 00 65 00 73 00 73 00 20 00 65 00 72 00 72 00 6F 00 72 00 :suffix 0A 00 0D 00 00 00 ; L"Subprocess error\n\r" :image_handle 00 00 00 00 00 00 00 00 :image 00 00 00 00 00 00 00 00 :system_out 00 00 00 00 00 00 00 00 :PE32_end