diff --git a/amd64/Development/kaem-optional.M1 b/amd64/Development/kaem-optional.M1 index 180fc18..bfb1139 100644 --- a/amd64/Development/kaem-optional.M1 +++ b/amd64/Development/kaem-optional.M1 @@ -11,6 +11,7 @@ DEFINE add_rbx,rsi 4801F3 DEFINE add_r15,rbx 4901DF DEFINE add_r15,rdi 4901FF DEFINE add_rbx,[rdi+BYTE] 48035F +DEFINE and_rsp, 4883E4 DEFINE call E8 DEFINE call_[rcx+BYTE] FF51 DEFINE call_[r14+BYTE] 41FF56 @@ -18,6 +19,7 @@ DEFINE call_[r14+DWORD] 41FF96 DEFINE cmp_al, 3C DEFINE cmp_rbx,rdx 4839D3 DEFINE inc_rax 48FFC0 +DEFINE je 0F84 DEFINE je8 74 DEFINE jmp8 EB DEFINE jmp E9 @@ -66,6 +68,7 @@ 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_rsp,[rsp+BYTE] 488B6424 DEFINE mov_r12,[rsp+BYTE] 4C8B6424 DEFINE mov_r14,[rdx+BYTE] 4C8B72 DEFINE mov_rcx,[rip+DWORD] 488B0D @@ -77,18 +80,32 @@ DEFINE mov_[rax+BYTE],rsi 488970 DEFINE mov_[rip+DWORD],rcx 48890D DEFINE mov_[rip+DWORD],rax 488905 DEFINE pop_rax 58 +DEFINE pop_rbx 5B +DEFINE pop_rbp 5D DEFINE pop_rcx 59 DEFINE pop_rdi 5F DEFINE pop_rdx 5A +DEFINE pop_rsi 5E DEFINE pop_r8 4158 DEFINE pop_r9 4159 +DEFINE pop_r12 415C +DEFINE pop_r13 415D +DEFINE pop_r14 415E +DEFINE pop_r15 415F DEFINE push 6A DEFINE push_rax 50 +DEFINE push_rbp 55 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 push_r12 4154 +DEFINE push_r13 4155 +DEFINE push_r14 4156 +DEFINE push_r15 4157 +DEFINE push_[rsp] FF3424 DEFINE ret C3 DEFINE sub_rbx, 4883EB DEFINE sub_rsp, 4883EC @@ -107,7 +124,17 @@ DEFINE xor_r15,r15 4D31FF # efi_main(void *image_handle, struct efi_system_table *system) :_start - mov_rbp,rsp # save stack pointer + # Save non-volatile registers + push_rbp + mov_rbp,rsp + push_rbx + push_rdi + push_rsi + push_r12 + push_r13 + push_r14 + push_r15 + mov_[rip+DWORD],rcx %image_handle # save image_handle mov_rbx,rcx # save image_handle mov_rax,[rdx+BYTE] !64 # system->out @@ -139,6 +166,7 @@ DEFINE xor_r15,r15 4D31FF # Get root directory lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + push_rax # align stack to 16 bytes 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) @@ -171,6 +199,7 @@ DEFINE xor_r15,r15 4D31FF :arg_done # Open file for reading + and_rsp, !-16 # align stack to 16 bytes push_rdx # allocate stack for fin mov_rdx,rsp # arg2 = &fin push !1 # arg5 = EFI_FILE_READ_ONLY @@ -181,7 +210,7 @@ DEFINE xor_r15,r15 4D31FF 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 + jne %terminate_2 # then exit without closing file mov_r12,[rsp+BYTE] !40 # get fin # Allocate pool for command @@ -245,6 +274,11 @@ DEFINE xor_r15,r15 4D31FF add_r15,rbx # go to the space separating command and its options mov_[r15],WORD @0 # zero it to hide command line options + # Align stack to 16 bytes + push_rsp + push_[rsp] + and_rsp, !-16 + # Open executable file for reading push_rdx # allocate stack for fcmd mov_rdx,rsp # arg2 = &fcmd @@ -359,6 +393,7 @@ DEFINE xor_r15,r15 4D31FF # Free device_path pool pop_rcx # arg1 = device_path + push_rax # make sure next call is aligned to 16 bytes push_rax # allocate shadow stack space for UEFI function call_[r14+BYTE] !72 # system->boot->free_pool(device_path) pop_rax # deallocate stack @@ -395,9 +430,8 @@ DEFINE xor_r15,r15 4D31FF 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 + + mov_rsp,[rsp+BYTE] !8 # deallocate stack (alignment before open executable) test_eax,eax # check if return code is 0 jne8 !print_error # print error and exit @@ -411,6 +445,11 @@ DEFINE xor_r15,r15 4D31FF # Close script file and exit :terminate + # Align stack to 16 bytes + push_rsp + push_[rsp] + and_rsp, !-16 + # Free pool mov_rcx,rbx # arg1 = command push_rax # save exit code @@ -439,19 +478,31 @@ DEFINE xor_r15,r15 4D31FF mov_rcx,r8 # arg1 = image_handle call %close_protocol # close protocol + # Restore non-volatile registers + pop_r15 + pop_r14 + pop_r13 + pop_r12 + pop_rsi + pop_rdi + pop_rbx + :abort - mov_rsp,rbp # restore stack - ret # return to UEFI + mov_rsp,rbp # restore stack + pop_rbp + ret # return to UEFI # File_Print function # Receives WCHAR* in RDX :File_Print + push_rsp # align stack to 16 bytes + push_[rsp] # align stack to 16 bytes + and_rsp, !-16 # align stack to 16 bytes 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 + mov_rsp,[rsp+BYTE] !24 # deallocate stack ret # read_byte function @@ -462,19 +513,18 @@ DEFINE xor_r15,r15 4D31FF mov_rdx,rsp # arg2 = &size push !0 # 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 + push_rsp # align stack to 16 bytes + push_[rsp] # align stack to 16 bytes + and_rsp, !-16 # align stack to 16 bytes + sub_rsp, !32 # allocate shadow stack space for UEFI and align stack call_[rcx+BYTE] !32 # fin->read() - pop_rax # deallocate stack - pop_rax # deallocate stack - pop_rax # deallocate stack + mov_rsp,[rsp+BYTE] !40 # 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 + je %terminate # then we are done ret # return @@ -485,11 +535,14 @@ DEFINE xor_r15,r15 4D31FF :open_protocol push_rax # allocate stack for interface mov_r8,rsp # arg3 = &interface + push_rsp # align stack to 16 bytes + push_[rsp] # align stack to 16 bytes + and_rsp, !-16 # align stack to 16 bytes 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 + mov_rsp,[rsp+BYTE] !56 # deallocate stack pop_rax # get interface ret @@ -497,10 +550,13 @@ DEFINE xor_r15,r15 4D31FF # rdx: &guid # r8: agent_handle :close_protocol + push_rsp # align stack to 16 bytes + push_[rsp] # align stack to 16 bytes + and_rsp, !-16 # align stack to 16 bytes 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 + mov_rsp,[rsp+BYTE] !40 # deallocate stack ret # rdx: number of bytes to allocate @@ -511,9 +567,12 @@ DEFINE xor_r15,r15 4D31FF mov_r8,rsp # arg3 = &pool push !2 pop_rcx # arg1 = EFI_LOADER_DATA - sub_rsp, !24 # allocate shadow stack space for UEFI + push_rsp # align stack to 16 bytes + push_[rsp] # align stack to 16 bytes + and_rsp, !-16 # align stack to 16 bytes + sub_rsp, !32 # allocate shadow stack space for UEFI and align stack call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) - add_rsp, !24 # deallocate stack + mov_rsp,[rsp+BYTE] !40 # deallocate stack pop_rax # get pool ret @@ -521,20 +580,20 @@ DEFINE xor_r15,r15 4D31FF # Protocol GUIDs :LOADED_IMAGE_PROTOCOL %0x5b1b31a1 - @0x9562 - @0x11d2 + $0x9562 + $0x11d2 !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :SIMPLE_FS_PROTOCOL %0x964e5b22 - @0x6459 - @0x11d2 + $0x6459 + $0x11d2 !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :FILE_INFO_PROTOCOL %0x09576e92 - @0x6d3f - @0x11d2 + $0x6d3f + $0x11d2 !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :default_file diff --git a/amd64/Development/kaem-optional.S b/amd64/Development/kaem-optional.S index dee5656..b637158 100644 --- a/amd64/Development/kaem-optional.S +++ b/amd64/Development/kaem-optional.S @@ -9,7 +9,17 @@ # efi_main(void *image_handle, struct efi_system_table *system) _start: - mov rbp, rsp # save stack pointer + # Save non-volatile registers + push rbp + mov rbp, rsp + push rbx + push rdi + push rsi + push r12 + push r13 + push r14 + push r15 + mov [rip+image_handle], rcx # save image_handle mov rbx, rcx # save image_handle mov rax, [rdx+64] # system->out @@ -41,6 +51,7 @@ _start: # Get root directory lea rdx, [rip+rootdir] # arg2 = &rootdir + push rax # align stack to 16 bytes 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) @@ -73,6 +84,7 @@ loop_options_done: arg_done: # Open file for reading + and rsp, -16 # align stack to 16 bytes push rdx # allocate stack for fin mov rdx, rsp # arg2 = &fin push 1 # arg5 = EFI_FILE_READ_ONLY @@ -147,6 +159,11 @@ read_command_done: add r15, rbx # go to the space separating command and its options mov WORD PTR [r15], 0 # zero it to hide command line options + # Align stack to 16 bytes + push rsp + push [rsp] + and rsp, -16 + # Open executable file for reading push rdx # allocate stack for fcmd mov rdx, rsp # arg2 = &fcmd @@ -261,6 +278,7 @@ read_command_done: # Free device_path pool pop rcx # arg1 = device_path + push rax # make sure next call is aligned to 16 bytes push rax # allocate shadow stack space for UEFI function call [r14+72] # system->boot->free_pool(device_path) pop rax # deallocate stack @@ -297,9 +315,8 @@ read_command_done: push rax # allocate shadow stack space for UEFI function push rax # allocate shadow stack space for UEFI function call [r14+208] # system->boot->start_image() - pop rcx # deallocate stack - pop rcx # deallocate stack - pop rcx # deallocate stack + + mov rsp, [rsp+8] # deallocate stack (alignment before open executable) test eax, eax # check if return code is 0 jne print_error # print error and exit @@ -313,6 +330,11 @@ print_error: # Close script file and exit terminate: + # Align stack to 16 bytes + push rsp + push [rsp] + and rsp, -16 + # Free pool mov rcx, rbx # arg1 = command push rax # save exit code @@ -341,19 +363,32 @@ terminate_2: mov rcx, r8 # arg1 = image_handle call close_protocol # close protocol + # Restore non-volatile registers + pop r15 + pop r14 + pop r13 + pop r12 + pop rsi + pop rdi + pop rbx + abort: mov rsp, rbp # restore stack + pop rbp ret # return to UEFI + # File_Print function # Receives WCHAR* in RDX File_Print: + push rsp # align stack to 16 bytes + push [rsp] # align stack to 16 bytes + and rsp, -16 # align stack to 16 bytes mov rcx, [rip+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+8] # system->out->output_string(system->out, WCHAR*) - pop rax # deallocate stack - pop rax # deallocate stack + mov rsp, [rsp+24] # deallocate stack ret # read_byte function @@ -364,13 +399,12 @@ read_byte: mov rdx, rsp # arg2 = &size push 0 # 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 + push rsp # align stack to 16 bytes + push [rsp] # align stack to 16 bytes + and rsp, -16 # align stack to 16 bytes + sub rsp, 32 # allocate shadow stack space for UEFI and align stack call [rcx+32] # fin->read() - pop rax # deallocate stack - pop rax # deallocate stack - pop rax # deallocate stack + mov rsp, [rsp+40] # deallocate stack pop rax # save c to rax pop rcx # save size to rcx @@ -385,38 +419,47 @@ read_byte: # 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 + push rax # allocate stack for interface + mov r8, rsp # arg3 = &interface + push rsp # align stack to 16 bytes + push [rsp] # align stack to 16 bytes + and rsp, -16 # align stack to 16 bytes + 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) + mov rsp, [rsp+56] # 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 + push rsp # align stack to 16 bytes + push [rsp] # align stack to 16 bytes + and rsp, -16 # align stack to 16 bytes + 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) + mov rsp, [rsp+40] # 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 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 + pop rcx # arg1 = EFI_LOADER_DATA + push rsp # align stack to 16 bytes + push [rsp] # align stack to 16 bytes + and rsp, -16 # align stack to 16 bytes + sub rsp, 32 # allocate shadow stack space for UEFI and align stack + call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) + mov rsp, [rsp+40] # deallocate stack + pop rax # get pool ret # Protocol GUIDs diff --git a/amd64/Development/kaem-optional.hex2 b/amd64/Development/kaem-optional.hex2 index 3bee683..6ca0828 100644 --- a/amd64/Development/kaem-optional.hex2 +++ b/amd64/Development/kaem-optional.hex2 @@ -5,7 +5,17 @@ # efi_main(void *image_handle, struct efi_system_table *system) :_start - 4889E5 ; mov_rbp,rsp # save stack pointer + # Save non-volatile registers + 55 ; push_rbp + 4889E5 ; mov_rbp,rsp + 53 ; push_rbx + 57 ; push_rdi + 56 ; push_rsi + 4154 ; push_r12 + 4155 ; push_r13 + 4156 ; push_r14 + 4157 ; push_r15 + 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 @@ -37,6 +47,7 @@ # Get root directory 488D15 %rootdir ; lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + 50 ; push_rax # align stack to 16 bytes 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) @@ -69,6 +80,7 @@ :arg_done # Open file for reading + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 52 ; push_rdx # allocate stack for fin 4889E2 ; mov_rdx,rsp # arg2 = &fin 6A 01 ; push !1 # arg5 = EFI_FILE_READ_ONLY @@ -79,7 +91,7 @@ 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 + 0F85 %terminate_2 ; jne %terminate_2 # then exit without closing file 4C8B6424 28 ; mov_r12,[rsp+BYTE] !40 # get fin # Allocate pool for command @@ -143,6 +155,11 @@ 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 + # Align stack to 16 bytes + 54 ; push_rsp + FF3424 ; push_[rsp] + 4883E4 F0 ; and_rsp, !-16 + # Open executable file for reading 52 ; push_rdx # allocate stack for fcmd 4889E2 ; mov_rdx,rsp # arg2 = &fcmd @@ -257,6 +274,7 @@ # Free device_path pool 59 ; pop_rcx # arg1 = device_path + 50 ; push_rax # make sure next call is aligned to 16 bytes 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 @@ -293,9 +311,8 @@ 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 + + 488B6424 08 ; mov_rsp,[rsp+BYTE] !8 # deallocate stack (alignment before open executable) 85C0 ; test_eax,eax # check if return code is 0 75 !print_error ; jne8 !print_error # print error and exit @@ -309,6 +326,11 @@ # Close script file and exit :terminate + # Align stack to 16 bytes + 54 ; push_rsp + FF3424 ; push_[rsp] + 4883E4 F0 ; and_rsp, !-16 + # Free pool 4889D9 ; mov_rcx,rbx # arg1 = command 50 ; push_rax # save exit code @@ -337,17 +359,29 @@ 4C89C1 ; mov_rcx,r8 # arg1 = image_handle E8 %close_protocol ; call %close_protocol # close protocol + # Restore non-volatile registers + 415F ; pop_r15 + 415E ; pop_r14 + 415D ; pop_r13 + 415C ; pop_r12 + 5E ; pop_rsi + 5F ; pop_rdi + 5B ; pop_rbx + :abort - 4889EC ; mov_rsp,rbp # restore stack - C3 ; ret # return to UEFI + 4889EC ; mov_rsp,rbp # restore stack + 5D ; pop_rbp + C3 ; ret # return to UEFI :File_Print + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 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 + 488B6424 18 ; mov_rsp,[rsp+BYTE] !24 # deallocate stack C3 ; ret # read_byte function @@ -358,19 +392,18 @@ 4889E2 ; mov_rdx,rsp # arg2 = &size 6A 00 ; push !0 # 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 + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI and align stack FF51 20 ; call_[rcx+BYTE] !32 # fin->read() - 58 ; pop_rax # deallocate stack - 58 ; pop_rax # deallocate stack - 58 ; pop_rax # deallocate stack + 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # 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 + 0F84 %terminate ; je %terminate # then we are done C3 ; ret # return @@ -381,11 +414,14 @@ :open_protocol 50 ; push_rax # allocate stack for interface 4989E0 ; mov_r8,rsp # arg3 = &interface + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 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 + 488B6424 38 ; mov_rsp,[rsp+BYTE] !56 # deallocate stack 58 ; pop_rax # get image C3 ; ret @@ -393,10 +429,13 @@ # rdx: &guid # r8: agent_handle :close_protocol + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 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 + 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack C3 ; ret # rdx: number of bytes to allocate @@ -407,29 +446,32 @@ 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 + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI and align stack 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) - 4883C4 18 ; add_rsp, !24 # deallocate stack + 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # 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 + A1 31 1B 5B ; %0x5b1b31a1 + 62 95 ; $0x9562 + D2 11 ; $0x11d2 8E 3F 00 A0 C9 69 72 3B ; !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :SIMPLE_FS_PROTOCOL 22 5B 4E 96 ; %0x964e5b22 - 59 64 ; @0x6459 - D2 11 ; @0x11d2 + 59 64 ; $0x6459 + D2 11 ; $0x11d2 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 + 3F 6D ; $0x6d3f + D2 11 ; $0x11d2 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :default_file diff --git a/amd64/kaem-optional.hex0 b/amd64/kaem-optional.hex0 index 55bae55..ee37f81 100644 --- a/amd64/kaem-optional.hex0 +++ b/amd64/kaem-optional.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" -19 04 00 00 ; VirtualSize +7E 04 00 00 ; VirtualSize 00 10 00 00 ; VirtualAddress -EE 03 00 00 ; SizeOfRawData +53 04 00 00 ; SizeOfRawData 70 01 00 00 ; PointerToRawData 00 00 00 00 ; PointerToRelocations 00 00 00 00 ; PointerToLinenumbers @@ -136,11 +136,21 @@ EE 03 00 00 ; SizeOfRawData # efi_main(void *image_handle, struct efi_system_table *system) # :_start - 4889E5 ; mov_rbp,rsp # save stack pointer - 48890D E7030000 ; mov_[rip+DWORD],rcx %image_handle # save image_handle + # Save non-volatile registers + 55 ; push_rbp + 4889E5 ; mov_rbp,rsp + 53 ; push_rbx + 57 ; push_rdi + 56 ; push_rsi + 4154 ; push_r12 + 4155 ; push_r13 + 4156 ; push_r14 + 4157 ; push_r15 + + 48890D 40040000 ; 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 F9030000 ; mov_[rip+DWORD],rax %system_out # save system->out + 488905 52040000 ; mov_[rip+DWORD],rax %system_out # save system->out 4C8B72 60 ; mov_r14,[rdx+BYTE] !96 # system->boot 31C9 ; xor_ecx,ecx # timeout = 0 @@ -152,22 +162,23 @@ EE 03 00 00 ; SizeOfRawData # Open Loaded Image protocol 4989D9 ; mov_r9,rbx # arg4 = image_handle - 488D15 40030000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 488D15 99030000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL 4889D9 ; mov_rcx,rbx # arg1 = image_handle - E8 F7020000 ; call %open_protocol # open protocol + E8 35030000 ; call %open_protocol # open protocol 4889C7 ; mov_rdi,rax # save image - 488905 AC030000 ; mov_[rip+DWORD],rax %image # save image + 488905 05040000 ; mov_[rip+DWORD],rax %image # save image # Get root file system 4989D9 ; mov_r9,rbx # arg4 = image_handle - 488D15 34030000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488D15 8D030000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL 488B4F 18 ; mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device - 48890D A7030000 ; mov_[rip+DWORD],rcx %root_device # save root_device - E8 D3020000 ; call %open_protocol # open protocol + 48890D 00040000 ; mov_[rip+DWORD],rcx %root_device # save root_device + E8 11030000 ; call %open_protocol # open protocol 4889C1 ; mov_rcx,rax # get rootfs # Get root directory - 488D15 90030000 ; lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + 488D15 E9030000 ; lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + 50 ; push_rax # align stack to 16 bytes 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) @@ -179,7 +190,7 @@ EE 03 00 00 ; SizeOfRawData 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] +# :loop_options [_start+0x92] 4839D3 ; cmp_rbx,rdx # Check if we are done 74 14 ; je8 !loop_options_done # We are done 4883EB 02 ; sub_rbx, !2 # --options @@ -190,41 +201,42 @@ EE 03 00 00 ; SizeOfRawData 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] +# :loop_options_done [_start+0xAB] 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 FF020000 ; lea_r8,[rip+DWORD] %default_file # Use "kaem.amd64" -# :arg_done [_start+0xAC] + 4C8D05 57030000 ; lea_r8,[rip+DWORD] %default_file # Use "kaem.amd64" +# :arg_done [_start+0xB9] # Open file for reading + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 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 44030000 ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + 488B0D 98030000 ; 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 + 0F85 24020000 ; jne %terminate_2 # then exit without closing file 4C8B6424 28 ; mov_r12,[rsp+BYTE] !40 # get fin # Allocate pool for command 31D2 ; xor_edx,edx # zero RDX B6 10 ; mov_dh, !0x10 # arg2 = 4096 = 0x1000 - E8 8C020000 ; call %allocate_pool # allocate memory + E8 D7020000 ; call %allocate_pool # allocate memory 4889C3 ; mov_rbx,rax # get command -# :next_command [_start+0xDD] +# :next_command [_start+0xEE] 31F6 ; xor_esi,esi # i = 0 4D31FF ; xor_r15,r15 # command_length = 0 -# :read_command [_start+0xE2] - E8 36020000 ; call %read_byte # read another byte c +# :read_command [_start+0xF3] + E8 60020000 ; call %read_byte # read another byte c 3C 0A ; cmp_al, !0xa # if c == '\n' 74 2A ; je8 !read_command_done # then we are done with this command command command @@ -235,25 +247,25 @@ EE 03 00 00 ; SizeOfRawData 75 03 ; jne8 !read_command_comments 4989F7 ; mov_r15,rsi # command_length = i -# :read_command_comments [_start+0xF7] +# :read_command_comments [_start+0x108] 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+0xFB] - E8 1D020000 ; call %read_byte # get another char +# :read_command_skip_comment [_start+0x10C] + E8 47020000 ; 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 -# :read_command_store_char [_start+0x106] +# :read_command_store_char [_start+0x117] 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+0x115] +# :read_command_done [_start+0x126] 4D85FF ; test_r15,r15 # if command_length == 0 74 C3 ; je8 !next_command # deal with another line @@ -263,17 +275,22 @@ EE 03 00 00 ; SizeOfRawData 4883C6 02 ; add_rsi, !2 # add 2 to get string length with NULL terminator - 488D15 91020000 ; lea_rdx,[rip+DWORD] %prefix # get prefix " +> " - E8 D9010000 ; call %File_Print # print it + 488D15 E5020000 ; lea_rdx,[rip+DWORD] %prefix # get prefix " +> " + E8 F8010000 ; call %File_Print # print it 4889DA ; mov_rdx,rbx # get command - E8 D1010000 ; call %File_Print # print it - 488D15 A7020000 ; lea_rdx,[rip+DWORD] %suffix # get suffix "\n\r" - E8 C5010000 ; call %File_Print # print it + E8 F0010000 ; call %File_Print # print it + 488D15 FB020000 ; lea_rdx,[rip+DWORD] %suffix # get suffix "\n\r" + E8 E4010000 ; call %File_Print # print it # Remove 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 + # Align stack to 16 bytes + 54 ; push_rsp + FF3424 ; push_[rsp] + 4883E4 F0 ; and_rsp, !-16 + # Open executable file for reading 52 ; push_rdx # allocate stack for fcmd 4889E2 ; mov_rdx,rsp # arg2 = &fcmd @@ -281,11 +298,11 @@ EE 03 00 00 ; SizeOfRawData 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 9B020000 ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + 488B0D E7020000 ; 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 + 0F85 42010000 ; jne %print_error # then exit 4883C4 28 ; add_rsp, !40 # deallocate stack 5F ; pop_rdi # get fcmd @@ -295,7 +312,7 @@ EE 03 00 00 ; SizeOfRawData # Allocate pool for file_info 31D2 ; xor_edx,edx # zero RDX B6 10 ; mov_dh, !0x10 # arg2 = 4096 = 0x1000 - E8 DD010000 ; call %allocate pool # allocate memory + E8 20020000 ; call %allocate pool # allocate memory 4989C1 ; mov_r9,rax # get file_info (arg4 for get_info) # Get file info @@ -303,7 +320,7 @@ EE 03 00 00 ; SizeOfRawData 50 ; push_rax # allocate stack for file_size 4989E0 ; mov_r8,rsp # arg3 = &file_size 49C700 00100000 ; mov_[r8], %0x1000 # file_size = 0x1000 - 488D15 FC010000 ; lea_rdx,[rip+DWORD] %FILE_INFO_PROTOCOL # arg2 = &EFI_FILE_INFO_PROTOCOL + 488D15 48020000 ; 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) @@ -318,9 +335,9 @@ EE 03 00 00 ; SizeOfRawData 58 ; pop_rax # deallocate stack 5A ; pop_rdx # restore file_size from stack (arg2 for allocate_pool) - # Allocate pool for executable [_start+0x1BA] + # Allocate pool for executable [_start+0x1D3] 52 ; push_rdx # save file_size onto stack - E8 A6010000 ; call %allocate_pool # allocate memory + E8 E9010000 ; call %allocate_pool # allocate memory 4989C7 ; mov_r15,rax # get executable 5A ; pop_rdx # restore file_size @@ -348,7 +365,7 @@ EE 03 00 00 ; SizeOfRawData # Allocate memory for device_path struct 6A 1C ; push !28 # 4 + sizeof(struct efi_device_path_protocol) 5A ; pop_rdx # arg2 = 28 - E8 7E010000 ; call %allocate_pool # allocate memory + E8 C1010000 ; call %allocate_pool # allocate memory 4989C0 ; mov_r8,rax # get device_path # Initialize struct @@ -379,7 +396,7 @@ EE 03 00 00 ; SizeOfRawData 57 ; push_rdi # arg5 = file size 4D89F9 ; mov_r9,r15 # arg4 = executable # arg3 = device_path - 488B15 B3010000 ; mov_rdx,[rip+DWORD] %image_handle # arg2 = image_handle + 488B15 FF010000 ; 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() @@ -388,6 +405,7 @@ EE 03 00 00 ; SizeOfRawData # Free device_path pool 59 ; pop_rcx # arg1 = device_path + 50 ; push_rax # make sure next call is aligned to 16 bytes 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 @@ -398,23 +416,23 @@ EE 03 00 00 ; SizeOfRawData 41FF56 48 ; call_[r14+BYTE] !72 # system->boot->free_pool(executable) 58 ; pop_rax # deallocate stack - # Open Child Image [_start+0x260] + # Open Child Image [_start+0x27A] 4989F9 ; mov_r9,rdi # arg4 = child_ih - 488D15 11010000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 488D15 5C010000 ; 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 C7000000 ; call %open_protocol # open protocol + E8 F7000000 ; call %open_protocol # open protocol 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 77010000 ; mov_rcx,[rip+DWORD] %image # get image + 488B0D C2010000 ; 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 BD000000 ; call %close_protocol # close protocol + E8 F6000000 ; call %close_protocol # close protocol # Run command 4D31C0 ; xor_r8,r8 # arg3 = 0 (ExitData) @@ -424,22 +442,26 @@ EE 03 00 00 ; SizeOfRawData 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 + + 488B6424 08 ; mov_rsp,[rsp+BYTE] !8 # deallocate stack (alignment before open executable) 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 + E9 1EFEFFFF ; jmp %next_command # process another line from kaem script -# :print_error [_start+0x2B4] +# :print_error [_start+0x2D0] 50 ; push_rax # save exit code - 488D15 0F010000 ; lea_rdx,[rip+DWORD] %subprocess_error # get error message - E8 4D000000 ; call %File_Print # print it + 488D15 58010000 ; lea_rdx,[rip+DWORD] %subprocess_error # get error message + E8 61000000 ; call %File_Print # print it 58 ; pop_rax # restore exit code # Close script file and exit -# :terminate [_start+0x2C2] +# :terminate [_start+0x2DE] + # Align stack to 16 bytes + 54 ; push_rsp + FF3424 ; push_[rsp] + 4883E4 F0 ; and_rsp, !-16 + # Free pool 4889D9 ; mov_rcx,rbx # arg1 = command 50 ; push_rax # save exit code @@ -449,59 +471,70 @@ EE 03 00 00 ; SizeOfRawData 4C89E1 ; mov_rcx,r12 # arg1 = fin FF51 10 ; call_[rcx+BYTE] !16 # fin->close(fin) - 488B0D 29010000 ; mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir + 488B0D 6A010000 ; 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 [_start+0x2DD] - 4C8B05 0D010000 ; mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle +# :terminate_2 [_start+0x301] + 4C8B05 4E010000 ; mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle 4150 ; push_r8 # save image_handle - 488D15 9E000000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL - 488B0D 15010000 ; mov_rcx,[rip+DWORD] %root_device # arg1 = root_device - E8 5A000000 ; call %close_protocol # close protocol + 488D15 DF000000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B0D 56010000 ; mov_rcx,[rip+DWORD] %root_device # arg1 = root_device + E8 89000000 ; call %close_protocol # close protocol 4158 ; pop_r8 # arg3 = image_handle - 488D15 79000000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 488D15 BA000000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL 4C89C1 ; mov_rcx,r8 # arg1 = image_handle - E8 49000000 ; call %close_protocol # close protocol + E8 78000000 ; call %close_protocol # close protocol -# :abort [_start+0x30A] - 4889EC ; mov_rsp,rbp # restore stack - C3 ; ret # return to UEFI + # Restore non-volatile registers + 415F ; pop_r15 + 415E ; pop_r14 + 415D ; pop_r13 + 415C ; pop_r12 + 5E ; pop_rsi + 5F ; pop_rdi + 5B ; pop_rbx -# :File_Print [_start+0x30E] - 488B0D FC000000 ; mov_rcx,[rip+DWORD] %system_out # get system_out +# :abort [_start+0x339] + 4889EC ; mov_rsp,rbp # restore stack + 5D ; pop_rbp + C3 ; ret # return to UEFI + +# :File_Print [_start+0x33E] + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes + 488B0D 29010000 ; 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 + 488B6424 18 ; mov_rsp,[rsp+BYTE] !24 # deallocate stack C3 ; ret # read_byte function # reads a single character -# :read_byte [_start+0x31D] +# :read_byte [_start+0x358] 4C89E1 ; mov_rcx,r12 # arg1 = fin 6A 01 ; push !1 # size = 1 4889E2 ; mov_rdx,rsp # arg2 = &size 6A 00 ; push !0 # 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 + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI and align stack FF51 20 ; call_[rcx+BYTE] !32 # fin->read() - 58 ; pop_rax # deallocate stack - 58 ; pop_rax # deallocate stack - 58 ; pop_rax # deallocate stack + 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # 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 89 ; je8 !terminate # then we are done + 0F84 5BFFFFFF ; je %terminate # then we are done C3 ; ret # return @@ -509,77 +542,86 @@ EE 03 00 00 ; SizeOfRawData # rdx: &guid # r9: agent_handle # returns interface -# :open_protocol [_start+0x340] +# :open_protocol [_start+0x384] 50 ; push_rax # allocate stack for interface 4989E0 ; mov_r8,rsp # arg3 = &interface + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 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 + 488B6424 38 ; mov_rsp,[rsp+BYTE] !56 # deallocate stack 58 ; pop_rax # get image C3 ; ret # rcx: handle # rdx: &guid # r8: agent_handle -# :close_protocol [_start+0x353] +# :close_protocol [_start+0x3A6] + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes 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 + 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack C3 ; ret # rdx: number of bytes to allocate # r14: system->boot # returns pointer in rax -# :allocate_pool [_start+0x366] +# :allocate_pool [_start+0x3C2] 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 + 54 ; push_rsp # align stack to 16 bytes + FF3424 ; push_[rsp] # align stack to 16 bytes + 4883E4 F0 ; and_rsp, !-16 # align stack to 16 bytes + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI and align stack 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) - 4883C4 18 ; add_rsp, !24 # deallocate stack + 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack 58 ; pop_rax # get pool C3 ; ret # Protocol GUIDs -# :LOADED_IMAGE_PROTOCOL [_start+0x37B] +# :LOADED_IMAGE_PROTOCOL [_start+0x3E0] A1 31 1B 5B ; %0x5b1b31a1 - 62 95 ; @0x9562 - D2 11 ; @0x11d2 + 62 95 ; $0x9562 + D2 11 ; $0x11d2 8E 3F 00 A0 C9 69 72 3B ; !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -# :SIMPLE_FS_PROTOCOL [_start+0x38B] +# :SIMPLE_FS_PROTOCOL [_start+0x3F0] 22 5B 4E 96 ; %0x964e5b22 - 59 64 ; @0x6459 - D2 11 ; @0x11d2 + 59 64 ; $0x6459 + D2 11 ; $0x11d2 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -# :FILE_INFO_PROTOCOL [_start+0x39B] +# :FILE_INFO_PROTOCOL [_start+0x400] 92 6E 57 09 ; %0x09576e92 - 3F 6D ; @0x6d3f - D2 11 ; @0x11d2 + 3F 6D ; $0x6d3f + D2 11 ; $0x11d2 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -# :default_file [_start+0x3AB] +# :default_file [_start+0x410] 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+0x3C1] +# :prefix [_start+0x426] 20 00 2B 00 3E 00 20 00 00 00 ; L" +> " -# :subprocess_error [_start+0x3CB] +# :subprocess_error [_start+0x430] 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+0x3EB] +# :suffix [_start+0x450] 0A 00 0D ; L"Subprocess error\n\r" -# :ELF_end [_start+0x3EE] -# :image_handle [_start+0x3F1] -# :image [_start+0x3F9] -# :rootdir [_start+0x401] -# :root_device [_start+0x409] -# :system_out [_start+0x411] -# :VirtualSizeEnd [_start+0x419] +# :ELF_end [_start+0x453] +# :image_handle [_start+0x456] +# :image [_start+0x45E] +# :rootdir [_start+0x466] +# :root_device [_start+0x46E] +# :system_out [_start+0x476] +# :VirtualSizeEnd [_start+0x47E]