diff --git a/Development/kaem-minimal.c b/Development/kaem-minimal.c index 0e76fa8..84a6385 100644 --- a/Development/kaem-minimal.c +++ b/Development/kaem-minimal.c @@ -55,6 +55,8 @@ efi_status_t efi_main(efi_handle_t image_handle, struct efi_system_table *system struct efi_file_protocol *fin; efi_status_t status = rootdir->open(rootdir, &fin, script_file, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY); if(status != EFI_SUCCESS) { + system->boot->close_protocol(root_device, &guid2, image_handle, 0); + system->boot->close_protocol(image_handle, &guid1, image_handle, 0); return status; } @@ -78,8 +80,11 @@ efi_status_t efi_main(efi_handle_t image_handle, struct efi_system_table *system { fin->read(fin, &size, &c); if (size == 0) { - rootdir->close(fin); + fin->close(fin); + rootdir->close(rootdir); system->boot->free_pool(command); + system->boot->close_protocol(root_device, &guid2, image_handle, 0); + system->boot->close_protocol(image_handle, &guid1, image_handle, 0); return EFI_SUCCESS; } else if(c == '\n') { @@ -115,7 +120,10 @@ efi_status_t efi_main(efi_handle_t image_handle, struct efi_system_table *system efi_status_t status = rootdir->open(rootdir, &fcmd, command, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY); if(status != EFI_SUCCESS) { system->boot->free_pool(command); - rootdir->close(fin); + fin->close(fin); + rootdir->close(rootdir); + system->boot->close_protocol(root_device, &guid2, image_handle, 0); + system->boot->close_protocol(image_handle, &guid1, image_handle, 0); return status; } @@ -129,7 +137,7 @@ efi_status_t efi_main(efi_handle_t image_handle, struct efi_system_table *system file_size = file_info->file_size; system->boot->free_pool(file_info); - system->boot->allocate_pool(EFI_LOADER_CODE, file_size, (void **) &executable); + system->boot->allocate_pool(EFI_LOADER_DATA, file_size, (void **) &executable); fcmd->read(fcmd, &file_size, executable); fcmd->close(fcmd); @@ -138,7 +146,7 @@ efi_status_t efi_main(efi_handle_t image_handle, struct efi_system_table *system device_path->type = HARDWARE_DEVICE_PATH; device_path->subtype = MEMORY_MAPPED; device_path->length = sizeof(struct efi_device_path_protocol); - device_path->memory_type = EFI_LOADER_CODE; + device_path->memory_type = EFI_LOADER_DATA; device_path->start_address = (uint64_t) executable; device_path->end_address = (uint64_t) executable + file_size; device_path[1].type = END_HARDWARE_DEVICE_PATH; @@ -154,6 +162,7 @@ efi_status_t efi_main(efi_handle_t image_handle, struct efi_system_table *system child_image->load_options = command; child_image->load_options_size = 2 * (i + 1); child_image->device = image->device; + system->boot->close_protocol(child_ih, &guid1, child_ih, 0); /* Run command */ return_code = system->boot->start_image(child_ih, 0, 0); @@ -161,7 +170,10 @@ efi_status_t efi_main(efi_handle_t image_handle, struct efi_system_table *system if(return_code != 0) { system->boot->free_pool(command); system->out->output_string(system->out, L"Subprocess error.\r\n"); - rootdir->close(fin); + fin->close(fin); + rootdir->close(rootdir); + system->boot->close_protocol(root_device, &guid2, image_handle, 0); + system->boot->close_protocol(image_handle, &guid1, image_handle, 0); return return_code; } } while(true); diff --git a/amd64/Development/hex2.M1 b/amd64/Development/hex2.M1 index 9d0c2cb..42c8028 100644 --- a/amd64/Development/hex2.M1 +++ b/amd64/Development/hex2.M1 @@ -110,9 +110,9 @@ DEFINE sub_rbx, 4883EB DEFINE sub_rsp, 4883EC DEFINE sub_rax,rdx 4829D0 DEFINE test_esi_esi 85F6 -DEFINE xor_eax_eax 31C0 -DEFINE xor_edx_edx 31D2 -DEFINE xor_esi_esi 31F6 +DEFINE xor_eax,eax 31C0 +DEFINE xor_edx,edx 31D2 +DEFINE xor_esi,esi 31F6 DEFINE xor_r9,r9 4D31C9 # Register usage: @@ -223,7 +223,7 @@ DEFINE xor_r9,r9 4D31C9 # rewind input file push_r11 # Protect r11 mov_rcx,[rip+DWORD] %fin # Using our input file - xor_edx_edx # Offset Zero + xor_edx,edx # Offset Zero push_rax # allocate shadow stack space for UEFI function push_rax # allocate shadow stack space for UEFI function call_[rcx+BYTE] !56 # fin->set_position(fin, 0) @@ -481,7 +481,7 @@ DEFINE xor_r9,r9 4D31C9 mov_rcx,[rip+DWORD] %fin # arg1 = fin push !1 # size = 1 mov_rdx,rsb # arg2 = &size - xor_esi_esi # zero rsi + xor_esi,esi # zero rsi push_rsi # allocate stack mov_rsp,r8 # arg3 = &input push_rax # allocate shadow stack space for UEFI function @@ -688,7 +688,7 @@ DEFINE xor_r9,r9 4D31C9 jmp %terminate :Done - xor_eax_eax # Set exit code 0 + xor_eax,eax # Set exit code 0 :terminate push_rax # save exit code diff --git a/amd64/Development/kaem-minimal.M1 b/amd64/Development/kaem-minimal.M1 index bc3951f..bd059ad 100644 --- a/amd64/Development/kaem-minimal.M1 +++ b/amd64/Development/kaem-minimal.M1 @@ -3,527 +3,520 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -DEFINE ADD_RBX_to_R15 4901DF -DEFINE ADD_RDI_to_R15 4901FF -DEFINE ADD_RSI_to_RBX 4801F3 -DEFINE ADDI8_RAX 4883C0 -DEFINE ADDI8_RBX 4883C3 -DEFINE ADDI8_RSI 4883C6 -DEFINE ADDI8_RSP 4883C4 -DEFINE CALLI32 E8 -DEFINE CALL_RCX_Immediate8 FF51 -DEFINE CALL_R14_Immediate8 41FF56 -DEFINE CALL_R14_Immediate32 41FF96 -DEFINE CMPI8_AL 3C -DEFINE COPY_RAX_to_RCX 4889C1 -DEFINE COPY_RBX_to_RCX 4889D9 -DEFINE COPY_RBX_to_RDX 4889DA -DEFINE COPY_RBX_to_R8 4989D8 -DEFINE COPY_RBX_to_R12 4989DC -DEFINE COPY_RBP_to_RSP 4889EC -DEFINE COPY_RDI_to_RCX 4889F9 -DEFINE COPY_RDI_to_R9 4989F9 -DEFINE COPY_RSI_to_R15 4989F7 -DEFINE COPY_RSP_to_RDX 4889E2 -DEFINE COPY_RSP_to_RBP 4889E5 -DEFINE COPY_RSP_to_R8 4989E0 -DEFINE COPY_R8_to_RAX 4C89C0 -DEFINE COPY_R9_to_RCX 4C89C9 -DEFINE COPY_R12_to_RCX 4C89E1 -DEFINE COPY_R12_to_R8 4D89E0 -DEFINE COPY_R13_to_RCX 4C89E9 -DEFINE COPY_R15_to_RCX 4C89F9 -DEFINE COPY_R15_to_R8 4D89F8 -DEFINE COPY_R15_to_R9 4D89F9 -DEFINE INC_RAX 48FFC0 -DEFINE JE8 74 -DEFINE JMP8 EB -DEFINE JMP32 E9 -DEFINE JNE8 75 -DEFINE JNE32 0F85 -DEFINE LEA_RDX_rel 488D15 -DEFINE LEA_R12_rel 4C8D25 -DEFINE LOAD64_into_RAX_from_Address_RDX_Immediate8 488B42 -DEFINE LOAD64_into_RAX_from_Address_RSP_Immediate8 488B4424 -DEFINE LOAD64_into_RBX_from_Address_RAX_Immediate8 488B58 -DEFINE LOAD64_into_RBX_from_Address_RSP_Immediate8 488B5C24 -DEFINE LOAD64_into_RCX_from_Address_RCX_Immediate8 488B49 -DEFINE LOAD64_into_RCX_from_Address_RSP_Immediate8 488B4C24 -DEFINE LOAD64_into_RDX_from_Address_RCX_Immediate8 488B51 -DEFINE LOAD64_into_R14_from_Address_RDX_Immediate8 4C8B72 -DEFINE LOAD64_into_R12_from_Address_RSP_Immediate8 4C8B6424 -DEFINE LOAD64_into_RDX_rel32 488B15 -DEFINE LOAD64_into_R9_rel32 4C8B0D -DEFINE LOAD8_AL_from_Address_RBX 8A03 -DEFINE LOADI8_DH B6 -DEFINE LOAD64_rel_RCX 488B0D -DEFINE LOAD64_rel_RDX 488B15 -DEFINE POP_RAX 58 -DEFINE POP_RBX 5B -DEFINE POP_RCX 59 -DEFINE POP_RDX 5A -DEFINE POP_RSI 5E -DEFINE POP_RDI 5F -DEFINE POP_R8 4158 -DEFINE POP_R9 4159 -DEFINE POP_R13 415D -DEFINE POP_R14 415E -DEFINE POP_R15 415F -DEFINE PUSH 6A -DEFINE PUSH_RAX 50 -DEFINE PUSH_RDX 52 -DEFINE PUSH_RBX 53 -DEFINE PUSH_RSP 54 -DEFINE PUSH_RSI 56 -DEFINE PUSH_RDI 57 -DEFINE PUSH_R8 4150 -DEFINE PUSH_R9 4151 -DEFINE RET C3 -DEFINE STORE16_AX_into_Address_RBX 668903 -DEFINE STORE64_R15_into_Address_RAX 4C8938 -DEFINE STORE64_from_RAX_rel32 488905 -DEFINE STORE64_from_RCX_rel32 48890D -DEFINE STORE64_from_RBX_into_Address_RAX_Immediate8 488958 -DEFINE STORE64_from_RCX_into_Address_RCX_Immediate8 488948 -DEFINE STORE64_from_RSI_into_Address_RAX_Immediate8 488970 -DEFINE STOREI8_into_Address_RAX C600 -DEFINE STOREI16_into_Address_RAX 66C700 -DEFINE STOREI32_into_Address_RAX C700 -DEFINE STOREI16_into_Address_RBX 66C703 -DEFINE STOREI16_into_Address_R15 6641C707 -DEFINE STOREI32_into_Address_R8 49C700 -DEFINE SUBI8_RSP 4883EC -DEFINE SUB_RDI_from_R15 4929FF -DEFINE SUB_RSI_from_RBX 4829F3 -DEFINE TEST_AL_AL 84C0 -DEFINE TEST_EAX_EAX 85C0 -DEFINE TEST_ECX_ECX 85C9 -DEFINE TEST_R15_R15 4D85FF -DEFINE XOR_ECX_ECX 31C9 -DEFINE XOR_EDX_EDX 31D2 -DEFINE XOR_ESI_ESI 31F6 -DEFINE XOR_R8_R8 4D31C0 -DEFINE XOR_R9_R9 4D31C9 -DEFINE XOR_R15_R15 4D31FF +DEFINE add_rax, 4883C0 +DEFINE add_rsp, 4883C4 +DEFINE add_rbx, 4883C3 +DEFINE add_rsi, 4883C6 +DEFINE add_rbx,rsi 4801F3 +DEFINE add_r15,rbx 4901DF +DEFINE add_r15,rdi 4901FF +DEFINE add_rbx,[rdi+BYTE] 48035F +DEFINE call E8 +DEFINE call_[rcx+BYTE] FF51 +DEFINE call_[r14+BYTE] 41FF56 +DEFINE call_[r14+DWORD] 41FF96 +DEFINE cmp_al, 3C +DEFINE cmp_rbx,rdx 4839D3 +DEFINE inc_rax 48FFC0 +DEFINE je8 74 +DEFINE jmp8 EB +DEFINE jmp E9 +DEFINE jne8 75 +DEFINE jne 0F85 +DEFINE lea_rdx,[rip+DWORD] 488D15 +DEFINE lea_r8,[rip+DWORD] 4C8D05 +DEFINE mov_dh, B6 +DEFINE mov_rbp,rsp 4889E5 +DEFINE mov_rbx,rax 4889C3 +DEFINE mov_rbx,rcx 4889CB +DEFINE mov_rcx,rax 4889C1 +DEFINE mov_rcx,rbx 4889D9 +DEFINE mov_rcx,rdi 4889F9 +DEFINE mov_rcx,r8 4C89C1 +DEFINE mov_rcx,r9 4C89C9 +DEFINE mov_rcx,r12 4C89E1 +DEFINE mov_rcx,r15 4C89F9 +DEFINE mov_rdi,rax 4889C7 +DEFINE mov_rdx,rbx 4889DA +DEFINE mov_rdx,rsp 4889E2 +DEFINE mov_rsp,rbp 4889EC +DEFINE mov_r8,rax 4989C0 +DEFINE mov_r8,rbx 4989D8 +DEFINE mov_r8,rdi 4989F8 +DEFINE mov_r8,rsp 4989E0 +DEFINE mov_r8,r15 4D89F8 +DEFINE mov_r9,rax 4989C1 +DEFINE mov_r9,rbx 4989D9 +DEFINE mov_r9,rdi 4989F9 +DEFINE mov_r9,r15 4D89F9 +DEFINE mov_r15,rsi 4989F7 +DEFINE mov_r15,rax 4989C7 +DEFINE mov_[rax], C700 +DEFINE mov_[rbx], C603 +DEFINE mov_[r8], 49C700 +DEFINE mov_[rax],BYTE C600 +DEFINE mov_[rax],WORD 66C700 +DEFINE mov_[rbx],WORD 66C703 +DEFINE mov_[r15],WORD 6641C707 +DEFINE mov_al,[rbx] 8A03 +DEFINE mov_[rax],r15 4C8938 +DEFINE mov_[rbx],ax 668903 +DEFINE mov_rax,[rdx+BYTE] 488B42 +DEFINE mov_rbx,[rdi+BYTE] 488B5F +DEFINE mov_rcx,[rcx+BYTE] 488B49 +DEFINE mov_rcx,[rdi+BYTE] 488B4F +DEFINE mov_rdx,[rcx+BYTE] 488B51 +DEFINE mov_r12,[rsp+BYTE] 4C8B6424 +DEFINE mov_r14,[rdx+BYTE] 4C8B72 +DEFINE mov_rcx,[rip+DWORD] 488B0D +DEFINE mov_rdx,[rip+DWORD] 488B15 +DEFINE mov_r8,[rip+DWORD] 4C8B05 +DEFINE mov_[rax+BYTE],rbx 488958 +DEFINE mov_[rax+BYTE],rcx 488948 +DEFINE mov_[rax+BYTE],rsi 488970 +DEFINE mov_[rip+DWORD],rcx 48890D +DEFINE mov_[rip+DWORD],rax 488905 +DEFINE pop_rax 58 +DEFINE pop_rcx 59 +DEFINE pop_rdi 5F +DEFINE pop_rdx 5A +DEFINE pop_r8 4158 +DEFINE pop_r9 4159 +DEFINE push 6A +DEFINE push_rax 50 +DEFINE push_rbx 53 +DEFINE push_rdi 57 +DEFINE push_rdx 52 +DEFINE push_rsi 56 +DEFINE push_rsp 54 +DEFINE push_r8 4150 +DEFINE ret C3 +DEFINE sub_rbx, 4883EB +DEFINE sub_rsp, 4883EC +DEFINE sub_rbx,rsi 4829F3 +DEFINE sub_r15,rdi 4929FF +DEFINE test_eax,eax 85C0 +DEFINE test_ecx,ecx 85C9 +DEFINE test_r8,r8 4D85C0 +DEFINE test_r15,r15 4D85FF +DEFINE xor_ecx,ecx 31C9 +DEFINE xor_edx,edx 31D2 +DEFINE xor_esi,esi 31F6 +DEFINE xor_r8,r8 4D31C0 +DEFINE xor_r9,r9 4D31C9 +DEFINE xor_r15,r15 4D31FF # efi_main(void *image_handle, struct efi_system_table *system) :_start - COPY_RSP_to_RBP # save stack pointer - STORE64_from_RCX_rel32 %image_handle # save image_handle - LOAD64_into_RAX_from_Address_RDX_Immediate8 !64 # system->out - STORE64_from_RAX_rel32 %system_out # save system->out - LOAD64_into_R14_from_Address_RDX_Immediate8 !96 # system->boot + mov_rbp,rsp # save stack pointer + mov_[rip+DWORD],rcx %image_handle # save image_handle + mov_rbx,rcx # save image_handle + mov_rax,[rdx+BYTE] !64 # system->out + mov_[rip+DWORD],rax %system_out # save system->out + mov_r14,[rdx+BYTE] !96 # system->boot - XOR_ECX_ECX # timeout = 0 - XOR_EDX_EDX # watchdog_code = 0 - XOR_R8_R8 # data_size = 0 - XOR_R9_R9 # watchdog_data = 0 - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_R14_Immediate32 %240 # system->boot->set_watchdog_timer + xor_ecx,ecx # timeout = 0 + xor_edx,edx # watchdog_code = 0 + xor_r8,r8 # data_size = 0 + xor_r9,r9 # watchdog_data = 0 + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[r14+DWORD] %240 # system->boot->set_watchdog_timer # Open Loaded Image protocol - PUSH_RAX # allocate stack for image - COPY_RSP_to_R8 # arg3 = &image - LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL_8 # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) - PUSH_RDX # push last 64 bits onto stack - LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) - PUSH_RDX # push first 64 bits onto stack - COPY_RSP_to_RDX # arg2 = &guid - PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - PUSH !0 # arg5 = NULL - LOAD64_into_R9_rel32 %image_handle # arg4 = image_handle - COPY_R9_to_RCX # arg1 = image_handle - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_R14_Immediate32 %280 # system->boot->open_protocol(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - LOAD64_into_RAX_from_Address_RSP_Immediate8 !64 # get_image - STORE64_from_RAX_rel32 %image # save image + mov_r9,rbx # arg4 = image_handle + lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + mov_rcx,rbx # arg1 = image_handle + call %open_protocol # open protocol + mov_rdi,rax # save image + mov_[rip+DWORD],rax %image # save image - # Command line args - COPY_RAX_to_RCX # copy image to rcx - LOAD64_into_RBX_from_Address_RAX_Immediate8 !56 # options = image->load_options - - # Skip application name -:loop_options1 - ADDI8_RBX !2 # ++options - LOAD8_AL_from_Address_RBX # *options - CMPI8_AL !0x20 # if *options == ' ' - JE8 !loop_options2 # then jump - TEST_AL_AL # if options != 0 - JNE8 !loop_options1 # then loop - - # Use default file - LEA_R12_rel %default_file # Use "kaem.amd64" - JMP8 !root_fs # jump - -:loop_options2 - ADDI8_RBX !2 # ++options - COPY_RBX_to_R12 # save input file - -:root_fs # Get root file system - PUSH_RAX # allocate stack for rootfs - COPY_RSP_to_R8 # arg3 = &rootfs - LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL_8 # SIMPLE_FS_PROTOCOL (last 64 bits) - PUSH_RDX # push last 64 bits onto stack - LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL # SIMPLE_FS_PROTOCOL (first 64 bits) - PUSH_RDX # push first 64 bits onto stack - COPY_RSP_to_RDX # arg2 = &guid - PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - PUSH !0 # arg5 = NULL - LOAD64_into_R9_rel32 %image_handle # arg4 = image_handle - LOAD64_into_RCX_from_Address_RCX_Immediate8 !24 # arg1 = root_device = image->device - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_R14_Immediate32 %280 # system->boot->open_protocol(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - LOAD64_into_RCX_from_Address_RSP_Immediate8 !64 # get rootfs + mov_r9,rbx # arg4 = image_handle + lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device + mov_[rip+DWORD],rcx %root_device # save root_device + call %open_protocol # open protocol + mov_rcx,rax # get rootfs # Get root directory - PUSH_RDX # allocate stack for rootdir - COPY_RSP_to_RDX # arg2 = &rootdir - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # rootfs->open_volume(rootfs, &rootdir) - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_R13 # save rootdir + lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) + pop_rax # deallocate stack + pop_rax # deallocate stack + + # Push command line arguments onto stack + mov_rbx,[rdi+BYTE] !56 # options = image->load_options + mov_rdx,rbx # save beginning of load_options + add_rbx,[rdi+BYTE] !48 # go to the end of load_options + push !0 # Save end of arguments (NULL) onto stack +:loop_options + cmp_rbx,rdx # Check if we are done + je8 !loop_options_done # We are done + sub_rbx, !2 # --options + mov_al,[rbx] # *options + cmp_al, !0x20 # if *options != ' ' + jne8 !loop_options # then continue looping + mov_[rbx], !0 # zero it + add_rbx, !2 # ++options + push_rbx # push another argument onto stack + jmp8 !loop_options # next argument +:loop_options_done + + pop_r8 # get input file + test_r8,r8 # Check if argument is specified + jne8 !arg_done # then use it + # Else use default_file + lea_r8,[rip+DWORD] %default_file # Use "kaem.amd64" +:arg_done # Open file for reading - PUSH_RDX # allocate stack for fin - COPY_RSP_to_RDX # arg2 = &fin - PUSH !1 # arg5 = EFI_FILE_READ_ONLY - PUSH !1 # prepare to set arg4 to EFI_FILE_MODE_READ - POP_R9 # arg4 = EFI_FILE_MODE_READ - COPY_R12_to_R8 # arg3 = in - COPY_R13_to_RCX # arg1 = rootdir - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # rootdir->open() - TEST_EAX_EAX # if status != EFI_SUCCESS - JNE32 %abort # then exit without closing file - LOAD64_into_R12_from_Address_RSP_Immediate8 !40 # get fin + push_rdx # allocate stack for fin + mov_rdx,rsp # arg2 = &fin + push !1 # arg5 = EFI_FILE_READ_ONLY + push !1 # prepare to set arg4 to EFI_FILE_MODE_READ + pop_r9 # arg4 = EFI_FILE_MODE_READ + # arg3 = script + mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !8 # rootdir->open() + test_eax,eax # if status != EFI_SUCCESS + jne %abort # then exit without closing file + mov_r12,[rsp+BYTE] !40 # get fin # Allocate pool for command - PUSH_RDX # allocate stack for command - COPY_RSP_to_R8 # arg3 = &command - XOR_EDX_EDX # zero RDX - LOADI8_DH !0x10 # arg2 = 4096 = 0x1000 - PUSH !2 - POP_RCX # arg1 = EFI_LOADER_DATA - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 4096, &commmand) - LOAD64_into_RBX_from_Address_RSP_Immediate8 !24 # get command + xor_edx,edx # zero RDX + mov_dh, !0x10 # arg2 = 4096 = 0x1000 + call %allocate_pool # allocate memory + mov_rbx,rax # get command :next_command - XOR_ESI_ESI # i = 0 - XOR_R15_R15 # command_length = 0 + xor_esi,esi # i = 0 + xor_r15,r15 # command_length = 0 :read_command - CALLI32 %read_byte # read another byte c + call %read_byte # read another byte c - CMPI8_AL !0xa # if c == '\n' - JE8 !read_command_done # then we are done with this command + cmp_al, !0xa # if c == '\n' + je8 !read_command_done # then we are done with this command - CMPI8_AL !0x20 # if c == ' ' - JNE8 !read_command_comments - TEST_R15_R15 # and command_length == 0 - JNE8 !read_command_comments - COPY_RSI_to_R15 # command_length = i + cmp_al, !0x20 # if c == ' ' + jne8 !read_command_comments + test_r15,r15 # and command_length == 0 + jne8 !read_command_comments + mov_r15,rsi # command_length = i :read_command_comments - CMPI8_AL !0x23 # if c == '#' then process comment - JNE8 !read_command_store_char # else store char + cmp_al, !0x23 # if c == '#' then process comment + jne8 !read_command_store_char # else store char :read_command_skip_comment - CALLI32 %read_byte # get another char - CMPI8_AL !0xa # if c == '\n' - JNE8 !read_command_skip_comment # continue reading until newline + call %read_byte # get another char + cmp_al, !0xa # if c == '\n' + jne8 !read_command_skip_comment # continue reading until newline - JMP8 !next_command # deal with another line + jmp8 !next_command # deal with another line :read_command_store_char - ADD_RSI_to_RBX # rbx = &command[i] - STORE16_AX_into_Address_RBX # command[i] = c - SUB_RSI_from_RBX # rbx = &command[0] - ADDI8_RSI !2 # location of the next char - JMP8 !read_command # continue looping + add_rbx,rsi # rbx = &command[i] + mov_[rbx],ax # command[i] = c + sub_rbx,rsi # rbx = &command[0] + add_rsi, !2 # location of the next char + jmp8 !read_command # continue looping :read_command_done - TEST_R15_R15 # if command_length == 0 - JE8 !next_command # deal with another line + test_r15,r15 # if command_length == 0 + je8 !next_command # deal with another line - ADD_RSI_to_RBX # rbx = &command[i] - STOREI16_into_Address_RBX @0 # command[i] = 0 - SUB_RSI_from_RBX # rbx = &command[0] + add_rbx,rsi # rbx = &command[i] + mov_[rbx],WORD @0 # command[i] = 0 + sub_rbx,rsi # rbx = &command[0] - ADDI8_RSI !2 # add 2 to get string length with NULL terminator + add_rsi, !2 # add 2 to get string length with NULL terminator - LEA_RDX_rel %prefix # get prefix " +> " - CALLI32 %File_Print # print it - COPY_RBX_to_RDX # get command - CALLI32 %File_Print # print it - LEA_RDX_rel %suffix # get suffix "\n\r" - CALLI32 %File_Print # print it + lea_rdx,[rip+DWORD] %prefix # get prefix " +> " + call %File_Print # print it + mov_rdx,rbx # get command + call %File_Print # print it + lea_rdx,[rip+DWORD] %suffix # get suffix "\n\r" + call %File_Print # print it # Remove command line options - ADD_RBX_to_R15 # go to the space separating command and its options - STOREI16_into_Address_R15 @0 # zero it to hide command line options + add_r15,rbx # go to the space separating command and its options + mov_[r15],WORD @0 # zero it to hide command line options # Open executable file for reading - PUSH_RDX # allocate stack for fcmd - COPY_RSP_to_RDX # arg2 = &fcmd - PUSH !1 # arg5 = EFI_FILE_READ_ONLY - PUSH !1 # prepare to set arg4 to EFI_FILE_MODE_READ - POP_R9 # arg4 = EFI_FILE_MODE_READ - COPY_RBX_to_R8 # arg3 = command - COPY_R13_to_RCX # arg1 = rootdir - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # rootdir->open() - TEST_EAX_EAX # if status != EFI_SUCCESS - JNE32 %print_error # then exit - ADDI8_RSP !40 # deallocate stack - POP_RDI # get fcmd + push_rdx # allocate stack for fcmd + mov_rdx,rsp # arg2 = &fcmd + push !1 # arg5 = EFI_FILE_READ_ONLY + push !1 # prepare to set arg4 to EFI_FILE_MODE_READ + pop_r9 # arg4 = EFI_FILE_MODE_READ + mov_r8,rbx # arg3 = command + mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !8 # rootdir->open() + test_eax,eax # if status != EFI_SUCCESS + jne %print_error # then exit + add_rsp, !40 # deallocate stack + pop_rdi # get fcmd # Restore command line arguments - STOREI16_into_Address_R15 @0x20 # restore command line options by readding ' ' + mov_[r15],WORD @0x20 # restore command line options by readding ' ' # Allocate pool for file_info - PUSH_RDX # allocate stack for file_info - COPY_RSP_to_R8 # arg3 = &file_info - XOR_EDX_EDX # zero RDX - LOADI8_DH !0x10 # arg2 = 4096 = 0x1000 - PUSH !2 - POP_RCX # arg1 = EFI_LOADER_DATA - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 4096, &file_info) - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_R9 # get file_info (arg4 for get_info) + xor_edx,edx # zero RDX + mov_dh, !0x10 # arg2 = 4096 = 0x1000 + call %allocate_pool # allocate memory + mov_r9,rax # get file_info (arg4 for get_info) # Get file info - PUSH_R9 # save file_info - PUSH_RAX # allocate stack for file_size - COPY_RSP_to_R8 # arg3 = &file_size - STOREI32_into_Address_R8 %0x1000 # file_size = 0x1000 - LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL_8 # EFI_FILE_INFO_PROTOCOL (last 64 bits) - PUSH_RDX # push last 64 bits onto stack - LOAD64_rel_RDX %FILE_INFO_PROTOCOL # EFI_FILE_INFO_PROTOCOL (first 64 bits) - PUSH_RDX # push first 64 bits onto stack - COPY_RSP_to_RDX # arg2 = &guid - COPY_RDI_to_RCX # arg1 = fcmd - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !64 # fcmd->get_info(fcmd, &guid, &file_size, file_info) - ADDI8_RSP !56 # deallocate stack - POP_RCX # restore file_info - LOAD64_into_RDX_from_Address_RCX_Immediate8 !8 # get file_size + push_rax # save file_info + push_rax # allocate stack for file_size + mov_r8,rsp # arg3 = &file_size + mov_[r8], %0x1000 # file_size = 0x1000 + lea_rdx,[rip+DWORD] %FILE_INFO_PROTOCOL # arg2 = &EFI_FILE_INFO_PROTOCOL + mov_rcx,rdi # arg1 = fcmd + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !64 # fcmd->get_info(fcmd, &guid, &file_size, file_info) + add_rsp, !40 # deallocate stack + pop_rcx # restore file_info + mov_rdx,[rcx+BYTE] !8 # get file_size # Free file_info pool - PUSH_RDX # save file_size onto stack - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_R14_Immediate8 !72 # system->boot->free_pool(file_info) - POP_RAX # deallocate stack - POP_RDX # restore file_size from stack (arg2 for allocate_pool) + push_rdx # save file_size onto stack + push_rax # allocate shadow stack space for UEFI function + call_[r14+BYTE] !72 # system->boot->free_pool(file_info) + pop_rax # deallocate stack + pop_rdx # restore file_size from stack (arg2 for allocate_pool) # Allocate pool for executable - PUSH_RDX # save file_size onto stack - PUSH_RDX # allocate stack for executable - COPY_RSP_to_R8 # arg3 = &executable - PUSH !2 - POP_RCX # arg1 = EFI_LOADER_DATA - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, file_size, &executable) - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_R15 # get executable - POP_RDX # restore file_size + push_rdx # save file_size onto stack + call %allocate_pool # allocate memory + mov_r15,rax # get executable + pop_rdx # restore file_size # Load executable into memory - PUSH_RDX # save file_size onto stack - COPY_R15_to_R8 # arg3 = executable - COPY_RSP_to_RDX # arg2 = &file_size - COPY_RDI_to_RCX # arg1 = fcmd - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - CALL_RCX_Immediate8 !32 # fcmd->read(fcmd, &file_size, executable) - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RAX # deallocate stack + push_rdx # save file_size onto stack + mov_r8,r15 # arg3 = executable + mov_rdx,rsp # arg2 = &file_size + mov_rcx,rdi # arg1 = fcmd + push_rax # allocate shadow stack space for UEFI + push_rax # allocate shadow stack space for UEFI + push_rax # allocate shadow stack space for UEFI + call_[rcx+BYTE] !32 # fcmd->read(fcmd, &file_size, executable) + pop_rax # deallocate stack + pop_rax # deallocate stack + pop_rax # deallocate stack # Close fcmd - PUSH_RAX # allocate stack - COPY_RDI_to_RCX # arg1 = fcmd - CALL_RCX_Immediate8 !16 # fcmd->close(fcmd) - POP_RAX # restore stack + push_rax # allocate stack + mov_rcx,rdi # arg1 = fcmd + call_[rcx+BYTE] !16 # fcmd->close(fcmd) + pop_rax # restore stack - POP_RDI # restore file_size + pop_rdi # restore file_size # Allocate memory for device_path struct - PUSH_RDX # allocate stack for device_path - COPY_RSP_to_R8 # arg3 = &device_path - PUSH !28 # 4 + sizeof(struct efi_device_path_protocol) - POP_RDX # arg2 = 28 - PUSH !2 - POP_RCX # arg1 = EFI_LOADER_DATA - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 28, &device_path) - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_R8 # get device_path + push !28 # 4 + sizeof(struct efi_device_path_protocol) + pop_rdx # arg2 = 28 + call %allocate_pool # allocate memory + mov_r8,rax # get device_path # Initialize struct - COPY_R8_to_RAX # Make a pointer to device_path members - STOREI8_into_Address_RAX !1 # device_path->type = HARDWARE_DEVICE_PATH - INC_RAX # next member - STOREI8_into_Address_RAX !3 # device_path->subtype = MEMORY_MAPPED - INC_RAX # next member - STOREI16_into_Address_RAX @24 # device_path->length = 24 - ADDI8_RAX !2 # next member - STOREI32_into_Address_RAX %1 # device_path->memory_type = EFI_LOADER_CODE - ADDI8_RAX !4 # next member - STORE64_R15_into_Address_RAX # device_path->start_address = executable - ADDI8_RAX !8 # next member - ADD_RDI_to_R15 # end_address = executable + file_size - STORE64_R15_into_Address_RAX # device_path->end_address = end_address - SUB_RDI_from_R15 # restore r15 = executable - ADDI8_RAX !8 # next member - STOREI8_into_Address_RAX !0x7f # device_path[1].type = END_HARDWARE_DEVICE_PATH - INC_RAX # next member - STOREI8_into_Address_RAX !0xff # device_path[1].subtype = END_ENTIRE_DEVICE_PATH - INC_RAX # next member - STOREI16_into_Address_RAX @4 # device_path[1].length = 4 + mov_[rax],BYTE !1 # device_path->type = HARDWARE_DEVICE_PATH + inc_rax # next member + mov_[rax],BYTE !3 # device_path->subtype = MEMORY_MAPPED + inc_rax # next member + mov_[rax],WORD @24 # device_path->length = 24 + add_rax, !2 # next member + mov_[rax], %1 # device_path->memory_type = EFI_LOADER_CODE + add_rax, !4 # next member + mov_[rax],r15 # device_path->start_address = executable + add_rax, !8 # next member + add_r15,rdi # end_address = executable + file_size + mov_[rax],r15 # device_path->end_address = end_address + sub_r15,rdi # restore r15 = executable + add_rax, !8 # next member + mov_[rax],BYTE !0x7f # device_path[1].type = END_HARDWARE_DEVICE_PATH + inc_rax # next member + mov_[rax],BYTE !0xff # device_path[1].subtype = END_ENTIRE_DEVICE_PATH + inc_rax # next member + mov_[rax],WORD @4 # device_path[1].length = 4 # Load image - PUSH_R8 # save device_path - PUSH_RAX # allocate stack for child_ih - PUSH_RSP # arg6 = &child_ih - PUSH_RDI # arg5 = file size - COPY_R15_to_R9 # arg4 = executable - # arg3 = device_path - LOAD64_into_RDX_rel32 %image_handle # arg2 = image_handle - XOR_ECX_ECX # arg1 = 0 - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_R14_Immediate32 %200 # system->boot->load_image() - ADDI8_RSP !48 # deallocate stack - POP_RDI # save child_ih + push_r8 # save device_path + push_rax # allocate stack for child_ih + push_rsp # arg6 = &child_ih + push_rdi # arg5 = file size + mov_r9,r15 # arg4 = executable + # arg3 = device_path + mov_rdx,[rip+DWORD] %image_handle # arg2 = image_handle + xor_ecx,ecx # arg1 = 0 + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[r14+DWORD] %200 # system->boot->load_image() + add_rsp, !48 # deallocate stack + pop_rdi # save child_ih # Free device_path pool - POP_RCX # arg1 = device_path - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_R14_Immediate8 !72 # system->boot->free_pool(device_path) - POP_RAX # deallocate stack + pop_rcx # arg1 = device_path + push_rax # allocate shadow stack space for UEFI function + call_[r14+BYTE] !72 # system->boot->free_pool(device_path) + pop_rax # deallocate stack # Free executable pool - COPY_R15_to_RCX # arg1 = executable - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_R14_Immediate8 !72 # system->boot->free_pool(executable) - POP_RAX # deallocate stack + mov_rcx,r15 # arg1 = executable + push_rax # allocate shadow stack space for UEFI function + call_[r14+BYTE] !72 # system->boot->free_pool(executable) + pop_rax # deallocate stack # Open Child Image - PUSH_RAX # allocate stack for child_image - COPY_RSP_to_R8 # arg3 = &child_image - LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL_8 # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) - PUSH_RDX # push last 64 bits onto stack - LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) - PUSH_RDX # push first 64 bits onto stack - COPY_RSP_to_RDX # arg2 = &guid - PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - PUSH !0 # arg5 = NULL - COPY_RDI_to_R9 # arg4 = child_ih - COPY_RDI_to_RCX # arg1 = child_ih - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_R14_Immediate32 %280 # system->boot->open_protocol(child_ih, &guid, &child_image, child_ih, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - ADDI8_RSP !64 # deallocate stack - POP_RAX # get child_image + mov_r9,rdi # arg4 = child_ih + lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + push_rdx # save &LOADED_IMAGE_PROTOCOL + mov_rcx,r9 # arg1 = child_ih + call %open_protocol # open protocol - STORE64_from_RBX_into_Address_RAX_Immediate8 !56 # child_image->load_options = command - STORE64_from_RSI_into_Address_RAX_Immediate8 !48 # set child_image->load_options_size - LOAD64_rel_RCX %image # get image - LOAD64_into_RCX_from_Address_RCX_Immediate8 !24 # image->device - STORE64_from_RCX_into_Address_RCX_Immediate8 !24 # child_image->device = image->device + mov_[rax+BYTE],rbx !56 # child_image->load_options = command + mov_[rax+BYTE],rsi !48 # set child_image->load_options_size + mov_rcx,[rip+DWORD] %image # get image + mov_rcx,[rcx+BYTE] !24 # image->device + mov_[rax+BYTE],rcx !24 # child_image->device = image->device + + mov_r8,rdi # arg3 = image_handle + pop_rdx # arg2 = &LOADED_IMAGE_PROTOCOL + mov_rcx,r8 # arg1 = image_handle + call %close_protocol # close protocol # Run command - XOR_R8_R8 # arg3 = 0 (ExitData) - XOR_EDX_EDX # arg2 = 0 (ExitData size) - COPY_RDI_to_RCX # arg1 = child_ih - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - PUSH_RAX # allocate shadow stack space for UEFI - CALL_R14_Immediate32 %208 # system->boot->start_image() - POP_RCX # deallocate stack - POP_RCX # deallocate stack - POP_RCX # deallocate stack + xor_r8,r8 # arg3 = 0 (ExitData) + xor_edx,edx # arg2 = 0 (ExitData size) + mov_rcx,rdi # arg1 = child_ih + push_rax # allocate shadow stack space for UEFI + push_rax # allocate shadow stack space for UEFI + push_rax # allocate shadow stack space for UEFI + call_[r14+DWORD] %208 # system->boot->start_image() + pop_rcx # deallocate stack + pop_rcx # deallocate stack + pop_rcx # deallocate stack - TEST_EAX_EAX # check if return code is 0 - JNE8 !print_error # print error and exit - JMP32 %next_command # process another line from kaem script + test_eax,eax # check if return code is 0 + jne8 !print_error # print error and exit + jmp %next_command # process another line from kaem script :print_error - PUSH_RAX # save exit code - LEA_RDX_rel %subprocess_error # get error message - CALLI32 %File_Print # print it - POP_RAX # restore exit code + push_rax # save exit code + lea_rdx,[rip+DWORD] %subprocess_error # get error message + call %File_Print # print it + pop_rax # restore exit code # Close script file and exit :terminate # Free pool - COPY_RBX_to_RCX # arg1 = command - PUSH_RAX # save exit code - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_R14_Immediate8 !72 # system->boot->free_pool(commmand) + mov_rcx,rbx # arg1 = command + push_rax # save exit code + push_rax # allocate shadow stack space for UEFI function + call_[r14+BYTE] !72 # system->boot->free_pool(commmand) - COPY_R12_to_RCX # arg1 = fin - CALL_RCX_Immediate8 !16 # fin->close(fin) - POP_RAX # deallocate stack - POP_RAX # restore exit code + mov_rcx,r12 # arg1 = fin + call_[rcx+BYTE] !16 # fin->close(fin) + + mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + call_[rcx+BYTE] !16 # rootdir->close(rootdir) + + pop_rax # deallocate stack + pop_rax # restore exit code # Exit without closing script file +:terminate_2 + mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle + push_r8 # save image_handle + lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + mov_rcx,[rip+DWORD] %root_device # arg1 = root_device + call %close_protocol # close protocol + + pop_r8 # arg3 = image_handle + lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + mov_rcx,r8 # arg1 = image_handle + call %close_protocol # close protocol + :abort - COPY_RBP_to_RSP # restore stack - RET + mov_rsp,rbp # restore stack + ret # return to UEFI # File_Print function # Receives WCHAR* in RDX :File_Print - LOAD64_rel_RCX %system_out # get system_out - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # system->out->output_string(system->out, WCHAR*) - POP_RAX # deallocate stack - POP_RAX # deallocate stack - RET + mov_rcx,[rip+DWORD] %system_out # get system_out + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !8 # system->out->output_string(system->out, WCHAR*) + pop_rax # deallocate stack + pop_rax # deallocate stack + ret # read_byte function # reads a single character :read_byte - COPY_R12_to_RCX # arg1 = fin - PUSH !1 # size = 1 - COPY_RSP_to_RDX # arg2 = &size - PUSH_RSI # allocate stack - COPY_RSP_to_R8 # arg3 = &c - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !32 # fin->read() - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RAX # save c to rax - POP_RCX # save size to rcx + mov_rcx,r12 # arg1 = fin + push !1 # size = 1 + mov_rdx,rsp # arg2 = &size + push_rsi # allocate stack + mov_r8,rsp # arg3 = &c + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !32 # fin->read() + pop_rax # deallocate stack + pop_rax # deallocate stack + pop_rax # deallocate stack + pop_rax # save c to rax + pop_rcx # save size to rcx # If the file ended (0 bytes read) terminate - TEST_ECX_ECX # if size = 0 - JE8 !terminate # then we are done + test_ecx,ecx # if size = 0 + je8 !terminate # then we are done - RET # return + ret # return + +# rcx: handle +# rdx: &guid +# r9: agent_handle +# returns interface +:open_protocol + push_rax # allocate stack for interface + mov_r8,rsp # arg3 = &interface + push !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + push !0 # arg5 = NULL + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[r14+DWORD] %280 # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + add_rsp, !48 # deallocate stack + pop_rax # get interface + ret + +# rcx: handle +# rdx: &guid +# r8: agent_handle +:close_protocol + xor_r9,r9 # arg4 = NULL + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[r14+DWORD] %288 # system->boot->close_protocol(handle, &guid, agent_handle, 0) + add_rsp, !32 # deallocate stack + ret + +# rdx: number of bytes to allocate +# r14: system->boot +# returns pointer in rax +:allocate_pool + push_rdx # allocate stack for pool pointer + mov_r8,rsp # arg3 = &pool + push !2 + pop_rcx # arg1 = EFI_LOADER_DATA + sub_rsp, !24 # allocate shadow stack space for UEFI + call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) + add_rsp, !24 # deallocate stack + pop_rax # get pool + ret # Protocol GUIDs @@ -531,21 +524,19 @@ DEFINE XOR_R15_R15 4D31FF %0x5b1b31a1 @0x9562 @0x11d2 -:LOADED_IMAGE_PROTOCOL_8 !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :SIMPLE_FS_PROTOCOL %0x0964e5b22 @0x6459 @0x11d2 -:SIMPLE_FS_PROTOCOL_8 !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :FILE_INFO_PROTOCOL %0x09576e92 @0x6d3f @0x11d2 -# last 64-bits of GUID are identical to SIMPLE_FS_PROTOCOL + !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :default_file "k" "a" "e" "m" "." "a" "m" "d" "6" "4" @0 @@ -565,6 +556,12 @@ DEFINE XOR_R15_R15 4D31FF :image %0 %0 +:rootdir + %0 %0 + +:root_device + %0 %0 + :system_out %0 %0 diff --git a/amd64/Development/kaem-minimal.S b/amd64/Development/kaem-minimal.S index fc379df..0961953 100644 --- a/amd64/Development/kaem-minimal.S +++ b/amd64/Development/kaem-minimal.S @@ -10,6 +10,7 @@ _start: mov rbp, rsp # save stack pointer mov [rip+image_handle], rcx # save image_handle + mov rbx, rcx # save image_handle mov rax, [rdx+64] # system->out mov [rip+system_out], rax # save system->out mov r14, [rdx+96] # system->boot @@ -22,69 +23,53 @@ _start: call [r14+240] # system->boot->set_watchdog_timer # Open Loaded Image protocol - push rax # allocate stack for image - mov r8, rsp # arg3 = &image - mov rdx, [rip+LOADED_IMAGE_PROTOCOL+8] # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) - push rdx # push last 64 bits onto stack - mov rdx, [rip+LOADED_IMAGE_PROTOCOL] # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) - push rdx # push first 64 bits onto stack - mov rdx, rsp # arg2 = &guid - push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - push 0 # arg5 = NULL - mov r9, [rip+image_handle] # arg4 = image_handle - mov rcx, r9 # arg1 = image_handle - sub rsp, 32 # allocate shadow stack space for UEFI function - call [r14+280] # system->boot->open_protocol(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - mov rax, [rsp+64] # get image + mov r9, rbx # arg4 = image_handle + lea rdx, [rip+LOADED_IMAGE_PROTOCOL] # guid = &LOADED_IMAGE_PROTOCOL + mov rcx, rbx # arg1 = image_handle + call open_protocol # open protocol + mov rdi, rax # save image mov [rip+image], rax # save image - # Command line args - mov rcx, rax # copy image to rcx - mov rbx, [rax+56] # options = image->load_options - - # Skip application name -loop_options1: - add rbx, 2 # ++options - mov al, [rbx] # *options - cmp al, 0x20 # if *options == ' ' - je loop_options2 # then jump - test al, al # if options != 0 - jne loop_options1 # then loop - - # Use default_file - lea r12, [rip+default_file] # Use "kaem.amd64" - jmp root_fs # jump - -loop_options2: - add rbx, 2 # ++options - mov r12, rbx # save script file - -root_fs: # Get root file system - push rax # allocate stack for rootfs - mov r8, rsp # arg3 = &rootfs - mov rdx, [rip+SIMPLE_FS_PROTOCOL+8] # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (last 64 bits) - push rdx # push last 64 bits onto stack - mov rdx, [rip+SIMPLE_FS_PROTOCOL] # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (first 64 bits) - push rdx # push first 64 bits onto stack - mov rdx, rsp # arg2 = &guid - push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - push 0 # arg5 = NULL - mov r9, [rip+image_handle] # arg4 = image_handle - mov rcx, [rcx+24] # arg1 = root_device = image->device - sub rsp, 32 # allocate shadow stack space for UEFI function - call [r14+280] # system->boot->open_protocol(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - mov rcx, [rsp+64] # get rootfs + mov r9, rbx # arg4 = image_handle + lea rdx, [rip+SIMPLE_FS_PROTOCOL] # guid = &SIMPLE_FS_PROTOCOL + mov rcx, [rdi+24] # arg1 = root_device = image->device + mov [rip+root_device], rcx # save root_device + call open_protocol # open protocol + mov rcx, rax # get rootfs # Get root directory - push rdx # allocate stack for rootdir - mov rdx, rsp # arg2 = &rootdir + lea rdx, [rip+rootdir] # arg2 = &rootdir push rax # allocate shadow stack space for UEFI function push rax # allocate shadow stack space for UEFI function call [rcx+8] # rootfs->open_volume(rootfs, &rootdir) pop rax # deallocate stack pop rax # deallocate stack - pop r13 # save rootdir + + # Push command line arguments onto stack + mov rbx, [rdi+56] # options = image->load_options + mov rdx, rbx # save beginning of load_options + add rbx, [rdi+48] # go to the end of load_options + push 0 # Save end of arguments (NULL) onto stack +loop_options: + cmp rbx, rdx # Check if we are done + je loop_options_done # We are done + sub rbx, 2 # --options + mov al, [rbx] # *options + cmp al, 0x20 # if *options != ' ' + jne loop_options # then continue looping + mov BYTE PTR [rbx], 0 # zero it + add rbx, 2 # ++options + push rbx # push another argument onto stack + jmp loop_options # next argument +loop_options_done: + + pop r8 # get input file + test r8, r8 # Check if argument is specified + jne arg_done # then use it + # Else use default_file + lea r8, [rip+default_file] # Use "kaem.amd64" +arg_done: # Open file for reading push rdx # allocate stack for fin @@ -92,26 +77,19 @@ root_fs: push 1 # arg5 = EFI_FILE_READ_ONLY push 1 # prepare to set arg4 to EFI_FILE_MODE_READ pop r9 # arg4 = EFI_FILE_MODE_READ - mov r8, r12 # arg3 = script - mov rcx, r13 # arg1 = rootdir + # arg3 = script + mov rcx, [rip+rootdir] # arg1 = rootdir sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+8] # rootdir->open() test eax, eax # if status != EFI_SUCCESS - jne abort # then exit without closing file + jne terminate_2 # then exit without closing file mov r12, [rsp+40] # get fin # Allocate pool for command - push rdx # allocate stack for command - mov r8, rsp # arg3 = &command xor edx, edx # zero rdx mov dh, 0x10 # arg2 = 4096 = 0x1000 - push 2 - pop rcx # arg1 = EFI_LOADER_DATA - push rax # allocate shadow stack space for UEFI function - push rax # allocate shadow stack space for UEFI function - push rax # allocate shadow stack space for UEFI function - call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 4096, &commmand) - mov rbx, [rsp+24] # get command + call allocate_pool # allocate memory + mov rbx, rax # get command next_command: xor esi, esi # i = 0 @@ -175,7 +153,7 @@ read_command_done: push 1 # prepare to set arg4 to EFI_FILE_MODE_READ pop r9 # arg4 = EFI_FILE_MODE_READ mov r8, rbx # arg3 = command - mov rcx, r13 # arg1 = rootdir + mov rcx, [rip+rootdir] # arg1 = rootdir sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+8] # rootdir->open() test eax, eax # if status != EFI_SUCCESS @@ -187,35 +165,21 @@ read_command_done: mov WORD PTR [r15], 0x20 # restore command line options by readding ' ' # Allocate pool for file_info - push rdx # allocate stack for file_info - mov r8, rsp # arg3 = &file_info xor edx, edx # zero rdx mov dh, 0x10 # arg2 = 4096 = 0x1000 - push 2 - pop rcx # arg1 = EFI_LOADER_DATA - push rax # allocate shadow stack space for UEFI function - push rax # allocate shadow stack space for UEFI function - push rax # allocate shadow stack space for UEFI function - call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 4096, &file_info) - pop rax # deallocate stack - pop rax # deallocate stack - pop rax # deallocate stack - pop r9 # get file_info (arg4 for get_info) + call allocate_pool # allocate memory + mov r9, rax # get file_info (arg4 for get_info) # Get file info - push r9 # save file_info + push rax # save file_info push rax # allocate stack for file_size mov r8, rsp # arg3 = &file_size mov QWORD PTR [r8], 0x1000 # file_size = 0x1000 - mov rdx, [rip+SIMPLE_FS_PROTOCOL+8] # EFI_FILE_INFO_PROTOCOL (last 64 bits) - push rdx # push last 64 bits onto stack - mov rdx, [rip+FILE_INFO_PROTOCOL] # EFI_FILE_INFO_PROTOCOL (first 64 bits) - push rdx # push first 64 bits onto stack - mov rdx, rsp # arg2 = &guid + lea rdx, [rip+FILE_INFO_PROTOCOL] # arg2 = &EFI_FILE_INFO_PROTOCOL mov rcx, rdi # arg1 = fcmd sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+64] # fcmd->get_info(fcmd, &guid, &file_size, file_info) - add rsp, 56 # deallocate stack + add rsp, 40 # deallocate stack pop rcx # restore file_info mov rdx, [rcx+8] # get file_size @@ -228,18 +192,8 @@ read_command_done: # Allocate pool for executable push rdx # save file_size onto stack - push rdx # allocate stack for executable - mov r8, rsp # arg3 = &executable - push 2 - pop rcx # arg1 = EFI_LOADER_DATA - push rax # allocate shadow stack space for UEFI function - push rax # allocate shadow stack space for UEFI function - push rax # allocate shadow stack space for UEFI function - call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, file_size, &executable) - pop rax # deallocate stack - pop rax # deallocate stack - pop rax # deallocate stack - pop r15 # get executable + call allocate_pool # allocate memory + mov r15, rax # get executable pop rdx # restore file_size # Load executable into memory @@ -264,23 +218,12 @@ read_command_done: pop rdi # restore file_size # Allocate memory for device_path struct - push rdx # allocate stack for device_path - mov r8, rsp # arg3 = &device_path push 28 # 4 + sizeof(struct efi_device_path_protocol) pop rdx # arg2 = 28 - push 2 - pop rcx # arg1 = EFI_LOADER_DATA - push rax # allocate shadow stack space for UEFI function - push rax # allocate shadow stack space for UEFI function - push rax # allocate shadow stack space for UEFI function - call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 28, &device_path) - pop rax # deallocate stack - pop rax # deallocate stack - pop rax # deallocate stack - pop r8 # get device_path + call allocate_pool # allocate memory + mov r8, rax # get device_path # Initialize struct - mov rax, r8 # Make a pointer to device_path members mov BYTE PTR [rax], 1 # device_path->type = HARDWARE_DEVICE_PATH inc rax # next member mov BYTE PTR [rax], 3 # device_path->subtype = MEMORY_MAPPED @@ -328,21 +271,11 @@ read_command_done: pop rax # deallocate stack # Open Child Image - push rax # allocate stack for child_image - mov r8, rsp # arg3 = &child_image - mov rdx, [rip+LOADED_IMAGE_PROTOCOL+8] # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) - push rdx # push last 64 bits onto stack - mov rdx, [rip+LOADED_IMAGE_PROTOCOL] # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) - push rdx # push first 64 bits onto stack - mov rdx, rsp # arg2 = &guid - push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - push 0 # arg5 = NULL mov r9, rdi # arg4 = child_ih - mov rcx, rdi # arg1 = child_ih - sub rsp, 32 # allocate shadow stack space for UEFI function - call [r14+280] # system->boot->open_protocol(child_ih, &guid, &child_image, child_ih, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - add rsp, 64 # deallocate stack - pop rax # get child_image + lea rdx, [rip+LOADED_IMAGE_PROTOCOL] # guid = &LOADED_IMAGE_PROTOCOL + push rdx # save &LOADED_IMAGE_PROTOCOL + mov rcx, r9 # arg1 = child_ih + call open_protocol # open protocol mov [rax+56], rbx # child_image->load_options = command mov [rax+48], rsi # set child_image->load_options_size @@ -350,6 +283,11 @@ read_command_done: mov rcx, [rcx+24] # image->device mov [rax+24], rcx # child_image->device = image->device + mov r8, rdi # arg3 = image_handle + pop rdx # arg2 = &LOADED_IMAGE_PROTOCOL + mov rcx, r8 # arg1 = image_handle + call close_protocol # close protocol + # Run command xor r8, r8 # arg3 = 0 (ExitData) xor edx, edx # arg2 = 0 (ExitData size) @@ -382,13 +320,29 @@ terminate: mov rcx, r12 # arg1 = fin call [rcx+16] # fin->close(fin) + + mov rcx, [rip+rootdir] # arg1 = rootdir + call [rcx+16] # rootdir->close(rootdir) + pop rax # deallocate stack pop rax # restore exit code # Exit without closing script file +terminate_2: + mov r8, [rip+image_handle] # arg3 = image_handle + push r8 # save image_handle + lea rdx, [rip+SIMPLE_FS_PROTOCOL] # guid = &SIMPLE_FS_PROTOCOL + mov rcx, [rip+root_device] # arg1 = root_device + call close_protocol # close protocol + + pop r8 # arg3 = image_handle + lea rdx, [rip+LOADED_IMAGE_PROTOCOL] # guid = &LOADED_IMAGE_PROTOCOL + mov rcx, r8 # arg1 = image_handle + call close_protocol # close protocol + abort: mov rsp, rbp # restore stack - ret + ret # return to UEFI # File_Print function # Receives WCHAR* in RDX @@ -425,6 +379,45 @@ read_byte: ret +# rcx: handle +# rdx: &guid +# r9: agent_handle +# returns interface +open_protocol: + push rax # allocate stack for interface + mov r8, rsp # arg3 = &interface + push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + push 0 # arg5 = NULL + sub rsp, 32 # allocate shadow stack space for UEFI function + call [r14+280] # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + add rsp, 48 # deallocate stack + pop rax # get interface + ret + +# rcx: handle +# rdx: &guid +# r8: agent_handle +close_protocol: + xor r9, r9 # arg4 = NULL + sub rsp, 32 # allocate shadow stack space for UEFI function + call [r14+288] # system->boot->close_protocol(handle, &guid, agent_handle, 0) + add rsp, 32 # deallocate stack + ret + +# rdx: number of bytes to allocate +# r14: system->boot +# returns pointer in rax +allocate_pool: + push rdx # allocate stack for pool pointer + mov r8, rsp # arg3 = &pool + push 2 + pop rcx # arg1 = EFI_LOADER_DATA + sub rsp, 24 # allocate shadow stack space for UEFI + call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) + add rsp, 24 # deallocate stack + pop rax # get pool + ret + # Protocol GUIDs LOADED_IMAGE_PROTOCOL: .long 0x5b1b31a1 @@ -442,7 +435,7 @@ FILE_INFO_PROTOCOL: .long 0x09576e92 .short 0x6d3f .short 0x11d2 -# last 64-bits of GUID are identical to SIMPLE_FS_PROTOCOL +.byte 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b default_file: .byte 0x6B, 0, 0x61, 0, 0x65, 0, 0x6D, 0, 0x2E, 0 @@ -463,5 +456,11 @@ image_handle: image: .long 0, 0 +rootdir: +.long 0, 0 + +root_device: +.long 0, 0 + system_out: .long 0, 0 diff --git a/amd64/Development/kaem-minimal.hex2 b/amd64/Development/kaem-minimal.hex2 index c58ef27..aead91a 100644 --- a/amd64/Development/kaem-minimal.hex2 +++ b/amd64/Development/kaem-minimal.hex2 @@ -5,442 +5,432 @@ # 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 + 4889E5 ; mov_rbp,rsp # save stack pointer + 48890D %image_handle ; mov_[rip+DWORD],rcx %image_handle # save image_handle + 4889CB ; mov_rbx,rcx # save image_handle + 488B42 40 ; mov_rax,[rdx+BYTE] !64 # system->out + 488905 %system_out ; mov_[rip+DWORD],rax %system_out # save system->out + 4C8B72 60 ; mov_r14,[rdx+BYTE] !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 + 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 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 F0000000 ; call_[r14+DWORD] %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 + 4989D9 ; mov_r9,rbx # arg4 = image_handle + 488D15 %LOADED_IMAGE_PROTOCOL ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4889D9 ; mov_rcx,rbx # arg1 = image_handle + E8 %open_protocol ; call %open_protocol # open protocol + 4889C7 ; mov_rdi,rax # save image + 488905 %image ; mov_[rip+DWORD],rax %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 + 4989D9 ; mov_r9,rbx # arg4 = image_handle + 488D15 %SIMPLE_FS_PROTOCOL ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B4F 18 ; mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device + 48890D %root_device ; mov_[rip+DWORD],rcx %root_device # save root_device + E8 %open_protocol ; call %open_protocol # open protocol + 4889C1 ; mov_rcx,rax # 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 + 488D15 %rootdir ; lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + 50 ; push_rax # allocate shadow stack space for UEFI function space for UEFI function + 50 ; push_rax # allocate shadow stack space for UEFI function space for UEFI function + FF51 08 ; call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # deallocate stack + + # Push command line arguments onto stack + 488B5F 38 ; mov_rbx,[rdi+BYTE] !56 # options = image->load_options + 4889DA ; mov_rdx,rbx # save beginning of load_options + 48035F 30 ; add_rbx,[rdi+BYTE] !48 # go to the end of load_options + 6A 00 ; push !0 # Save end of arguments (NULL) onto stack +:loop_options + 4839D3 ; cmp_rbx,rdx # Check if we are done + 74 !loop_options_done ; je8 !loop_options_done # We are done + 4883EB 02 ; sub_rbx, !2 # --options + 8A03 ; mov_al,[rbx] # *options + 3C 20 ; cmp_al, !0x20 # if *options != ' ' + 75 !loop_options ; jne8 !loop_options # then continue looping + C603 00 ; mov_[rbx], !0 # zero it + 4883C3 02 ; add_rbx, !2 # ++options + 53 ; push_rbx # push another argument onto stack + EB !loop_options ; jmp8 !loop_options # next argument +:loop_options_done + + 4158 ; pop_r8 # get input file + 4D85C0 ; test_r8,r8 # Check if argument is specified + 75 !arg_done ; jne8 !arg_done # then use it + # Else use default_file + 4C8D05 %default_file ; lea_r8,[rip+DWORD] %default_file # Use "kaem.amd64" +:arg_done # 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 + 52 ; push_rdx # allocate stack for fin + 4889E2 ; mov_rdx,rsp # 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 + # arg3 = in + 488B0D %rootdir ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + FF51 08 ; call_[rcx+BYTE] !8 # rootdir->open() + 85C0 ; test_eax,eax # if status != EFI_SUCCESS + 0F85 %abort ; jne %abort # then exit without closing file + 4C8B6424 28 ; mov_r12,[rsp+BYTE] !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 + 31D2 ; xor_edx,edx # zero RDX + B6 10 ; mov_dh, !0x10 # arg2 = 4096 = 0x1000 + E8 %allocate_pool ; call %allocate_pool # allocate memory + 4889C3 ; mov_rbx,rax # get command :next_command - 31F6 ; XOR_ESI_ESI # i = 0 - 4D31FF ; XOR_R15_R15 # command_length = 0 + 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 + E8 %read_byte ; call %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 0A ; cmp_al, !0xa # if c == '\n' + 74 !read_command_done ; je8 !read_command_done # then we are done with this command 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 + 3C 20 ; cmp_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 ; mov_r15,rsi # 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 + 3C 23 ; cmp_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 + E8 %read_byte ; call %read_byte # get another char + 3C 0A ; cmp_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 + 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 + 4801F3 ; add_rbx,rsi # rbx = &command[i] + 668903 ; mov_[rbx],ax # command[i] = c + 4829F3 ; sub_rbx,rsi # rbx = &command[0] + 4883C6 02 ; add_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 + 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] + 4801F3 ; add_rbx,rsi # rbx = &command[i] + 66C703 0000 ; mov_[rbx],WORD @0 # command[i] = 0 + 4829F3 ; sub_rbx,rsi # rbx = &command[0] - 4883C6 02 ; ADDI8_RSI !2 # add 2 to get string length with NULL terminator + 4883C6 02 ; add_rsi, !2 # add 2 to get string length with NULL terminator - 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 + 488D15 %prefix ; lea_rdx,[rip+DWORD] %prefix # get prefix " +> " + E8 %File_Print ; call %File_Print # print it + 4889DA ; mov_rdx,rbx # get command + E8 %File_Print ; call %File_Print # print it + 488D15 %suffix ; lea_rdx,[rip+DWORD] %suffix # get suffix "\n\r" + E8 %File_Print ; call %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 + 4901DF ; add_r15,rbx # go to the space separating command and its options + 6641C707 0000 ; mov_[r15],WORD @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 + 52 ; push_rdx # allocate stack for fcmd + 4889E2 ; mov_rdx,rsp # 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 ; mov_r8,rbx # arg3 = command + 488B0D %rootdir ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + FF51 08 ; call_[rcx+BYTE] !8 # rootdir->open() + 85C0 ; test_eax,eax # if status != EFI_SUCCESS + 0F85 %print_error ; jne %print_error # then exit + 4883C4 28 ; add_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 ' ' + 6641C707 2000 ; mov_[r15],WORD @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) + 31D2 ; xor_edx,edx # zero RDX + B6 10 ; mov_dh, !0x10 # arg2 = 4096 = 0x1000 + E8 %allocate_pool ; call %allocate pool # allocate memory + 4989C1 ; mov_r9,rax # 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 + 50 ; push_rax # save file_info + 50 ; push_rax # allocate stack for file_size + 4989E0 ; mov_r8,rsp # arg3 = &file_size + 49C700 00100000 ; mov_[r8], %0x1000 # file_size = 0x1000 + 488D15 %FILE_INFO_PROTOCOL ; lea_rdx,[rip+DWORD] %FILE_INFO_PROTOCOL # arg2 = &EFI_FILE_INFO_PROTOCOL + 4889F9 ; mov_rcx,rdi # arg1 = fcmd + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + FF51 40 ; call_[rcx+BYTE] !64 # fcmd->get_info(fcmd, &guid, &file_size, file_info) + 4883C4 28 ; add_rsp, !40 # deallocate stack + 59 ; pop_rcx # restore file_info + 488B51 08 ; mov_rdx,[rcx+BYTE] !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) + 52 ; push_rdx # save file_size onto stack + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !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 + 52 ; push_rdx # save file_size onto stack + E8 %allocate_pool ; call %allocate_pool # allocate memory + 4989C7 ; mov_r15,rax # 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 + 52 ; push_rdx # save file_size onto stack + 4D89F8 ; mov_r8,r15 # arg3 = executable + 4889E2 ; mov_rdx,rsp # arg2 = &file_size + 4889F9 ; mov_rcx,rdi # arg1 = fcmd + 50 ; push_rax # allocate shadow stack space for UEFI + 50 ; push_rax # allocate shadow stack space for UEFI + 50 ; push_rax # allocate shadow stack space for UEFI + FF51 20 ; call_[rcx+BYTE] !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 + 50 ; push_rax # allocate shadow stack space for UEFI + 4889F9 ; mov_rcx,rdi # arg1 = fcmd + FF51 10 ; call_[rcx+BYTE] !16 # fcmd->close(fcmd) + 58 ; pop_rax # deallocate stack - 5F ; POP_RDI # restore file_size + 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 + 6A 1C ; push !28 # 4 + sizeof(struct efi_device_path_protocol) + 5A ; pop_rdx # arg2 = 28 + E8 %allocate_pool ; call %allocate_pool # allocate memory + 4989C0 ; mov_r8,rax # 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 + C600 01 ; mov_[rax],BYTE !1 # device_path->type = HARDWARE_DEVICE_PATH + 48FFC0 ; inc_rax # next member + C600 03 ; mov_[rax],BYTE !3 # device_path->subtype = MEMORY_MAPPED + 48FFC0 ; inc_rax # next member + 66C700 1800 ; mov_[rax],WORD @24 # device_path->length = 24 + 4883C0 02 ; add_rax, !2 # next member + C700 01000000 ; mov_[rax], %1 # device_path->memory_type = EFI_LOADER_CODE + 4883C0 04 ; add_rax, !4 # next member + 4C8938 ; mov_[rax],r15 # device_path->start_address = executable + 4883C0 08 ; add_rax, !8 # next member + 4901FF ; add_r15,rdi # end_address = executable + file_size + 4C8938 ; mov_[rax],r15 # device_path->end_address = end_address + 4929FF ; sub_r15,rdi # restore r15 = executable + 4883C0 08 ; add_rax, !8 # next member + C600 7F ; mov_[rax],BYTE !0x7f # device_path[1].type = END_HARDWARE_DEVICE_PATH + 48FFC0 ; inc_rax # next member + C600 FF ; mov_[rax],BYTE !0xff # device_path[1].subtype = END_ENTIRE_DEVICE_PATH + 48FFC0 ; inc_rax # next member + 66C700 0400 ; mov_[rax],WORD @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 + 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 ; mov_r9,r15 # arg4 = executable + # arg3 = device_path + 488B15 %image_handle ; mov_rdx,[rip+DWORD] %image_handle # arg2 = image_handle + 31C9 ; xor_ecx,ecx # arg1 = 0 + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 C8000000 ; call_[r14+DWORD] %200 # system->boot->load_image() + 4883C4 30 ; add_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 + 59 ; pop_rcx # arg1 = device_path + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !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 + 4C89F9 ; mov_rcx,r15 # arg1 = executable + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !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 + 4989F9 ; mov_r9,rdi # arg4 = child_ih + 488D15 %LOADED_IMAGE_PROTOCOL ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 52 ; push_rdx # save &LOADED_IMAGE_PROTOCOL + 4C89C9 ; mov_rcx,r9 # arg1 = child_ih + E8 %open_protocol ; call %open_protocol # open protocol - 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 + 488958 38 ; mov_[rax+BYTE],rbx !56 # child_image->load_options = command + 488970 30 ; mov_[rax+BYTE],rsi !48 # set child_image->load_options_size + 488B0D %image ; mov_rcx,[rip+DWORD] %image # get image + 488B49 18 ; mov_rcx,[rcx+BYTE] !24 # image->device + 488948 18 ; mov_[rax+BYTE],rcx !24 # child_image->device = image->device + + 4989F8 ; mov_r8,rdi # arg3 = image_handle + 5A ; pop_rdx # arg2 = &LOADED_IMAGE_PROTOCOL + 4C89C1 ; mov_rcx,r8 # arg1 = image_handle + E8 %close_protocol ; call %close_protocol # close protocol # 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 + 4D31C0 ; xor_r8,r8 # arg3 = 0 (ExitData) + 31D2 ; xor_edx,edx # arg2 = 0 (ExitData size) + 4889F9 ; mov_rcx,rdi # arg1 = child_ih + 50 ; push_rax # allocate shadow stack space for UEFI + 50 ; push_rax # allocate shadow stack space for UEFI + 50 ; push_rax # allocate shadow stack space for UEFI + 41FF96 D0000000 ; call_[r14+DWORD] %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 + 85C0 ; test_eax,eax # check if return code is 0 + 75 !print_error ; jne8 !print_error # print error and exit + E9 %next_command ; jmp %next_command # process another line from kaem script :print_error - 50 ; PUSH_RAX # save exit code - 488D15 %subprocess_error ; LEA_RDX_rel %subprocess_error # get error message - E8 %File_Print ; CALLI32 %File_Print # print it - 58 ; POP_RAX # restore exit code + 50 ; push_rax # save exit code + 488D15 %subprocess_error ; lea_rdx,[rip+DWORD] %subprocess_error # get error message + E8 %File_Print ; call %File_Print # print it + 58 ; pop_rax # restore exit code # Close script file and exit :terminate # Free pool - 4889D9 ; 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) + 4889D9 ; mov_rcx,rbx # arg1 = command + 50 ; push_rax # save exit code + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !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 + 4C89E1 ; mov_rcx,r12 # arg1 = fin + FF51 10 ; call_[rcx+BYTE] !16 # fin->close(fin) + + 488B0D %rootdir ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + FF51 10 ; call_[rcx+BYTE] !16 # rootdir->close(rootdir) + + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # restore exit code # Exit without closing script file +:terminate_2 + 4C8B05 %image_handle ; mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle + 4150 ; push_r8 # save image_handle + 488D15 %SIMPLE_FS_PROTOCOL ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B0D %root_device ; mov_rcx,[rip+DWORD] %root_device # arg1 = root_device + E8 %close_protocol ; call %close_protocol # close protocol + + 4158 ; pop_r8 # arg3 = image_handle + 488D15 %LOADED_IMAGE_PROTOCOL ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4C89C1 ; mov_rcx,r8 # arg1 = image_handle + E8 %close_protocol ; call %close_protocol # close protocol + :abort - 4889EC ; COPY_RBP_to_RSP # restore stack - C3 ; RET + 4889EC ; mov_rsp,rbp # restore stack + C3 ; ret # return to UEFI :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 + 488B0D %system_out ; mov_rcx,[rip+DWORD] %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 for UEFI function + FF51 08 ; call_[rcx+BYTE] !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 + 4C89E1 ; mov_rcx,r12 # arg1 = fin + 6A 01 ; push !1 # size = 1 + 4889E2 ; mov_rdx,rsp # arg2 = &size + 56 ; push_rsi # allocate stack + 4989E0 ; mov_r8,rsp # 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+BYTE] !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 + 85C9 ; test_ecx,ecx # if size = 0 + 74 !terminate ; je8 !terminate # then we are done - C3 ; RET # return + C3 ; ret # return +# rcx: handle +# rdx: &guid +# r9: agent_handle +# returns interface +:open_protocol + 50 ; push_rax # allocate stack for interface + 4989E0 ; mov_r8,rsp # arg3 = &interface + 6A 01 ; push !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + 6A 00 ; push !0 # arg5 = NULL + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 18010000 ; call_[r14+DWORD] %280 # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + 4883C4 30 ; add_rsp, !48 # deallocate stack + 58 ; pop_rax # get image + C3 ; ret + +# rcx: handle +# rdx: &guid +# r8: agent_handle +:close_protocol + 4D31C9 ; xor_r9,r9 # arg4 = NULL + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 20010000 ; call_[r14+DWORD] %288 # system->boot->close_protocol(handle, &guid, agent_handle, 0) + 4883C4 20 ; add_rsp, !32 # deallocate stack + C3 ; ret + +# rdx: number of bytes to allocate +# r14: system->boot +# returns pointer in rax +:allocate_pool + 52 ; push_rdx # allocate stack for pool pointer + 4989E0 ; mov_r8,rsp # arg3 = &pool + 6A 02 ; push !2 + 59 ; pop_rcx # arg1 = EFI_LOADER_DATA + 4883EC 18 ; sub_rsp, !24 # allocate shadow stack space for UEFI + 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) + 4883C4 18 ; add_rsp, !24 # deallocate stack + 58 ; pop_rax # get pool + C3 ; ret # 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 + 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :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" @@ -460,6 +450,12 @@ :image 00 00 00 00 00 00 00 00 +:rootdir + 00 00 00 00 00 00 00 00 + +:root_device + 00 00 00 00 00 00 00 00 + :system_out 00 00 00 00 00 00 00 00 diff --git a/amd64/hex1.hex0 b/amd64/hex1.hex0 index 772a009..2edb784 100644 --- a/amd64/hex1.hex0 +++ b/amd64/hex1.hex0 @@ -143,7 +143,7 @@ CF 03 00 00 ; SizeOfRawData # Open Loaded Image protocol 4D89F9 ; mov_r9,r15 # arg4 = image_handle - 488D15 9B030000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 488D15 9B030000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL 4C89C9 ; mov_rcx,r9 # arg1 = image_handle 50 ; push_rax # allocate stack for image 4989E0 ; mov_r8,rsp # arg3 = &image @@ -156,7 +156,7 @@ CF 03 00 00 ; SizeOfRawData # Get root file system 4D89F9 ; mov_r9,r15 # arg4 = image_handle - 488D15 86030000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488D15 86030000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL 488B4F 18 ; mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device 4989CD ; mov_r13,rcx # save root_device 50 ; push_rax # allocate stack for rootfs @@ -185,7 +185,7 @@ CF 03 00 00 ; SizeOfRawData 6A 00 ; push !0 # Save end of arguments (NULL) onto stack # :loop_options [_start + 0x71] 4839D3 ; cmp_rbx,rdx # Check if we are done - 74 14 ; je8 !loop_options_done # We are done + 74 14 ; je8 !loop_options_done # We are done 4883EB 02 ; sub_rbx, !2 # --options 8A03 ; mov_al,[rbx] # *options 3C 20 ; cmp_al, !0x20 # if *options != ' ' diff --git a/amd64/hex2.hex1 b/amd64/hex2.hex1 index e135a50..7897275 100644 --- a/amd64/hex2.hex1 +++ b/amd64/hex2.hex1 @@ -242,7 +242,7 @@ DD 06 00 00 ; SizeOfRawData # rewind input file 4153 ; push_r11 # Protect r11 488B0D %0 ; mov_rcx,[rip+DWORD] %fin # Using our input file - 31D2 ; xor_edx_edx # Offset Zero + 31D2 ; xor_edx,edx # Offset Zero 50 ; push_rax # allocate shadow stack space for UEFI function 50 ; push_rax # allocate shadow stack space for UEFI function FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0) @@ -500,7 +500,7 @@ DD 06 00 00 ; SizeOfRawData 488B0D %0 ; mov_rcx,[rip+DWORD] %fin # arg1 = fin 6A 01 ; push !1 # size = 1 4889E2 ; mov_rdx,rsb # arg2 = &size - 31F6 ; xor_esi_esi # zero rsi + 31F6 ; xor_esi,esi # zero rsi 56 ; push_rsi # allocate stack 4989E0 ; mov_rsp,r8 # arg3 = &input 50 ; push_rax # allocate shadow stack space for UEFI function @@ -707,7 +707,7 @@ DD 06 00 00 ; SizeOfRawData E9 %T ; jmp %terminate :S #:Done - 31C0 ; xor_eax_eax # Set exit code 0 + 31C0 ; xor_eax,eax # Set exit code 0 :T #:terminate 50 ; push_rax # save exit code diff --git a/amd64/kaem-minimal.hex0 b/amd64/kaem-minimal.hex0 index b0a6e70..827b2fa 100644 --- a/amd64/kaem-minimal.hex0 +++ b/amd64/kaem-minimal.hex0 @@ -120,9 +120,9 @@ F0 00 # SizeOfOptionalHeader # [0x148] # Start of section headers 00 00 00 00 00 00 00 00 ; Name of the section (empty) but could set to ".text" -F7 03 00 00 ; VirtualSize +18 04 00 00 ; VirtualSize 00 10 00 00 ; VirtualAddress -F7 03 00 00 ; SizeOfRawData +18 04 00 00 ; SizeOfRawData 70 01 00 00 ; PointerToRawData 00 00 00 00 ; PointerToRelocations 00 00 00 00 ; PointerToLinenumbers @@ -136,462 +136,459 @@ F7 03 00 00 ; SizeOfRawData # efi_main(void *image_handle, struct efi_system_table *system) # :_start - 4889E5 ; COPY_RSP_to_RBP # save stack pointer - 48890D D5030000 ; STORE64_from_RCX_rel32 %image_handle # save image_handle - 488B42 40 ; LOAD64_into_RAX_from_Address_RDX_Immediate8 !64 # system->out - 488905 DA030000 ; STORE64_from_RAX_rel32 %system_out # save system->out - 4C8B72 60 ; LOAD64_into_R14_from_Address_RDX_Immediate8 !96 # system->boot + 4889E5 ; mov_rbp,rsp # save stack pointer + 48890D E6030000 ; mov_[rip+DWORD],rcx %image_handle # save image_handle + 4889CB ; mov_rbx,rcx # save image_handle + 488B42 40 ; mov_rax,[rdx+BYTE] !64 # system->out + 488905 F8030000 ; mov_[rip+DWORD],rax %system_out # save system->out + 4C8B72 60 ; mov_r14,[rdx+BYTE] !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 + 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 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 F0000000 ; call_[r14+DWORD] %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 40030000 ; 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 30030000 ; 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 8F030000 ; 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 7D030000 ; STORE64_from_RAX_rel32 %image # save image + 4989D9 ; mov_r9,rbx # arg4 = image_handle + 488D15 3F030000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4889D9 ; mov_rcx,rbx # arg1 = image_handle + E8 F6020000 ; call %open_protocol # open protocol + 4889C7 ; mov_rdi,rax # save image + 488905 AB030000 ; mov_[rip+DWORD],rax %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 [_start+0x71] - 4883C3 02 ; ADDI8_RBX !2 # ++options - 8A03 ; LOAD8_AL_from_Address_RBX # *options - 3C 20 ; CMPI8_AL !0x20 # if *options == ' ' - 74 0D ; JE8 !loop_options2 # then jump - 84C0 ; TEST_AL_AL # if options != 0 - 75 F2 ; JNE8 !loop_options1 # then loop - - # Use default file - 4C8D25 13030000 ; LEA_R12_rel %default_file # Use "kaem.amd64" - EB 07 ; JMP8 !root_fs # jump - -# :loop_options2 [_start+0x88] - 4883C3 02 ; ADDI8_RBX !2 # ++options - 4989DC ; COPY_RBX_to_R12 # save input file - -# :root_fs [_start+0x8F] # Get root file system - 50 ; PUSH_RAX # allocate stack for rootfs - 4989E0 ; COPY_RSP_to_R8 # arg3 = &rootfs - 488B15 EF020000 ; 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 DF020000 ; 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 2E030000 ; 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 + 4989D9 ; mov_r9,rbx # arg4 = image_handle + 488D15 33030000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B4F 18 ; mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device + 48890D A6030000 ; mov_[rip+DWORD],rcx %root_device # save root_device + E8 D2020000 ; call %open_protocol # open protocol + 4889C1 ; mov_rcx,rax # 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 + 488D15 8F030000 ; lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + 50 ; push_rax # allocate shadow stack space for UEFI function space for UEFI function + 50 ; push_rax # allocate shadow stack space for UEFI function space for UEFI function + FF51 08 ; call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # deallocate stack + + # Push command line arguments onto stack + 488B5F 38 ; mov_rbx,[rdi+BYTE] !56 # options = image->load_options + 4889DA ; mov_rdx,rbx # save beginning of load_options + 48035F 30 ; add_rbx,[rdi+BYTE] !48 # go to the end of load_options + 6A 00 ; push !0 # Save end of arguments (NULL) onto stack +# :loop_options [_start+0x85] + 4839D3 ; cmp_rbx,rdx # Check if we are done + 74 14 ; je8 !loop_options_done # We are done + 4883EB 02 ; sub_rbx, !2 # --options + 8A03 ; mov_al,[rbx] # *options + 3C 20 ; cmp_al, !0x20 # if *options != ' ' + 75 F1 ; jne8 !loop_options # then continue looping + C603 00 ; mov_[rbx], !0 # zero it + 4883C3 02 ; add_rbx, !2 # ++options + 53 ; push_rbx # push another argument onto stack + EB E7 ; jmp8 !loop_options # next argument +# :loop_options_done [_start+0x9E] + + 4158 ; pop_r8 # get input file + 4D85C0 ; test_r8,r8 # Check if argument is specified + 75 07 ; jne8 !arg_done # then use it + # Else use default_file + 4C8D05 FE020000 ; lea_r8,[rip+DWORD] %default_file # Use "kaem.amd64" +# :arg_done [_start+0xAC] # 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 51020000 ; JNE32 %abort # then exit without closing file - 4C8B6424 28 ; LOAD64_into_R12_from_Address_RSP_Immediate8 !40 # get fin + 52 ; push_rdx # allocate stack for fin + 4889E2 ; mov_rdx,rsp # 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 + # arg3 = in + 488B0D 43030000 ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + FF51 08 ; call_[rcx+BYTE] !8 # rootdir->open() + 85C0 ; test_eax,eax # if status != EFI_SUCCESS + 0F85 3E020000 ; jne %abort # then exit without closing file + 4C8B6424 28 ; mov_r12,[rsp+BYTE] !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 + 31D2 ; xor_edx,edx # zero RDX + B6 10 ; mov_dh, !0x10 # arg2 = 4096 = 0x1000 + E8 8B020000 ; call %allocate_pool # allocate memory + 4889C3 ; mov_rbx,rax # get command -# :next_command [_start+0x10D] - 31F6 ; XOR_ESI_ESI # i = 0 - 4D31FF ; XOR_R15_R15 # command_length = 0 +# :next_command [_start+0xDD] + 31F6 ; xor_esi,esi # i = 0 + 4D31FF ; xor_r15,r15 # command_length = 0 -# :read_command [_start+0x112] - E8 3E020000 ; CALLI32 %read_byte # read another byte c +# :read_command [_start+0xE2] + E8 36020000 ; call %read_byte # read another byte c - 3C 0A ; CMPI8_AL !0xa # if c == '\n' - 74 2A ; JE8 !read_command_done # then we are done with this command + 3C 0A ; cmp_al, !0xa # if c == '\n' + 74 2A ; je8 !read_command_done # then we are done with this command command command - 3C 20 ; CMPI8_AL !0x20 # if c == ' ' - 75 08 ; JNE8 !read_command_comments - 4D85FF ; TEST_R15_R15 # and command_length == 0 - 75 03 ; JNE8 !read_command_comments - 4989F7 ; COPY_RSI_to_R15 # command_length = i + 3C 20 ; cmp_al, !0x20 # if c == ' ' + 75 08 ; jne8 !read_command_comments + 4D85FF ; test_r15,r15 # and command_length == 0 + 75 03 ; jne8 !read_command_comments + 4989F7 ; mov_r15,rsi # command_length = i -# :read_command_comments [_start+0x127] - 3C 23 ; CMPI8_AL !0x23 # if c == '#' then process comment - 75 0B ; JNE8 !read_command_store_char # else store char +# :read_command_comments [_start+0xF7] + 3C 23 ; cmp_al, !0x23 # if c == '#' then process comment + 75 0B ; jne8 !read_command_store_char # else store char -# :read_command_skip_comment [_start+0x12B] - E8 25020000 ; CALLI32 %read_byte # get another char - 3C 0A ; CMPI8_AL !0xa # if c == '\n' - 75 F7 ; JNE8 !read_command_skip_comment # continue reading until newline +# :read_command_skip_comment [_start+0xFB] + E8 1D020000 ; call %read_byte # get another char + 3C 0A ; cmp_al, !0xa # if c == '\n' + 75 F7 ; jne8 !read_command_skip_comment # continue reading until newline - EB D7 ; JMP8 !next_command # deal with another line + EB D7 ; jmp8 !next_command # deal with another line -# :read_command_store_char [_start+0x136] - 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 CD ; JMP8 !read_command # continue looping +# :read_command_store_char [_start+0x106] + 4801F3 ; add_rbx,rsi # rbx = &command[i] + 668903 ; mov_[rbx],ax # command[i] = c + 4829F3 ; sub_rbx,rsi # rbx = &command[0] + 4883C6 02 ; add_rsi, !2 # location of the next char + EB CD ; jmp8 !read_command # continue looping -# :read_command_done [_start+0x145] - 4D85FF ; TEST_R15_R15 # if command_length == 0 - 74 C3 ; JE8 !next_command # deal with another line +# :read_command_done [_start+0x115] + 4D85FF ; test_r15,r15 # if command_length == 0 + 74 C3 ; 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] + 4801F3 ; add_rbx,rsi # rbx = &command[i] + 66C703 0000 ; mov_[rbx],WORD @0 # command[i] = 0 + 4829F3 ; sub_rbx,rsi # rbx = &command[0] - 4883C6 02 ; ADDI8_RSI !2 # add 2 to get string length with NULL terminator + 4883C6 02 ; add_rsi, !2 # add 2 to get string length with NULL terminator - 488D15 4F020000 ; LEA_RDX_rel %prefix # get prefix " +> " - E8 E1010000 ; CALLI32 %File_Print # print it - 4889DA ; COPY_RBX_to_RDX # get command - E8 D9010000 ; CALLI32 %File_Print # print it - 488D15 65020000 ; LEA_RDX_rel %suffix # get suffix "\n\r" - E8 CD010000 ; CALLI32 %File_Print # print it + 488D15 90020000 ; lea_rdx,[rip+DWORD] %prefix # get prefix " +> " + E8 D9010000 ; call %File_Print # print it + 4889DA ; mov_rdx,rbx # get command + E8 D1010000 ; call %File_Print # print it + 488D15 A6020000 ; lea_rdx,[rip+DWORD] %suffix # get suffix "\n\r" + E8 C5010000 ; call %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 + 4901DF ; add_r15,rbx # go to the space separating command and its options + 6641C707 0000 ; mov_[r15],WORD @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 82010000 ; JNE32 %print_error # then exit - 4883C4 28 ; ADDI8_RSP !40 # deallocate stack - 5F ; POP_RDI # get fcmd + 52 ; push_rdx # allocate stack for fcmd + 4889E2 ; mov_rdx,rsp # 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 ; mov_r8,rbx # arg3 = command + 488B0D 9A020000 ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + FF51 08 ; call_[rcx+BYTE] !8 # rootdir->open() + 85C0 ; test_eax,eax # if status != EFI_SUCCESS + 0F85 3F010000 ; jne %print_error # then exit + 4883C4 28 ; add_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) + 31D2 ; xor_edx,edx # zero RDX + B6 10 ; mov_dh, !0x10 # arg2 = 4096 = 0x1000 + E8 DC010000 ; call %allocate pool # allocate memory + 4989C1 ; mov_r9,rax # 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 B2010000 ; LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL_8 # EFI_FILE_INFO_PROTOCOL (last 64 bits) - 52 ; PUSH_RDX # push last 64 bits onto stack - 488B15 B2010000 ; 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 + 50 ; push_rax # save file_info + 50 ; push_rax # allocate stack for file_size + 4989E0 ; mov_r8,rsp # arg3 = &file_size + 49C700 00100000 ; mov_[r8], %0x1000 # file_size = 0x1000 + 488D15 FB010000 ; lea_rdx,[rip+DWORD] %FILE_INFO_PROTOCOL # arg2 = &EFI_FILE_INFO_PROTOCOL + 4889F9 ; mov_rcx,rdi # arg1 = fcmd + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + FF51 40 ; call_[rcx+BYTE] !64 # fcmd->get_info(fcmd, &guid, &file_size, file_info) + 4883C4 28 ; add_rsp, !40 # deallocate stack + 59 ; pop_rcx # restore file_info + 488B51 08 ; mov_rdx,[rcx+BYTE] !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) + 52 ; push_rdx # save file_size onto stack + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !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 + # Allocate pool for executable [_start+0x1BA] + 52 ; push_rdx # save file_size onto stack + E8 A5010000 ; call %allocate_pool # allocate memory + 4989C7 ; mov_r15,rax # 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 + 52 ; push_rdx # save file_size onto stack + 4D89F8 ; mov_r8,r15 # arg3 = executable + 4889E2 ; mov_rdx,rsp # arg2 = &file_size + 4889F9 ; mov_rcx,rdi # arg1 = fcmd + 50 ; push_rax # allocate shadow stack space for UEFI + 50 ; push_rax # allocate shadow stack space for UEFI + 50 ; push_rax # allocate shadow stack space for UEFI + FF51 20 ; call_[rcx+BYTE] !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 + 50 ; push_rax # allocate shadow stack space for UEFI + 4889F9 ; mov_rcx,rdi # arg1 = fcmd + FF51 10 ; call_[rcx+BYTE] !16 # fcmd->close(fcmd) + 58 ; pop_rax # deallocate stack - 5F ; POP_RDI # restore file_size + 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 + 6A 1C ; push !28 # 4 + sizeof(struct efi_device_path_protocol) + 5A ; pop_rdx # arg2 = 28 + E8 7D010000 ; call %allocate_pool # allocate memory + 4989C0 ; mov_r8,rax # 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 + C600 01 ; mov_[rax],BYTE !1 # device_path->type = HARDWARE_DEVICE_PATH + 48FFC0 ; inc_rax # next member + C600 03 ; mov_[rax],BYTE !3 # device_path->subtype = MEMORY_MAPPED + 48FFC0 ; inc_rax # next member + 66C700 1800 ; mov_[rax],WORD @24 # device_path->length = 24 + 4883C0 02 ; add_rax, !2 # next member + C700 01000000 ; mov_[rax], %1 # device_path->memory_type = EFI_LOADER_CODE + 4883C0 04 ; add_rax, !4 # next member + 4C8938 ; mov_[rax],r15 # device_path->start_address = executable + 4883C0 08 ; add_rax, !8 # next member + 4901FF ; add_r15,rdi # end_address = executable + file_size + 4C8938 ; mov_[rax],r15 # device_path->end_address = end_address + 4929FF ; sub_r15,rdi # restore r15 = executable + 4883C0 08 ; add_rax, !8 # next member + C600 7F ; mov_[rax],BYTE !0x7f # device_path[1].type = END_HARDWARE_DEVICE_PATH + 48FFC0 ; inc_rax # next member + C600 FF ; mov_[rax],BYTE !0xff # device_path[1].subtype = END_ENTIRE_DEVICE_PATH + 48FFC0 ; inc_rax # next member + 66C700 0400 ; mov_[rax],WORD @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 44010000 ; 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 + 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 ; mov_r9,r15 # arg4 = executable + # arg3 = device_path + 488B15 B2010000 ; mov_rdx,[rip+DWORD] %image_handle # arg2 = image_handle + 31C9 ; xor_ecx,ecx # arg1 = 0 + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 C8000000 ; call_[r14+DWORD] %200 # system->boot->load_image() + 4883C4 30 ; add_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 + 59 ; pop_rcx # arg1 = device_path + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !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 + 4C89F9 ; mov_rcx,r15 # arg1 = executable + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !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 B1000000 ; 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 A1000000 ; 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 + # Open Child Image [_start+0x260] + 4989F9 ; mov_r9,rdi # arg4 = child_ih + 488D15 10010000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 52 ; push_rdx # save &LOADED_IMAGE_PROTOCOL + 4C89C9 ; mov_rcx,r9 # arg1 = child_ih + E8 C6000000 ; call %open_protocol # open protocol - 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 EA000000 ; 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 + 488958 38 ; mov_[rax+BYTE],rbx !56 # child_image->load_options = command + 488970 30 ; mov_[rax+BYTE],rsi !48 # set child_image->load_options_size + 488B0D 76010000 ; mov_rcx,[rip+DWORD] %image # get image + 488B49 18 ; mov_rcx,[rcx+BYTE] !24 # image->device + 488948 18 ; mov_[rax+BYTE],rcx !24 # child_image->device = image->device + + 4989F8 ; mov_r8,rdi # arg3 = image_handle + 5A ; pop_rdx # arg2 = &LOADED_IMAGE_PROTOCOL + 4C89C1 ; mov_rcx,r8 # arg1 = image_handle + E8 BC000000 ; call %close_protocol # close protocol # 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 + 4D31C0 ; xor_r8,r8 # arg3 = 0 (ExitData) + 31D2 ; xor_edx,edx # arg2 = 0 (ExitData size) + 4889F9 ; mov_rcx,rdi # arg1 = child_ih + 50 ; push_rax # allocate shadow stack space for UEFI + 50 ; push_rax # allocate shadow stack space for UEFI + 50 ; push_rax # allocate shadow stack space for UEFI + 41FF96 D0000000 ; call_[r14+DWORD] %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 05 ; JNE8 !print_error # print error and exit - E9 EAFDFFFF ; JMP32 %next_command # process another line from kaem script + 85C0 ; test_eax,eax # check if return code is 0 + 75 05 ; jne8 !print_error # print error and exit + E9 29FEFFFF ; jmp %next_command # process another line from kaem script -# :print_error [_start+0x323] - 50 ; PUSH_RAX # save exit code - 488D15 8E000000 ; LEA_RDX_rel %subprocess_error # get error message - E8 16000000 ; CALLI32 %File_Print # print it - 58 ; POP_RAX # restore exit code +# :print_error [_start+0x2B4] + 50 ; push_rax # save exit code + 488D15 0E010000 ; lea_rdx,[rip+DWORD] %subprocess_error # get error message + E8 4D000000 ; call %File_Print # print it + 58 ; pop_rax # restore exit code # Close script file and exit -# :terminate [_start+0x331] +# :terminate [_start+0x2C2] # Free pool - 4889D9 ; 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) + 4889D9 ; mov_rcx,rbx # arg1 = command + 50 ; push_rax # save exit code + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !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 + 4C89E1 ; mov_rcx,r12 # arg1 = fin + FF51 10 ; call_[rcx+BYTE] !16 # fin->close(fin) + + 488B0D 28010000 ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + FF51 10 ; call_[rcx+BYTE] !16 # rootdir->close(rootdir) + + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # restore exit code # Exit without closing script file -# :abort [_start+0x342] - 4889EC ; COPY_RBP_to_RSP # restore stack - C3 ; RET +# :terminate_2 [_start+0x2DD] + 4C8B05 0C010000 ; mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle + 4150 ; push_r8 # save image_handle + 488D15 9D000000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B0D 14010000 ; mov_rcx,[rip+DWORD] %root_device # arg1 = root_device + E8 59000000 ; call %close_protocol # close protocol -# :File_Print [_start+0x346] - 488B0D A2000000 ; 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 + 4158 ; pop_r8 # arg3 = image_handle + 488D15 78000000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4C89C1 ; mov_rcx,r8 # arg1 = image_handle + E8 48000000 ; call %close_protocol # close protocol + +# :abort [_start+0x30A] + 4889EC ; mov_rsp,rbp # restore stack + C3 ; ret # return to UEFI + +# :File_Print [_start+0x30E] + 488B0D FB000000 ; mov_rcx,[rip+DWORD] %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 for UEFI function + FF51 08 ; call_[rcx+BYTE] !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 [_start+0x355] - 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 +# :read_byte [_start+0x31D] + 4C89E1 ; mov_rcx,r12 # arg1 = fin + 6A 01 ; push !1 # size = 1 + 4889E2 ; mov_rdx,rsp # arg2 = &size + 56 ; push_rsi # allocate stack + 4989E0 ; mov_r8,rsp # 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+BYTE] !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 C1 ; JE8 !terminate # then we are done + 85C9 ; test_ecx,ecx # if size = 0 + 74 8A ; je8 !terminate # then we are done - C3 ; RET # return + C3 ; ret # return + +# rcx: handle +# rdx: &guid +# r9: agent_handle +# returns interface +# :open_protocol [_start+0x339] + 50 ; push_rax # allocate stack for interface + 4989E0 ; mov_r8,rsp # arg3 = &interface + 6A 01 ; push !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + 6A 00 ; push !0 # arg5 = NULL + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 18010000 ; call_[r14+DWORD] %280 # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + 4883C4 30 ; add_rsp, !48 # deallocate stack + 58 ; pop_rax # get image + C3 ; ret + +# rcx: handle +# rdx: &guid +# r8: agent_handle +# :close_protocol [_start+0x352] + 4D31C9 ; xor_r9,r9 # arg4 = NULL + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 20010000 ; call_[r14+DWORD] %288 # system->boot->close_protocol(handle, &guid, agent_handle, 0) + 4883C4 20 ; add_rsp, !32 # deallocate stack + C3 ; ret + +# rdx: number of bytes to allocate +# r14: system->boot +# returns pointer in rax +# :allocate_pool [_start+0x365] + 52 ; push_rdx # allocate stack for pool pointer + 4989E0 ; mov_r8,rsp # arg3 = &pool + 6A 02 ; push !2 + 59 ; pop_rcx # arg1 = EFI_LOADER_DATA + 4883EC 18 ; sub_rsp, !24 # allocate shadow stack space for UEFI + 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) + 4883C4 18 ; add_rsp, !24 # deallocate stack + 58 ; pop_rax # get pool + C3 ; ret # Protocol GUIDs -# :LOADED_IMAGE_PROTOCOL [_start+0x371] +# :LOADED_IMAGE_PROTOCOL [_start+0x37A] 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 [_start+0x379] 8E 3F 00 A0 C9 69 72 3B ; !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -# :SIMPLE_FS_PROTOCOL [_start+0x381] +# :SIMPLE_FS_PROTOCOL [_start+0x38A] 22 5B 4E 96 ; %0x0964e5b22 59 64 ; @0x6459 D2 11 ; @0x11d2 -# :SIMPLE_FS_PROTOCOL_8 [_start+0x389] 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -# :FILE_INFO_PROTOCOL [_start+0x391] +# :FILE_INFO_PROTOCOL [_start+0x39A] 92 6E 57 09 ; %0x09576e92 3F 6D ; @0x6d3f D2 11 ; @0x11d2 -# last 64-bits of GUID are identical to SIMPLE_FS_PROTOCOL + 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -# :default_file [_start+0x399] +# :default_file [_start+0x3AA] 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 [_start+0x3AF] +# :prefix [_start+0x3C0] 20 00 2B 00 3E 00 20 00 00 00 ; L" +> " -# :subprocess_error [_start+0x3B9] +# :subprocess_error [_start+0x3CA] 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 [_start+0x3D9] +# :suffix [_start+0x3EA] 0A 00 0D 00 00 00 ; L"Subprocess error\n\r" -# :image_handle [_start+0x3DF] +# :image_handle [_start+0x3F0] 00 00 00 00 00 00 00 00 -# :image [_start+0x3E7] +# :image [_start+0x3F8] 00 00 00 00 00 00 00 00 -# :system_out [_start+0x3EF] +# :rootdir [_start+0x400] 00 00 00 00 00 00 00 00 -# :PE32_end [_start+0x3F7] +# :root_device [_start+0x408] + 00 00 00 00 00 00 00 00 + +# :system_out [_start+0x410] + 00 00 00 00 00 00 00 00 + +# :PE32_end [_start+0x418]