From 1407f92220a6e0f28b4fa03626d8114799ce17c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 23 Dec 2023 23:09:33 +0000 Subject: [PATCH] cc_amd64: fix stack alignment and save non-volatile registers. --- amd64/Development/M0.M1 | 6 +- amd64/Development/M0.S | 6 +- amd64/Development/catm.M1 | 8 +-- amd64/Development/catm.S | 6 +- amd64/Development/cc_amd64.S | 85 +++++++++++++++++----- amd64/Development/hex1.S | 4 +- amd64/Development/hex1.hex2 | 4 +- amd64/Development/hex2.M1 | 2 +- amd64/Development/hex2.S | 2 +- amd64/Development/kaem-optional.S | 2 +- amd64/Development/kaem-optional.hex2 | 2 +- amd64/M0.hex2 | 4 +- amd64/cc_amd64.M1 | 102 +++++++++++++++++++++------ amd64/hex1.hex0 | 4 +- amd64/hex2.hex1 | 4 +- amd64/kaem-optional.hex0 | 4 +- 16 files changed, 176 insertions(+), 69 deletions(-) diff --git a/amd64/Development/M0.M1 b/amd64/Development/M0.M1 index e2f2e68..1327598 100644 --- a/amd64/Development/M0.M1 +++ b/amd64/Development/M0.M1 @@ -402,7 +402,7 @@ DEFINE xor_r13,r13 4D31ED 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 + sub_rsp, !32 # allocate shadow stack space for UEFI function call_[rcx+BYTE] !32 # fin->read() mov_rsp,[rsp+BYTE] !40 # deallocate stack pop_rax # save input to rax @@ -1169,7 +1169,7 @@ DEFINE xor_r13,r13 4D31ED 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 + sub_rsp, !32 # allocate shadow stack space for UEFI function call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) mov_rsp,[rsp+BYTE] !40 # deallocate stack pop_rax # get pool @@ -1181,7 +1181,7 @@ DEFINE xor_r13,r13 4D31ED 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 + sub_rsp, !32 # allocate shadow stack space for UEFI function call_[r14+BYTE] !72 # system->boot->free_pool(pool) mov_rsp,[rsp+BYTE] !40 # deallocate stack ret diff --git a/amd64/Development/M0.S b/amd64/Development/M0.S index 102e60e..14e6d20 100644 --- a/amd64/Development/M0.S +++ b/amd64/Development/M0.S @@ -252,7 +252,7 @@ fgetc: 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 + sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+32] # fin->read() mov rsp, [rsp+40] # deallocate stack pop rax # save input to rax @@ -958,7 +958,7 @@ fputc: mov rdx, rsp # arg2 = &size push rax # allocate stack mov r8, rsp # arg3 = &output - sub rsp, 32 # allocate shadow stack space for UEFI + sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+40] # fout->write() mov rsp, [rsp+56] # deallocate stack @@ -1019,7 +1019,7 @@ allocate_pool: 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 + sub rsp, 32 # allocate shadow stack space for UEFI function call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) mov rsp, [rsp+40] # deallocate stack pop rax # get pool diff --git a/amd64/Development/catm.M1 b/amd64/Development/catm.M1 index 65db0eb..70278ae 100644 --- a/amd64/Development/catm.M1 +++ b/amd64/Development/catm.M1 @@ -294,7 +294,7 @@ DEFINE xor_r9,r9 4D31C9 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 + sub_rsp, !32 # allocate shadow stack space for UEFI function call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) mov_rsp,[rsp+BYTE] !40 # deallocate stack pop_rax # get pool @@ -306,7 +306,7 @@ DEFINE xor_r9,r9 4D31C9 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 + sub_rsp, !32 # allocate shadow stack space for UEFI function call_[r14+BYTE] !72 # system->boot->free_pool(pool) mov_rsp,[rsp+BYTE] !40 # deallocate stack ret @@ -323,7 +323,7 @@ DEFINE xor_r9,r9 4D31C9 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 + sub_rsp, !32 # allocate shadow stack space for UEFI function call_[rcx+BYTE] !32 # fin->read() mov_rsp,[rsp+BYTE] !40 # deallocate stack pop_rax # save size to rax @@ -341,7 +341,7 @@ DEFINE xor_r9,r9 4D31C9 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 + sub_rsp, !32 # allocate shadow stack space for UEFI function call_[rcx+BYTE] !40 # fin->write() mov_rsp,[rsp+BYTE] !40 # deallocate stack pop_rax # save size to rax diff --git a/amd64/Development/catm.S b/amd64/Development/catm.S index 8caf2e6..1fabbef 100644 --- a/amd64/Development/catm.S +++ b/amd64/Development/catm.S @@ -218,7 +218,7 @@ allocate_pool: 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 + sub rsp, 32 # allocate shadow stack space for UEFI function call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) mov rsp, [rsp+40] # deallocate stack pop rax # get pool @@ -247,7 +247,7 @@ read: 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 + sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+32] # fin->read() mov rsp, [rsp+40] # deallocate stack pop rax # save size to rax @@ -265,7 +265,7 @@ write: 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 + sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+40] # fin->write() mov rsp, [rsp+40] # deallocate stack pop rax # save size to rax diff --git a/amd64/Development/cc_amd64.S b/amd64/Development/cc_amd64.S index afaa154..feb8b33 100644 --- a/amd64/Development/cc_amd64.S +++ b/amd64/Development/cc_amd64.S @@ -42,7 +42,17 @@ # efi_main(void *image_handle, struct efi_system_table *system) _start: + # Save non-volatile registers + push rbp + push rbx + push rdi + push rsi + push r12 + push r13 + push r14 + push r15 mov rbp, rsp # save stack pointer + mov [rip+image_handle], rcx # save image_handle mov [rip+system], rdx # save system mov r14, [rdx+96] # system->boot @@ -64,9 +74,9 @@ _start: # Get root directory lea rdx, [rip+rootdir] # arg2 = &rootdir - sub rsp, 16 # allocate shadow stack space for UEFI function + sub rsp, 40 # allocate shadow stack space for UEFI function call [rcx+8] # rootfs->open_volume(rootfs, &rootdir) - add rsp, 16 # deallocate stack + add rsp, 40 # deallocate stack # Push command line arguments onto stack mov rbx, [rdi+56] # options = image->load_options @@ -86,8 +96,11 @@ loop_options: jmp loop_options # next argument loop_options_done: - # Open file for reading pop r8 # arg3 = in + pop r12 # file out + and rsp, -16 # align stack to 16 bytes + + # Open file for reading push 1 # Set exit code in case of failure cmp r8, 0 # If NULL je failed_input # then exit @@ -102,7 +115,7 @@ loop_options_done: add rsp, 48 # deallocate stack # Open file for writing - pop r8 # arg3 = out + mov r8, r12 # arg3 = out push 1 # Set exit code in case of failure cmp r8, 0 # If NULL je failed_output # then exit @@ -200,7 +213,17 @@ failed_input: pop rax # restore exit code abort: # used for debugging only - mov rsp, rbp # restore stack + + # Restore non-volatile registers + mov rsp, rbp + pop r15 + pop r14 + pop r13 + pop r12 + pop rsi + pop rdi + pop rbx + pop rbp ret # return to UEFI @@ -642,9 +665,12 @@ fgetc: mov rdx, rsp # arg2 = &size push 0 # zero rsi mov r8, rsp # arg3 = &input - sub rsp, 24 # 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 function call [rcx+32] # fin->read() - add rsp, 24 # deallocate stack + mov rsp, [rsp+40] # deallocate stack pop rax # save input to rax pop rsi # save size to rsi @@ -748,9 +774,12 @@ fputc: mov rcx, [rcx+64] # system->out (system->err doesn't print anything for some reason) mov [rip+WCHAR], rax # Convert to WCHAR lea rdx, [rip+WCHAR] # arg3 = *WCHAR - sub rsp, 16 # 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 function call [rcx+8] # system->err->output_string(system->err, WCHAR*) - add rsp, 16 # deallocate stack + mov rsp, [rsp+40] # deallocate stack popf # Restore condition jne fputc_done # We are done if not LF @@ -759,14 +788,17 @@ fputc: jmp fputc_done # We are done fputc_file: + 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+fout] # arg1 = fout push 1 # set size mov rdx, rsp # arg2 = &size push rax # allocate stack mov r8, rsp # arg3 = &output - sub rsp, 24 # allocate shadow stack space for UEFI function + sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+40] # fout->write() - add rsp, 40 # deallocate stack + mov rsp, [rsp+56] # deallocate stack fputc_done: pop rdx # Restore RDX @@ -4540,9 +4572,12 @@ Exit_Failure: # rcx: file handle close_file: - 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 function call [rcx+16] # file_handle->close(file_handle) - pop rax # deallocate stack + mov rsp, [rsp+40] # deallocate stack ret # rcx: handle @@ -4552,11 +4587,14 @@ close_file: 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+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+56] # deallocate stack pop rax # get interface ret @@ -4564,10 +4602,13 @@ open_protocol: # 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 mov r9, 0 # 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 + mov rsp, [rsp+40] # deallocate stack ret # rdx: number of bytes to allocate @@ -4577,18 +4618,24 @@ allocate_pool: push rdx # allocate stack for pool pointer mov r8, rsp # arg3 = &pool mov rcx, 2 # 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 function call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) - add rsp, 24 # deallocate stack + mov rsp, [rsp+40] # deallocate stack pop rax # get pool ret # rcx: memory pool # r14: system->boot free_pool: - 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 function call [r14+72] # system->boot->free_pool(pool) - pop rax # deallocate stack + mov rsp, [rsp+40] # deallocate stack ret # Switch to uefi stack diff --git a/amd64/Development/hex1.S b/amd64/Development/hex1.S index 811d66c..7aec17c 100644 --- a/amd64/Development/hex1.S +++ b/amd64/Development/hex1.S @@ -123,7 +123,7 @@ loop_options_done: mov dh, 0x8 # arg2 = 256 * 8 = 2048 = 0x800 push 2 pop rcx # arg1 = EFI_LOADER_DATA - sub rsp, 32 # allocate shadow stack space for UEFI + sub rsp, 32 # allocate shadow stack space for UEFI function call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table) add rsp, 32 # deallocate stack @@ -135,7 +135,7 @@ loop_options_done: # rewind input file mov rcx, rdi # Using our input file xor edx, edx # Offset Zero - sub rsp, 32 # allocate shadow stack space for UEFI + sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+56] # fin->set_position(fin, 0) add rsp, 32 # deallocate stack diff --git a/amd64/Development/hex1.hex2 b/amd64/Development/hex1.hex2 index 306c3ed..fe55f78 100644 --- a/amd64/Development/hex1.hex2 +++ b/amd64/Development/hex1.hex2 @@ -119,7 +119,7 @@ B6 08 ; mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800 6A 02 ; push !2 59 ; pop_rcx # arg1 = EFI_LOADER_DATA - 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table) 4883C4 20 ; add_rsp, !32 # deallocate stack @@ -131,7 +131,7 @@ # rewind input file 4889F9 ; mov_rcx,rdi # Using our input file 31D2 ; xor_edx,edx # Offset Zero - 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0) 4883C4 20 ; add_rsp, !32 # deallocate stack diff --git a/amd64/Development/hex2.M1 b/amd64/Development/hex2.M1 index f2c8708..dc54c7d 100644 --- a/amd64/Development/hex2.M1 +++ b/amd64/Development/hex2.M1 @@ -817,7 +817,7 @@ DEFINE xor_r9,r9 4D31C9 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 + sub_rsp, !32 # allocate shadow stack space for UEFI function call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) mov_rsp,[rsp+BYTE] !40 # deallocate stack pop_rax # get pool diff --git a/amd64/Development/hex2.S b/amd64/Development/hex2.S index faa6b3a..afa0f8b 100644 --- a/amd64/Development/hex2.S +++ b/amd64/Development/hex2.S @@ -692,7 +692,7 @@ allocate_pool: 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 + sub rsp, 32 # allocate shadow stack space for UEFI function call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) mov rsp, [rsp+40] # deallocate stack pop rax # get pool diff --git a/amd64/Development/kaem-optional.S b/amd64/Development/kaem-optional.S index 368587c..3ab63aa 100644 --- a/amd64/Development/kaem-optional.S +++ b/amd64/Development/kaem-optional.S @@ -51,7 +51,7 @@ _start: # Get root directory lea rdx, [rip+rootdir] # arg2 = &rootdir - sub rsp, 32 # allocate shadow stack space for UEFI + sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+8] # rootfs->open_volume(rootfs, &rootdir) add rsp, 32 # deallocate stack diff --git a/amd64/Development/kaem-optional.hex2 b/amd64/Development/kaem-optional.hex2 index ded45c7..6a00fca 100644 --- a/amd64/Development/kaem-optional.hex2 +++ b/amd64/Development/kaem-optional.hex2 @@ -379,7 +379,7 @@ :File_Print 488B0D %system_out ; mov_rcx,[rip+DWORD] %system_out # get system_out - 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI + 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI function FF51 08 ; call_[rcx+BYTE] !8 # system->out->output_string(system->out, WCHAR*) 4883C4 28 ; add_rsp, !40 # deallocate stack C3 ; ret diff --git a/amd64/M0.hex2 b/amd64/M0.hex2 index 2090316..4250812 100644 --- a/amd64/M0.hex2 +++ b/amd64/M0.hex2 @@ -1014,7 +1014,7 @@ 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 + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack 58 ; pop_rax # get pool @@ -1026,7 +1026,7 @@ 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 + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function 41FF56 48 ; call_[r14+BYTE] !72 # system->boot->free_pool(pool) 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack C3 ; ret diff --git a/amd64/cc_amd64.M1 b/amd64/cc_amd64.M1 index e4fcdd2..5e37266 100644 --- a/amd64/cc_amd64.M1 +++ b/amd64/cc_amd64.M1 @@ -26,9 +26,10 @@ DEFINE add_rax,rbx 4801D8 DEFINE add_rax,rcx 4801C8 DEFINE add_rbx,rax 4801C3 DEFINE add_rcx,rdi 4801F9 -DEFINE and_rax, 4825 -DEFINE and_rax,rbx 4821D8 DEFINE add_rbx,[rdi+BYTE] 48035F +DEFINE and_rax, 4825 +DEFINE and_rsp, 4883E4 +DEFINE and_rax,rbx 4821D8 DEFINE call E8 DEFINE call_rax FFD0 DEFINE call_[rcx+BYTE] FF51 @@ -98,6 +99,7 @@ DEFINE mov_rsi,rax 4889C6 DEFINE mov_rsi,rdi 4889FE DEFINE mov_rsp,rbp 4889EC DEFINE mov_r8,rsp 4989E0 +DEFINE mov_r8,r12 4D89E0 DEFINE mov_r12,rax 4989C4 DEFINE mov_al,[rax] 8A00 DEFINE mov_al,[rbx] 8A03 @@ -141,6 +143,7 @@ DEFINE mov_rcx,[rdi+BYTE] 488B4F DEFINE mov_rcx,[rdx+BYTE] 488B4A DEFINE mov_rdi,[rdx+BYTE] 488B7A DEFINE mov_rdx,[rdx+BYTE] 488B52 +DEFINE mov_rsp,[rsp+BYTE] 488B6424 DEFINE mov_r14,[rdx+BYTE] 4C8B72 DEFINE mov_rax,[rax+DWORD] 488B40 DEFINE mov_rbx,[rbx+DWORD] 488B5B @@ -179,6 +182,10 @@ DEFINE pop_rdi 5F DEFINE pop_rdx 5A DEFINE pop_rsi 5E DEFINE pop_r8 4158 +DEFINE pop_r12 415C +DEFINE pop_r13 415D +DEFINE pop_r14 415E +DEFINE pop_r15 415F DEFINE push 6A DEFINE pushf 9C DEFINE push_rax 50 @@ -188,6 +195,12 @@ DEFINE push_rcx 51 DEFINE push_rdi 57 DEFINE push_rdx 52 DEFINE push_rsi 56 +DEFINE push_rsp 54 +DEFINE push_r12 4154 +DEFINE push_r13 4155 +DEFINE push_r14 4156 +DEFINE push_r15 4157 +DEFINE push_[rsp] FF3424 DEFINE ret C3 DEFINE ror_r9 49D1C9 DEFINE sal_rax, 48C1E0 @@ -226,7 +239,17 @@ DEFINE NULL 0000000000000000 # efi_main(void *image_handle, struct efi_system_table *system) :_start + # Save non-volatile registers + push_rbp + push_rbx + push_rdi + push_rsi + push_r12 + push_r13 + push_r14 + push_r15 mov_rbp,rsp # save stack pointer + mov_[rip+DWORD],rcx %image_handle # save image_handle mov_[rip+DWORD],rdx %system # save system mov_r14,[rdx+BYTE] !96 # system->boot @@ -248,9 +271,9 @@ DEFINE NULL 0000000000000000 # Get root directory lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir - sub_rsp, %16 # allocate shadow stack space for UEFI function + sub_rsp, %40 # allocate shadow stack space for UEFI function call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) - add_rsp, %16 # deallocate stack + add_rsp, %40 # deallocate stack # Push command line arguments onto stack mov_rbx,[rdi+BYTE] !56 # options = image->load_options @@ -270,8 +293,11 @@ DEFINE NULL 0000000000000000 jmp %loop_options # next argument :loop_options_done - # Open file for reading pop_r8 # arg3 = in + pop_r12 # file out + and_rsp, !-16 # align stack to 16 bytes + + # Open file for reading push !1 # Set exit code in case of failure cmp_r8, %0 # If NULL je %failed_input # then exit @@ -286,7 +312,7 @@ DEFINE NULL 0000000000000000 add_rsp, %48 # deallocate stack # Open file for writing - pop_r8 # arg3 = out + mov_r8,r12 # arg3 = out push !1 # Set exit code in case of failure cmp_r8, %0 # If NULL je %failed_output # then exit @@ -384,7 +410,17 @@ DEFINE NULL 0000000000000000 pop_rax # restore exit code :abort # used for debugging only - mov_rsp,rbp # restore stack + + # Restore non-volatile registers + mov_rsp,rbp + pop_r15 + pop_r14 + pop_r13 + pop_r12 + pop_rsi + pop_rdi + pop_rbx + pop_rbp ret # return to UEFI @@ -850,9 +886,12 @@ DEFINE NULL 0000000000000000 mov_rdx,rsp # arg2 = &size push !0 # allocate stack mov_r8,rsp # arg3 = &input - sub_rsp, %24 # 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 function call_[rcx+BYTE] !32 # fin->read() - add_rsp, %24 # deallocate stack + mov_rsp,[rsp+BYTE] !40 # deallocate stack pop_rax # save input to rax pop_rsi # save size to rsi @@ -956,9 +995,12 @@ DEFINE NULL 0000000000000000 mov_rcx,[rcx+BYTE] !64 # system->out (system->err doesn't print anything for some reason) mov_[rip+DWORD],rax %WCHAR # Convert to WCHAR lea_rdx,[rip+DWORD] %WCHAR # arg3 = *WCHAR - sub_rsp, %16 # 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 function call_[rcx+BYTE] !8 # system->err->output_string(system->err, WCHAR*) - add_rsp, %16 # deallocate stack + mov_rsp,[rsp+BYTE] !40 # deallocate stack popf # Restore condition jne %fputc_done # We are done if not LF @@ -967,14 +1009,17 @@ DEFINE NULL 0000000000000000 jmp %fputc_done # We are done :fputc_file + 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] %fout # arg1 = fout push !1 # set size mov_rdx,rsp # arg2 = &size push_rax # allocate stack mov_r8,rsp # arg3 = &output - sub_rsp, %24 # allocate shadow stack space for UEFI function + sub_rsp, %32 # allocate shadow stack space for UEFI function call_[rcx+BYTE] !40 # fout->write() - add_rsp, %40 # deallocate stack + mov_rsp,[rsp+BYTE] !56 # deallocate stack :fputc_done pop_rdx # Restore RDX @@ -5197,9 +5242,12 @@ Missing ; # rcx: file handle :close_file - 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 function call_[rcx+BYTE] !16 # file_handle->close(file_handle) - pop_rax # deallocate stack + mov_rsp,[rsp+BYTE] !40 # deallocate stack ret # rcx: handle @@ -5209,11 +5257,14 @@ Missing ; :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 @@ -5221,10 +5272,13 @@ Missing ; # 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 mov_r9, %0 # 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 @@ -5234,18 +5288,24 @@ Missing ; push_rdx # allocate stack for pool pointer mov_r8,rsp # arg3 = &pool mov_rcx, %2 # 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 function call_[r14+DWORD] %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 # rcx: memory pool # r14: system->boot :free_pool - 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 function call_[r14+DWORD] %72 # system->boot->free_pool(pool) - pop_rax # deallocate stack + mov_rsp,[rsp+BYTE] !40 # deallocate stack ret # Switch to uefi stack diff --git a/amd64/hex1.hex0 b/amd64/hex1.hex0 index f82bdae..c2eec86 100644 --- a/amd64/hex1.hex0 +++ b/amd64/hex1.hex0 @@ -248,7 +248,7 @@ F0 00 # SizeOfOptionalHeader B6 08 ; mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800 6A 02 ; push !2 59 ; pop_rcx # arg1 = EFI_LOADER_DATA - 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table) 4883C4 20 ; add_rsp, !32 # deallocate stack @@ -261,7 +261,7 @@ F0 00 # SizeOfOptionalHeader # rewind input file 4889F9 ; mov_rcx,rdi # Using our input file 31D2 ; xor_edx,edx # Offset Zero - 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0) 4883C4 20 ; add_rsp, !32 # deallocate stack diff --git a/amd64/hex2.hex1 b/amd64/hex2.hex1 index ce7589b..9aeb608 100644 --- a/amd64/hex2.hex1 +++ b/amd64/hex2.hex1 @@ -254,7 +254,7 @@ F0 00 # SizeOfOptionalHeader 4153 ; push_r11 # Protect r11 488B0D %0 ; mov_rcx,[rip+DWORD] %fin # Using our input file 31D2 ; xor_edx,edx # Offset Zero - 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI + 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI function FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0) 4883C4 28 ; add_rsp, !40 # deallocate stack 415B ; pop_r11 # restore r11 @@ -817,7 +817,7 @@ F0 00 # SizeOfOptionalHeader 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 + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) 488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack 58 ; pop_rax # get pool diff --git a/amd64/kaem-optional.hex0 b/amd64/kaem-optional.hex0 index 15e37d0..448c21c 100644 --- a/amd64/kaem-optional.hex0 +++ b/amd64/kaem-optional.hex0 @@ -301,7 +301,7 @@ F0 00 # SizeOfOptionalHeader 5F ; pop_rdi # get fcmd # Restore command line arguments - 6641C707 2000 ; STOREI16_into_Address_R15 @0x20 # restore command line options by readding ' ' + 6641C707 2000 ; STOREI16_into_Address_R15 @0x20 # restore command line options by readding ' ' # Allocate pool for file_info 31D2 ; xor_edx,edx # zero RDX @@ -510,7 +510,7 @@ F0 00 # SizeOfOptionalHeader # :File_Print [_start+0x361] 488B0D E3000000 ; mov_rcx,[rip+DWORD] %system_out # get system_out - 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI + 4883EC 28 ; sub_rsp, !40 # allocate shadow stack space for UEFI function FF51 08 ; call_[rcx+BYTE] !8 # system->out->output_string(system->out, WCHAR*) 4883C4 28 ; add_rsp, !40 # deallocate stack C3 ; ret