catm: fix stack alignment and save non-volatile registers.
This commit is contained in:
parent
c01f86c7c5
commit
e871378bcf
|
@ -6,6 +6,7 @@
|
|||
DEFINE add_rbx,[rdi+BYTE] 48035F
|
||||
DEFINE add_rbx, 4883C3
|
||||
DEFINE add_rsp, 4883C4
|
||||
DEFINE and_rsp, 4883E4
|
||||
DEFINE call E8
|
||||
DEFINE call_[rcx+BYTE] FF51
|
||||
DEFINE call_[r14+BYTE] 41FF56
|
||||
|
@ -15,6 +16,7 @@ DEFINE cmp_rax, 483D
|
|||
DEFINE cmp_rbx,rdx 4839D3
|
||||
DEFINE cmp_r8, 4983F8
|
||||
DEFINE je 74
|
||||
DEFINE je32 0F84
|
||||
DEFINE jmp EB
|
||||
DEFINE jne 75
|
||||
DEFINE lea_rdx,[rip+DWORD] 488D15
|
||||
|
@ -42,21 +44,37 @@ DEFINE mov_rax,[rsp+BYTE] 488B4424
|
|||
DEFINE mov_rbx,[rdi+BYTE] 488B5F
|
||||
DEFINE mov_rcx,[rdi+BYTE] 488B4F
|
||||
DEFINE mov_rcx,[rsp+BYTE] 488B4C24
|
||||
DEFINE mov_rsp,[rsp+BYTE] 488B6424
|
||||
DEFINE mov_r14,[rdx+BYTE] 4C8B72
|
||||
DEFINE mov_rcx,[rip+DWORD] 488B0D
|
||||
DEFINE mov_[rip+DWORD],rax 488905
|
||||
DEFINE mov_[rip+DWORD],rcx 48890D
|
||||
DEFINE mov_[rbx], C603
|
||||
DEFINE pop_rax 58
|
||||
DEFINE pop_rbp 5D
|
||||
DEFINE pop_rbx 5B
|
||||
DEFINE pop_rcx 59
|
||||
DEFINE pop_rdi 5F
|
||||
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_rbx 53
|
||||
DEFINE push_rbp 55
|
||||
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 sub_rbx, 4883EB
|
||||
|
@ -68,7 +86,17 @@ DEFINE xor_r9,r9 4D31C9
|
|||
|
||||
# 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_r12,rcx # save image_handle
|
||||
mov_r14,[rdx+BYTE] !96 # save system->boot
|
||||
|
||||
|
@ -89,11 +117,9 @@ DEFINE xor_r9,r9 4D31C9
|
|||
|
||||
# Get root directory
|
||||
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
|
||||
sub_rsp, !40 # allocate shadow stack space for UEFI function
|
||||
call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir)
|
||||
pop_rax # deallocate stack
|
||||
pop_rax # deallocate stack
|
||||
add_rsp, !40 # deallocate stack
|
||||
|
||||
# Push command line arguments onto stack
|
||||
mov_rbx,[rdi+BYTE] !56 # options = image->load_options
|
||||
|
@ -114,11 +140,15 @@ DEFINE xor_r9,r9 4D31C9
|
|||
:loop_options_done
|
||||
pop_r8 # get output file
|
||||
test_r8,r8 # if no output file
|
||||
je !exit_early # then exit
|
||||
je32 %exit_early # then exit
|
||||
|
||||
# Open file for writing
|
||||
push_rdx # allocate stack for fout
|
||||
mov_rdx,rsp # arg2 = &fout
|
||||
push_rsp # align stack to 16 bytes
|
||||
push_[rsp] # align stack to 16 bytes
|
||||
and_rsp, !-16 # align stack to 16 bytes
|
||||
push_rax # align stack
|
||||
push !0 # arg5 = 0
|
||||
push !7 # to get 0x8000000000000003 we set the rightmost 3 bits
|
||||
pop_r9 # and then do right rotation by 1
|
||||
|
@ -126,7 +156,7 @@ DEFINE xor_r9,r9 4D31C9
|
|||
mov_rcx,[rip+DWORD] %rootdir # arg1 = rootdir
|
||||
sub_rsp, !32 # allocate shadow stack space for UEFI function
|
||||
call_[rcx+BYTE] !8 # rootdir->open()
|
||||
add_rsp, !40 # deallocate stack
|
||||
mov_rsp,[rsp+BYTE] !56 # deallocate stack
|
||||
pop_r15 # get fout
|
||||
|
||||
mov_rdx, %0x100000 # Allocate 1MB
|
||||
|
@ -180,7 +210,16 @@ DEFINE xor_r9,r9 4D31C9
|
|||
mov_rcx,r12 # arg1 = image_handle
|
||||
call %close_protocol # close protocol
|
||||
|
||||
mov_rsp,rbp # restore stack pointer
|
||||
# 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
|
||||
|
||||
# r8: input file name
|
||||
|
@ -189,21 +228,28 @@ DEFINE xor_r9,r9 4D31C9
|
|||
# Open file for reading
|
||||
push_rdx # allocate stack for fin
|
||||
mov_rdx,rsp # arg2 = &fin
|
||||
push_rsp # align stack to 16 bytes
|
||||
push_[rsp] # align stack to 16 bytes
|
||||
and_rsp, !-16 # align stack to 16 bytes
|
||||
push_rax # align stack
|
||||
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_rcx,[rip+DWORD] %rootdir # arg1 = rootdir
|
||||
sub_rsp, !32 # allocate shadow stack space for UEFI function
|
||||
call_[rcx+BYTE] !8 # rootdir->open()
|
||||
add_rsp, !40 # deallocate stack
|
||||
mov_rsp,[rsp+BYTE] !56 # deallocate stack
|
||||
pop_rsi # get fin
|
||||
ret
|
||||
|
||||
# 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
|
||||
|
@ -213,22 +259,28 @@ DEFINE xor_r9,r9 4D31C9
|
|||
: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
|
||||
pop_rax # get image
|
||||
mov_rsp,[rsp+BYTE] !56 # deallocate stack
|
||||
pop_rax # get interface
|
||||
ret
|
||||
|
||||
# rcx: handle
|
||||
# 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
|
||||
|
@ -239,18 +291,24 @@ DEFINE xor_r9,r9 4D31C9
|
|||
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
|
||||
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
|
||||
|
||||
# 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
|
||||
call_[r14+BYTE] !72 # system->boot->free_pool(pool)
|
||||
pop_rax # deallocate stack
|
||||
mov_rsp,[rsp+BYTE] !40 # deallocate stack
|
||||
ret
|
||||
|
||||
# rdx: number of bytes to read
|
||||
|
@ -262,9 +320,12 @@ DEFINE xor_r9,r9 4D31C9
|
|||
push_rdx # set size
|
||||
mov_rdx,rsp # arg2 = &size
|
||||
mov_r8,rbx # arg3 = buffer
|
||||
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
|
||||
call_[rcx+BYTE] !32 # fin->read()
|
||||
add_rsp, !24 # deallocate stack
|
||||
mov_rsp,[rsp+BYTE] !40 # deallocate stack
|
||||
pop_rax # save size to rax
|
||||
ret
|
||||
|
||||
|
@ -277,9 +338,12 @@ DEFINE xor_r9,r9 4D31C9
|
|||
push_rdx # set size
|
||||
mov_rdx,rsp # arg2 = &size
|
||||
mov_r8,rbx # arg3 = buffer
|
||||
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
|
||||
call_[rcx+BYTE] !40 # fin->write()
|
||||
add_rsp, !24 # deallocate stack
|
||||
mov_rsp,[rsp+BYTE] !40 # deallocate stack
|
||||
pop_rax # save size to rax
|
||||
ret
|
||||
|
||||
|
@ -287,14 +351,14 @@ DEFINE xor_r9,r9 4D31C9
|
|||
# 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
|
||||
|
||||
:rootdir
|
||||
|
|
|
@ -9,7 +9,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 r12, rcx # save image_handle
|
||||
mov r14, [rdx+96] # save system->boot
|
||||
|
||||
|
@ -30,11 +40,9 @@ _start:
|
|||
|
||||
# Get root directory
|
||||
lea rdx, [rip+rootdir] # arg2 = &rootdir
|
||||
push rax # allocate shadow stack space for UEFI function
|
||||
push rax # 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)
|
||||
pop rax # deallocate stack
|
||||
pop rax # deallocate stack
|
||||
add rsp, 40 # deallocate stack
|
||||
|
||||
# Push command line arguments onto stack
|
||||
mov rbx, [rdi+56] # options = image->load_options
|
||||
|
@ -60,6 +68,10 @@ loop_options_done:
|
|||
# Open file for writing
|
||||
push rdx # allocate stack for fout
|
||||
mov rdx, rsp # arg2 = &fout
|
||||
push rsp # align stack to 16 bytes
|
||||
push [rsp] # align stack to 16 bytes
|
||||
and rsp, -16 # align stack to 16 bytes
|
||||
push rax # align stack
|
||||
push 0 # arg5 = 0
|
||||
push 7 # to get 0x8000000000000003 we set the rightmost 3 bits
|
||||
pop r9 # and then do right rotation by 1
|
||||
|
@ -67,7 +79,7 @@ loop_options_done:
|
|||
mov rcx, [rip+rootdir] # arg1 = rootdir
|
||||
sub rsp, 32 # allocate shadow stack space for UEFI function
|
||||
call [rcx+8] # rootdir->open()
|
||||
add rsp, 40 # deallocate stack
|
||||
mov rsp, [rsp+56] # deallocate stack
|
||||
pop r15 # get fout
|
||||
|
||||
mov rdx, 0x100000 # Allocate 1MiB
|
||||
|
@ -121,7 +133,16 @@ exit_early:
|
|||
mov rcx, r12 # arg1 = image_handle
|
||||
call close_protocol # close protocol
|
||||
|
||||
mov rsp, rbp # restore stack pointer
|
||||
# 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
|
||||
|
||||
# r8: input file name
|
||||
|
@ -130,21 +151,28 @@ open_file:
|
|||
# Open file for reading
|
||||
push rdx # allocate stack for fin
|
||||
mov rdx, rsp # arg2 = &fin
|
||||
push rsp # align stack to 16 bytes
|
||||
push [rsp] # align stack to 16 bytes
|
||||
and rsp, -16 # align stack to 16 bytes
|
||||
push rax # align stack
|
||||
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 rcx, [rip+rootdir] # arg1 = rootdir
|
||||
sub rsp, 32 # allocate shadow stack space for UEFI function
|
||||
call [rcx+8] # rootdir->open()
|
||||
add rsp, 40 # deallocate stack
|
||||
mov rsp, [rsp+56] # deallocate stack
|
||||
pop rsi # get fin
|
||||
ret
|
||||
|
||||
# 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
|
||||
|
@ -154,22 +182,28 @@ 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
|
||||
pop rax # get image
|
||||
mov rsp, [rsp+56] # deallocate stack
|
||||
pop rax # get interface
|
||||
ret
|
||||
|
||||
# rcx: handle
|
||||
# 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+288] # system->boot->close_protocol(handle, &guid, agent_handle, 0)
|
||||
add rsp, 32 # deallocate stack
|
||||
mov rsp, [rsp+40] # deallocate stack
|
||||
ret
|
||||
|
||||
|
||||
|
@ -181,18 +215,24 @@ allocate_pool:
|
|||
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
|
||||
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
|
||||
|
||||
# rdx: number of bytes to read
|
||||
|
@ -204,9 +244,12 @@ read:
|
|||
push rdx # set size
|
||||
mov rdx, rsp # arg2 = &size
|
||||
mov r8, rbx # arg3 = buffer
|
||||
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
|
||||
call [rcx+32] # fin->read()
|
||||
add rsp, 24 # deallocate stack
|
||||
mov rsp, [rsp+40] # deallocate stack
|
||||
pop rax # save size to rax
|
||||
ret
|
||||
|
||||
|
@ -219,9 +262,12 @@ write:
|
|||
push rdx # set size
|
||||
mov rdx, rsp # arg2 = &size
|
||||
mov r8, rbx # arg3 = buffer
|
||||
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
|
||||
call [rcx+40] # fin->write()
|
||||
add rsp, 24 # deallocate stack
|
||||
mov rsp, [rsp+40] # deallocate stack
|
||||
pop rax # save size to rax
|
||||
ret
|
||||
|
||||
|
|
|
@ -139,7 +139,17 @@
|
|||
|
||||
# efi_main(void *image_handle, struct efi_system_table *system)
|
||||
:_start
|
||||
# Save non-volatile registers
|
||||
55 ; push_rbp
|
||||
53 ; push_rbx
|
||||
57 ; push_rdi
|
||||
56 ; push_rsi
|
||||
4154 ; push_r12
|
||||
4155 ; push_r13
|
||||
4156 ; push_r14
|
||||
4157 ; push_r15
|
||||
4889E5 ; mov_rbp,rsp # save stack pointer
|
||||
|
||||
4989CC ; mov_r12,rcx # save image_handle
|
||||
4C8B72 60 ; mov_r14,[rdx+BYTE] !96 # save system->boot
|
||||
|
||||
|
@ -160,11 +170,9 @@
|
|||
|
||||
# Get root directory
|
||||
488D15 %rootdir ; lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir
|
||||
50 ; push_rax # allocate shadow stack space for UEFI function
|
||||
50 ; push_rax # allocate shadow stack space for UEFI function
|
||||
4883EC 28 ; sub_rsp, !40 # allocate shadow stack 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
|
||||
4883C4 28 ; add_rsp, !40 # deallocate stack
|
||||
|
||||
# Push command line arguments onto stack
|
||||
488B5F 38 ; mov_rbx,[rdi+BYTE] !56 # options = image->load_options
|
||||
|
@ -185,11 +193,15 @@
|
|||
:loop_options_done
|
||||
4158 ; pop_r8 # get output file
|
||||
4D85C0 ; test_r8,r8 # if no output file
|
||||
74 !exit_early ; je !exit_early # then exit
|
||||
0F84 %exit_early ; je32 %exit_early # then exit
|
||||
|
||||
# Open file for writing
|
||||
52 ; push_rdx # allocate stack for fout
|
||||
4889E2 ; mov_rdx,rsp # arg2 = &fout
|
||||
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
|
||||
50 ; push_rax # align stack
|
||||
6A 00 ; push !0 # arg5 = 0
|
||||
6A 07 ; push !7 # to get 0x8000000000000003 we set the rightmost 3 bits
|
||||
4159 ; pop_r9 # and then do right rotation by 1
|
||||
|
@ -197,7 +209,7 @@
|
|||
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()
|
||||
4883C4 28 ; add_rsp, !40 # deallocate stack
|
||||
488B6424 38 ; mov_rsp,[rsp+BYTE] !56 # deallocate stack
|
||||
415F ; pop_r15 # get fout
|
||||
|
||||
48C7C2 00001000 ; mov_rdx, %0x100000 # Allocate 1MB
|
||||
|
@ -251,7 +263,16 @@
|
|||
4C89E1 ; mov_rcx,r12 # arg1 = image_handle
|
||||
E8 %close_protocol ; call %close_protocol # close protocol
|
||||
|
||||
4889EC ; mov_rsp,rbp # restore stack
|
||||
# Restore non-volatile registers
|
||||
4889EC ; mov_rsp,rbp
|
||||
415F ; pop_r15
|
||||
415E ; pop_r14
|
||||
415D ; pop_r13
|
||||
415C ; pop_r12
|
||||
5E ; pop_rsi
|
||||
5F ; pop_rdi
|
||||
5B ; pop_rbx
|
||||
5D ; pop_rbp
|
||||
C3 ; ret # return to UEFI
|
||||
|
||||
# r8: input file name
|
||||
|
@ -260,21 +281,28 @@
|
|||
# Open file for reading
|
||||
52 ; push_rdx # allocate stack for fin
|
||||
4889E2 ; mov_rdx,rsp # arg2 = &fin
|
||||
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
|
||||
50 ; push_rax # align stack
|
||||
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
|
||||
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()
|
||||
4883C4 28 ; add_rsp, !40 # deallocate stack
|
||||
488B6424 38 ; mov_rsp,[rsp+BYTE] !56 # deallocate stack
|
||||
5E ; pop_rsi # get fin
|
||||
C3 ; ret
|
||||
|
||||
# rcx: file handle
|
||||
:close_file
|
||||
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 function
|
||||
FF51 10 ; call_[rcx+BYTE] !16 # file_handle->close(file_handle)
|
||||
58 ; pop_rax # deallocate stack
|
||||
488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack
|
||||
C3 ; ret
|
||||
|
||||
# rcx: handle
|
||||
|
@ -284,22 +312,28 @@
|
|||
: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
|
||||
58 ; pop_rax # get image
|
||||
488B6424 38 ; mov_rsp,[rsp+BYTE] !56 # deallocate stack
|
||||
58 ; pop_rax # get interface
|
||||
C3 ; ret
|
||||
|
||||
# rcx: handle
|
||||
# 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
|
||||
|
@ -310,18 +344,24 @@
|
|||
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 function
|
||||
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
|
||||
|
||||
# rcx: memory pool
|
||||
# r14: system->boot
|
||||
:free_pool
|
||||
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 function
|
||||
41FF56 48 ; call_[r14+BYTE] !72 # system->boot->free_pool(pool)
|
||||
58 ; pop_rax # deallocate stack
|
||||
488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack
|
||||
C3 ; ret
|
||||
|
||||
# rdx: number of bytes to read
|
||||
|
@ -333,9 +373,12 @@
|
|||
52 ; push_rdx # set size
|
||||
4889E2 ; mov_rdx,rsp # arg2 = &size
|
||||
4989D8 ; mov_r8,rbx # arg3 = buffer
|
||||
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 function
|
||||
FF51 20 ; call_[rcx+BYTE] !32 # fin->read()
|
||||
4883C4 18 ; add_rsp, !24 # deallocate stack
|
||||
488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack
|
||||
58 ; pop_rax # save size to rax
|
||||
C3 ; ret
|
||||
|
||||
|
@ -348,9 +391,12 @@
|
|||
52 ; push_rdx # set size
|
||||
4889E2 ; mov_rdx,rsp # arg2 = &size
|
||||
4989D8 ; mov_r8,rbx # arg3 = buffer
|
||||
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 function
|
||||
FF51 28 ; call_[rcx+BYTE] !40 # fin->write()
|
||||
4883C4 18 ; add_rsp, !24 # deallocate stack
|
||||
488B6424 28 ; mov_rsp,[rsp+BYTE] !40 # deallocate stack
|
||||
58 ; pop_rax # save size to rax
|
||||
C3 ; ret
|
||||
|
||||
|
@ -358,14 +404,14 @@
|
|||
# Protocol GUIDs
|
||||
:LOADED_IMAGE_PROTOCOL
|
||||
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
|
||||
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
|
||||
|
||||
:rootdir
|
||||
|
|
Loading…
Reference in New Issue