From 2b25915169ea1d725e07409a1190c89990ef1581 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Sat, 27 Aug 2022 23:52:38 +0100 Subject: [PATCH] hex2: implement various improvements. * Make sure to close all protocols before exit. * Use more sophisticated command line argument processinh that pushes command line arguments onto stack. * Switch to more readable M1 defines * Handle the case when output file is not specified --- amd64/Development/catm.M1 | 42 +- amd64/Development/catm.S | 2 +- amd64/Development/hex2.M1 | 1086 +++++++++++++++++++------------------ amd64/Development/hex2.S | 173 +++--- amd64/catm.hex2 | 4 +- amd64/hex2.hex1 | 869 ++++++++++++++--------------- 6 files changed, 1105 insertions(+), 1071 deletions(-) diff --git a/amd64/Development/catm.M1 b/amd64/Development/catm.M1 index d9d6c7e..fc98710 100644 --- a/amd64/Development/catm.M1 +++ b/amd64/Development/catm.M1 @@ -19,13 +19,13 @@ DEFINE jmp EB DEFINE jne 75 DEFINE lea_rdx,[rip+DWORD] 488D15 DEFINE mov_rdx, 48C7C2 -DEFINE mov_rax,rdi 4889C7 DEFINE mov_rbx,rax 4889C3 DEFINE mov_rcx,rax 4889C1 DEFINE mov_rcx,rbx 4889D9 DEFINE mov_rcx,r12 4C89E1 DEFINE mov_rcx,r13 4C89E9 DEFINE mov_rcx,r15 4C89F9 +DEFINE mov_rdi,rax 4889C7 DEFINE mov_rdx,rax 4889C2 DEFINE mov_rdx,rbx 4889DA DEFINE mov_rdx,rsp 4889E2 @@ -68,32 +68,32 @@ DEFINE xor_r9,r9 4D31C9 # efi_main(void *image_handle, struct efi_system_table *system) :_start - mov_rbp,rsp # save stack pointer - mov_r12,rcx # save image_handle - mov_r14,[rdx+BYTE] !96 # system->boot + mov_rbp,rsp # save stack pointer + mov_r12,rcx # save image_handle + mov_r14,[rdx+BYTE] !96 # save system->boot # Open Loaded Image protocol - mov_r9,r12 # arg4 = image_handle - lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL - mov_rcx,r12 # arg1 = image_handle - call %open_protocol # open protocol - mov_rax,rdi # save image + mov_r9,r12 # arg4 = image_handle + lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + mov_rcx,r12 # arg1 = image_handle + call %open_protocol # open protocol + mov_rdi,rax # save image # Get root file system - mov_r9,r12 # arg4 = image_handle - lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL - mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device - mov_[rip+DWORD],rcx %root_device # save root_device - call %open_protocol # open protocol - mov_rcx,rax # get rootfs + mov_r9,r12 # arg4 = image_handle + lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device + mov_[rip+DWORD],rcx %root_device # save root_device + call %open_protocol # open protocol + mov_rcx,rax # get rootfs # Get root directory - lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir - push_rax # allocate shadow stack space for UEFI function - push_rax # allocate shadow stack space for UEFI function - call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) - pop_rax # deallocate stack - pop_rax # deallocate stack + lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) + pop_rax # deallocate stack + pop_rax # deallocate stack # Push command line arguments onto stack mov_rbx,[rdi+BYTE] !56 # options = image->load_options diff --git a/amd64/Development/catm.S b/amd64/Development/catm.S index 19728bd..ef18803 100644 --- a/amd64/Development/catm.S +++ b/amd64/Development/catm.S @@ -11,7 +11,7 @@ _start: mov rbp, rsp # save stack pointer mov r12, rcx # save image_handle - mov r14, [rdx+96] # system->boot + mov r14, [rdx+96] # save system->boot # Open Loaded Image protocol mov r9, r12 # arg4 = image_handle diff --git a/amd64/Development/hex2.M1 b/amd64/Development/hex2.M1 index 6e9595d..a3eb89e 100644 --- a/amd64/Development/hex2.M1 +++ b/amd64/Development/hex2.M1 @@ -3,126 +3,124 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -DEFINE ADDI8_RBX 4883C3 -DEFINE ADDI8_RSP 4883C4 -DEFINE ADDI8_to_RDI 4883C7 -DEFINE ADDI8_to_RSI 4883C6 -DEFINE ADDI8_to_R12 4983C4 -DEFINE ADDI8_to_R13 4983C5 -DEFINE ADDI32_RAX 4805 -DEFINE ADDI32_RDX 4881C2 -DEFINE ADD_R14_to_RAX 4C01F0 -DEFINE CALLI32 E8 -DEFINE CALL_RCX_Immediate8 FF51 -DEFINE CALL_R14_Immediate8 41FF56 -DEFINE CALL_R14_Immediate32 41FF96 -DEFINE CMPI8_AL 3C -DEFINE CMP_AL_to_BL 38D8 -DEFINE CMP_RBX_RDX 4839D3 -DEFINE CMP_RAX_Immediate8 4883F8 -DEFINE CMP_RBX_Immediate8 4883FB -DEFINE CMP_RCX_Immediate8 4883F9 -DEFINE CMP_R15_Immediate8 4983FF -DEFINE COPY_RAX_to_RDX 4889C2 -DEFINE COPY_RAX_to_R11 4989C3 -DEFINE COPY_RAX_to_R12 4989C4 -DEFINE COPY_RAX_to_R14 4989C6 -DEFINE COPY_RBX_to_RCX 4889D9 -DEFINE COPY_RBX_to_RDX 4889DA -DEFINE COPY_RBX_to_R12 4989DC -DEFINE COPY_RBX_to_R13 4989DD -DEFINE COPY_RBP_to_RSP 4889EC -DEFINE COPY_RCX_to_RAX 4889C1 -DEFINE COPY_RCX_to_R15 4989CF -DEFINE COPY_RSP_to_RBP 4889E5 -DEFINE COPY_RSP_to_RDX 4889E2 -DEFINE COPY_RSP_to_R8 4989E0 -DEFINE COPY_R10_to_RCX 4C89D1 -DEFINE COPY_R11_to_RCX 4C89D9 -DEFINE COPY_R12_to_RAX 4C89E0 -DEFINE COPY_R12_to_RBX 4C89E3 -DEFINE COPY_R12_to_RCX 4C89E1 -DEFINE COPY_R12_to_R8 4D89E0 -DEFINE COPY_R13_to_R8 4D89E8 -DEFINE COPY_R13_to_RDX 4C89EA -DEFINE COPY_R15_to_RCX 4C89F9 -DEFINE COPY_R15_to_R9 4D89F9 -DEFINE JE32 0F84 -DEFINE JL32 0F8C -DEFINE JMP32 E9 -DEFINE JNE32 0F85 -DEFINE LOADI8_AL B0 -DEFINE LOADI32_RAX 48C7C0 -DEFINE LOADI32_RCX 48C7C1 -DEFINE LOADI32_RDX 48C7C2 -DEFINE LOADI32_R11 49C7C3 -DEFINE LOADI32_R13 49C7C5 -DEFINE LOADI32_R14 49C7C6 -DEFINE LOADI32_R15 49C7C7 -DEFINE LOAD8_AL_from_Address_RBX 8A03 -DEFINE LOAD8_AL_from_Address_RSI 8A06 -DEFINE LOAD8_BL_from_Address_RDI 8A1F -DEFINE LOAD32_into_RAX_from_Address_RCX_Immediate8 488B41 -DEFINE LOAD32_into_RSI_from_Address_RCX_Immediate8 488B71 -DEFINE LOAD32_into_RCX_from_Address_RBX 488B0B -DEFINE LOAD32_into_RCX_from_Address_RCX 488B09 -DEFINE LOAD64_into_RAX_from_Address_RSP_Immediate8 488B4424 -DEFINE LOAD64_into_RBX_from_Address_RAX_Immediate8 488B58 -DEFINE LOAD64_into_RCX_from_Address_RCX_Immediate8 488B49 -DEFINE LOAD64_into_RCX_from_Address_RSP_Immediate8 488B4C24 -DEFINE LOAD64_into_R10_from_Address_RSP_Immediate8 4C8B5424 -DEFINE LOAD64_into_R14_from_Address_RDX_Immediate8 4C8B72 -DEFINE LOAD64_rel_RAX 488B05 -DEFINE LOAD64_rel_RBX 488B1D -DEFINE LOAD64_rel_RCX 488B0D -DEFINE LOAD64_rel_RDX 488B15 -DEFINE LOAD64_rel_RDI 488B3D -DEFINE LOAD64_rel_R14 4C8B35 -DEFINE NOT_R15 49F7D7 -DEFINE POP_RAX 58 -DEFINE POP_RBX 5B -DEFINE POP_RCX 59 -DEFINE POP_RDX 5A -DEFINE POP_RSI 5E -DEFINE POP_R9 4159 -DEFINE POP_R10 415A -DEFINE POP_R11 415B -DEFINE PUSH 6A -DEFINE PUSH_RAX 50 -DEFINE PUSH_RBX 53 -DEFINE PUSH_RCX 51 -DEFINE PUSH_RDX 52 -DEFINE PUSH_RSI 56 -DEFINE PUSH_R10 4152 -DEFINE PUSH_R11 4153 -DEFINE RET C3 -DEFINE ROR_R9 49D1C9 -DEFINE SHL_R14_Immediate8 49C1E6 -DEFINE STOREI8_into_Address_RBX C603 -DEFINE STORE8_al_into_Address_RBX 8803 -DEFINE STORE32_RCX_into_Address_RBX 48890B -DEFINE STORE32_R11_into_Address_RAX 4C8918 -DEFINE STORE32_R12_into_Address_R11_Immediate8 4D8963 -DEFINE STORE32_R13_into_Address_RAX_Immediate8 4C8968 -DEFINE STORE64_rel_RAX 488905 -DEFINE STORE64_rel_RBX 48891D -DEFINE STORE64_rel_R14 4C8935 -DEFINE SUBI8_RAX 83E8 -DEFINE SUBI8_RSP 4883EC -DEFINE SUB_RDX_from_RAX 4829D0 -DEFINE TEST_ESI_ESI 85F6 -DEFINE XOR_EAX_EAX 31C0 -DEFINE XOR_EDX_EDX 31D2 -DEFINE XOR_ESI_ESI 31F6 -DEFINE ZERO_EXTEND_AL 480FB6C0 -DEFINE ZERO_EXTEND_BL 480FB6DB +DEFINE add_rax, 4805 +DEFINE add_rbx, 4883C3 +DEFINE add_rbx,[rdi+BYTE] 48035F +DEFINE add_rdi, 4883C7 +DEFINE add_rdx, 4881C2 +DEFINE add_rsi, 4883C6 +DEFINE add_rsp, 4883C4 +DEFINE add_r12, 4983C4 +DEFINE add_r13, 4983C5 +DEFINE add_rax,r14 4C01F0 +DEFINE call E8 +DEFINE call_[rcx+BYTE] FF51 +DEFINE call_[r14+BYTE] 41FF56 +DEFINE call_[r14+DWORD] 41FF96 +DEFINE cmp_al, 3C +DEFINE cmp_rax, 4883F8 +DEFINE cmp_rbx, 4883FB +DEFINE cmp_rcx, 4883F9 +DEFINE cmp_r8, 4983F8 +DEFINE cmp_r15, 4983FF +DEFINE cmp_al,bl 38D8 +DEFINE cmp_rbx,rdx 4839D3 +DEFINE je 0F84 +DEFINE jl 0F8C +DEFINE jmp E9 +DEFINE jne 0F85 +DEFINE lea_rdx,[rip+DWORD] 488D15 +DEFINE mov_al, B0 +DEFINE mov_rax, 48C7C0 +DEFINE mov_rcx, 48C7C1 +DEFINE mov_rdx, 48C7C2 +DEFINE mov_r11, 49C7C3 +DEFINE mov_r13, 49C7C5 +DEFINE mov_r14, 49C7C6 +DEFINE mov_r15, 49C7C7 +DEFINE mov_rax,r12 4C89E0 +DEFINE mov_rbp,rsp 4889E5 +DEFINE mov_rbx,r12 4C89E3 +DEFINE mov_rcx,rax 4889C1 +DEFINE mov_rcx,r9 4C89C9 +DEFINE mov_rcx,r8 4C89C1 +DEFINE mov_rcx,r11 4C89D9 +DEFINE mov_rdi,rax 4889C7 +DEFINE mov_rdx,rax 4889C2 +DEFINE mov_rdx,rbx 4889DA +DEFINE mov_rdx,rsb 4889E2 +DEFINE mov_rdx,rsp 4889E2 +DEFINE mov_rdx,r13 4C89EA +DEFINE mov_rsp,rbp 4889EC +DEFINE mov_rsp,r8 4989E0 +DEFINE mov_r8,rsp 4989E0 +DEFINE mov_r11,rax 4989C3 +DEFINE mov_r12,rax 4989C4 +DEFINE mov_r12,rbx 4989DC +DEFINE mov_r14,rax 4989C6 +DEFINE mov_al,[rbx] 8A03 +DEFINE mov_al,[rsi] 8A06 +DEFINE mov_bl,[rdi] 8A1F +DEFINE mov_rcx,[rbx] 488B0B +DEFINE mov_rcx,[rcx] 488B09 +DEFINE mov_rax,[rcx+BYTE] 488B41 +DEFINE mov_rbx,[rdi+BYTE] 488B5F +DEFINE mov_rcx,[rdi+BYTE] 488B4F +DEFINE mov_r14,[rdx+BYTE] 4C8B72 +DEFINE mov_rsi,[rcx+BYTE] 488B71 +DEFINE mov_rax,[rip+DWORD] 488B05 +DEFINE mov_rbx,[rip+DWORD] 488B1D +DEFINE mov_rcx,[rip+DWORD] 488B0D +DEFINE mov_rdi,[rip+DWORD] 488B3D +DEFINE mov_r14,[rip+DWORD] 4C8B35 +DEFINE mov_r8,[rip+DWORD] 4C8B05 +DEFINE mov_r9,[rip+DWORD] 4C8B0D +DEFINE mov_[rax+BYTE],r13 4C8968 +DEFINE mov_[r11+BYTE],r12 4D8963 +DEFINE mov_[rip+DWORD],rax 488905 +DEFINE mov_[rip+DWORD],rcx 48890D +DEFINE mov_[rip+DWORD],r14 4C8935 +DEFINE mov_[rax],r11 4C8918 +DEFINE mov_[rbx], C603 +DEFINE mov_[rbx],al 8803 +DEFINE mov_[rbx],rcx 48890B +DEFINE movzx_rax,al 480FB6C0 +DEFINE movzx_rbx,bl 480FB6DB +DEFINE not_r15 49F7D7 +DEFINE pop_rax 58 +DEFINE pop_rbx 5B +DEFINE pop_rcx 59 +DEFINE pop_rdx 5A +DEFINE pop_rsi 5E +DEFINE pop_r8 4158 +DEFINE pop_r9 4159 +DEFINE pop_r11 415B +DEFINE push 6A +DEFINE push_rax 50 +DEFINE push_rbx 53 +DEFINE push_rcx 51 +DEFINE push_rdx 52 +DEFINE push_rsi 56 +DEFINE push_r11 4153 +DEFINE ret C3 +DEFINE ror_r9 49D1C9 +DEFINE shl_r14, 49C1E6 +DEFINE sub_rax, 83E8 +DEFINE sub_rbx, 4883EB +DEFINE sub_rsp, 4883EC +DEFINE sub_rax,rdx 4829D0 +DEFINE test_esi_esi 85F6 +DEFINE xor_eax_eax 31C0 +DEFINE xor_edx_edx 31D2 +DEFINE xor_esi_esi 31F6 +DEFINE xor_r9,r9 4D31C9 # Register usage: - # R15 => Flag - # R14 => High bits - # R13 => IP - # R12 => MALLOC - # R11 => HEAD + # r15 => Flag + # r14 => High bits + # r13 => IP + # r12 => MALLOC + # r11 => HEAD # Struct format: (size 24) # NEXT => 0 @@ -131,638 +129,641 @@ DEFINE ZERO_EXTEND_BL 480FB6DB # efi_main(void *image_handle, struct efi_system_table *system) :_start - - COPY_RSP_to_RBP # save stack pointer - COPY_RCX_to_R15 # save image_handle - LOAD64_into_R14_from_Address_RDX_Immediate8 !96 # system->boot - STORE64_rel_R14 %SystemBoot # save system->boot + mov_rbp,rsp # save stack pointer + mov_[rip+DWORD],rcx %image_handle # save image_handle + mov_r14,[rdx+BYTE] !96 # system->boot + mov_[rip+DWORD],r14 %SystemBoot # save system->boot # Open Loaded Image protocol - PUSH_RAX # allocate stack for image - COPY_RSP_to_R8 # arg3 = &image - LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL_8 # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) - PUSH_RDX # push last 64 bits onto stack - LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) - PUSH_RDX # push first 64 bits onto stack - COPY_RSP_to_RDX # arg2 = &guid - PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - PUSH !0 # arg5 = NULL - COPY_R15_to_R9 # arg4 = image_handle - COPY_R15_to_RCX # arg1 = image_handle - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_R14_Immediate32 %280 # system->boot->open_protocol(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - LOAD64_into_RAX_from_Address_RSP_Immediate8 !64 # get_image - COPY_RCX_to_RAX # save image - - # Command line args - LOAD64_into_RBX_from_Address_RAX_Immediate8 !56 # options = image->load_options - -:loop_options1 # Skip application name - ADDI8_RBX !2 # ++options - LOAD8_AL_from_Address_RBX # *options - CMPI8_AL !0x20 # if *options != ' ' - JNE32 %loop_options1 # then jump - - ADDI8_RBX !2 # ++options - COPY_RBX_to_R12 # save input file - -:loop_options2 # Skip argv[1] - ADDI8_RBX !2 # ++options - LOAD8_AL_from_Address_RBX # *options - CMPI8_AL !0x20 # if *options != ' ' - JNE32 %loop_options2 # then jump - - STOREI8_into_Address_RBX !0 # *options = 0; - ADDI8_RBX !2 # ++options - COPY_RBX_to_R13 # save output file + mov_r9,[rip+DWORD] %image_handle # arg4 = image_handle + lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + mov_rcx,r9 # arg1 = image_handle + call %open_protocol # open protocol + mov_rdi,rax # save image # Get root file system - PUSH_RAX # allocate stack for rootfs - COPY_RSP_to_R8 # arg3 = &rootfs - LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL_8 # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (last 64 bits) - PUSH_RDX # push last 64 bits onto stack - LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (first 64 bits) - PUSH_RDX # push first 64 bits onto stack - COPY_RSP_to_RDX # arg2 = &guid - PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - PUSH !0 # arg5 = NULL - COPY_R15_to_R9 # arg4 = image_handle - LOAD64_into_RCX_from_Address_RCX_Immediate8 !24 # arg1 = root_device = image->device - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_R14_Immediate32 %280 # system->boot->open_protocol(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - LOAD64_into_RCX_from_Address_RSP_Immediate8 !64 # get rootfs + mov_r9,[rip+DWORD] %image_handle # arg4 = image_handle + lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device + mov_[rip+DWORD],rcx %root_device # save root_device + call %open_protocol # open protocol + mov_rcx,rax # get rootfs # Get root directory - PUSH_RDX # allocate stack for rootdir - COPY_RSP_to_RDX # arg2 = &rootdir - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # rootfs->open_volume(rootfs, &rootdir) - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RBX # get rootdir - STORE64_rel_RBX %rootdir # save rootdir + lea_rdx,[rip+DWORD] %rootdir # arg2 = &rootdir + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) + pop_rax # deallocate stack + pop_rax # deallocate stack + + # Push command line arguments onto stack + mov_rbx,[rdi+BYTE] !56 # options = image->load_options + mov_rdx,rbx # save beginning of load_options + add_rbx,[rdi+BYTE] !48 # go to the end of load_options + push !0 # Save end of arguments (NULL) onto stack +:loop_options + cmp_rbx,rdx # Check if we are done + je %loop_options_done # We are done + sub_rbx, !2 # --options + mov_al,[rbx] # *options + cmp_al, !0x20 # if *options != ' ' + jne %loop_options # then continue looping + mov_[rbx], !0 # zero it + add_rbx, !2 # ++options + push_rbx # push another argument onto stack + jmp %loop_options # next argument +:loop_options_done # Open file for reading - PUSH_RDX # allocate stack for fin - COPY_RSP_to_RDX # arg2 = &fin - PUSH !1 # arg5 = EFI_FILE_READ_ONLY - PUSH !1 # prepare to set arg4 to EFI_FILE_MODE_READ - POP_R9 # arg4 = EFI_FILE_MODE_READ - COPY_R12_to_R8 # arg3 = in - COPY_RBX_to_RCX # arg1 = rootdir - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # rootdir->open() - LOAD64_into_RAX_from_Address_RSP_Immediate8 !40 # get fin - STORE64_rel_RAX %fin # save fin + lea_rdx,[rip+DWORD] %fin # arg2 = &fin + pop_r8 # arg3 = in + 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 # Open file for writing - PUSH_RDX # allocate stack for fout - COPY_RSP_to_RDX # arg2 = &fout - PUSH !0 # arg5 = 0 - PUSH !7 # to get 0x8000000000000003 we set the rightmost 3 bits - POP_R9 # and then do right rotation by 1 - ROR_R9 # arg4 = EFI_FILE_MODE_CREATE| EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ - COPY_R13_to_R8 # arg3 = out - COPY_RBX_to_RCX # arg1 = rootdir - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # rootdir->open() - LOAD64_into_R10_from_Address_RSP_Immediate8 !40 # get fout + pop_r8 # arg3 = out + push !1 # Set exit code in case of failure + cmp_r8, !0 # If NULL + je %failed_output # then exit + lea_rdx,[rip+DWORD] %fout # arg2 = &fout + push !0 # arg5 = 0 + push !7 # to get 0x8000000000000003 we set the rightmost 3 bits + pop_r9 # and then do right rotation by 1 + ror_r9 # arg4 = EFI_FILE_MODE_CREATE| EFI_FILE_MODE_WRITE | 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 # Allocate ourselves 16 MiB of memory - LOADI32_RDX %0x1000000 # allocate 16 MiB of memory - CALLI32 %allocate_pool - STORE64_rel_RAX %scratch # Allocate space for scratch area - ADDI32_RAX %0x800 # 2 KiB of scratch - COPY_RAX_to_R12 # save structs pointer + mov_rdx, %0x1000000 # allocate 16 MiB of memory + call %allocate_pool + mov_[rip+DWORD],rax %scratch # Allocate space for scratch area + add_rax, %0x800 # 2 KiB of scratch + mov_r12,rax # save structs pointer - CALLI32 %ClearScratch # Zero scratch - LOADI32_R15 %-1 # Our flag for byte processing - LOADI32_R14 %0 # temp storage for the sum - LOADI32_R13 %0x00600000 # Our starting IP - LOADI32_R11 %0 # HEAD = NULL - CALLI32 %First_pass # Process it + call %ClearScratch # Zero scratch + mov_r15, %-1 # Our flag for byte processing + mov_r14, %0 # temp storage for the sum + mov_r13, %0x00600000 # Our starting IP + mov_r11, %0 # HEAD = NULL + call %First_pass # Process it # rewind input file - PUSH_R10 # Protect r10 - PUSH_R11 # Protect r11 - LOAD64_rel_RCX %fin # Using our input file - XOR_EDX_EDX # Offset Zero - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !56 # fin->set_position(fin, 0) - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_R11 # restore r11 - POP_R10 # restore r10 + push_r11 # Protect r11 + mov_rcx,[rip+DWORD] %fin # Using our input file + xor_edx_edx # Offset Zero + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !56 # fin->set_position(fin, 0) + pop_rax # deallocate stack + pop_rax # deallocate stack + pop_r11 # restore r11 - LOADI32_R15 %-1 # Our flag for byte processing - LOADI32_R14 %0 # temp storage for the sum - LOADI32_R13 %0x00600000 # Our starting IP - CALLI32 %Second_pass # Process it + mov_r15, %-1 # Our flag for byte processing + mov_r14, %0 # temp storage for the sum + mov_r13, %0x00600000 # Our starting IP + call %Second_pass # Process it - JMP32 %Done + jmp %Done :First_pass - CALLI32 %Read_byte + call %Read_byte # Deal with EOF - CMP_RAX_Immediate8 !-4 - JE32 %First_pass_done + cmp_rax, !-4 + je %First_pass_done # Check for : - CMP_RAX_Immediate8 !0x3A - JNE32 %First_pass_0 + cmp_rax, !0x3A + jne %First_pass_0 # Deal with label - CALLI32 %StoreLabel + call %StoreLabel :First_pass_0 # Check for ! - CMP_RAX_Immediate8 !0x21 - JE32 %First_pass_pointer + cmp_rax, !0x21 + je %First_pass_pointer # Check for @ - CMP_RAX_Immediate8 !0x40 - JE32 %First_pass_pointer + cmp_rax, !0x40 + je %First_pass_pointer # Check for $ - CMP_RAX_Immediate8 !0x24 - JE32 %First_pass_pointer + cmp_rax, !0x24 + je %First_pass_pointer # Check for % - CMP_RAX_Immediate8 !0x25 - JE32 %First_pass_pointer + cmp_rax, !0x25 + je %First_pass_pointer # Check for & - CMP_RAX_Immediate8 !0x26 - JE32 %First_pass_pointer + cmp_rax, !0x26 + je %First_pass_pointer # Deal with everything else - CALLI32 %hex # Process our char + call %hex # Process our char # Deal with EOF - CMP_RAX_Immediate8 !-4 - JE32 %First_pass_done + cmp_rax, !-4 + je %First_pass_done # deal with -1 values - CMP_RAX_Immediate8 !0 - JL32 %First_pass + cmp_rax, !0 + jl %First_pass # deal with toggle - CMP_R15_Immediate8 !0 - JE32 %First_pass_1 - ADDI8_to_R13 !1 # Increment IP + cmp_r15, !0 + je %First_pass_1 + add_r13, !1 # Increment IP :First_pass_1 - NOT_R15 - JMP32 %First_pass + not_r15 + jmp %First_pass :Update_Pointer # Check for ! - CMP_RAX_Immediate8 !0x21 - JE32 %Update_Pointer_1 + cmp_rax, !0x21 + je %Update_Pointer_1 # Check for @ - CMP_RAX_Immediate8 !0x40 - JE32 %Update_Pointer_2 + cmp_rax, !0x40 + je %Update_Pointer_2 # Check for $ - CMP_RAX_Immediate8 !0x24 - JE32 %Update_Pointer_2 + cmp_rax, !0x24 + je %Update_Pointer_2 # Check for % - CMP_RAX_Immediate8 !0x25 - JE32 %Update_Pointer_4 + cmp_rax, !0x25 + je %Update_Pointer_4 # Check for & - CMP_RAX_Immediate8 !0x26 - JE32 %Update_Pointer_4 + cmp_rax, !0x26 + je %Update_Pointer_4 # deal with bad input - CALLI32 %fail + call %fail :Update_Pointer_4 - ADDI8_to_R13 !2 # Increment IP + add_r13, !2 # Increment IP :Update_Pointer_2 - ADDI8_to_R13 !1 # Increment IP + add_r13, !1 # Increment IP :Update_Pointer_1 - ADDI8_to_R13 !1 # Increment IP - RET + add_r13, !1 # Increment IP + ret :First_pass_pointer # Deal with Pointer to label - CALLI32 %Update_Pointer # Increment IP - LOAD64_rel_RBX %scratch # Using scratch - CALLI32 %consume_token # Read token - CALLI32 %ClearScratch # Throw away token - CMP_RAX_Immediate8 !0x3E # check for '>' - JNE32 %First_pass # Loop again + call %Update_Pointer # Increment IP + mov_rbx,[rip+DWORD] %scratch # Using scratch + call %consume_token # Read token + call %ClearScratch # Throw away token + cmp_rax, !0x3E # check for '>' + jne %First_pass # Loop again # Deal with %label>label case - LOAD64_rel_RBX %scratch # Write to scratch - CALLI32 %consume_token # get token - CALLI32 %ClearScratch # Clean up after ourselves - JMP32 %First_pass # Loop again + mov_rbx,[rip+DWORD] %scratch # Write to scratch + call %consume_token # get token + call %ClearScratch # Clean up after ourselves + jmp %First_pass # Loop again :First_pass_done - RET + ret :hex # deal with EOF - CMP_RAX_Immediate8 !-4 - JE32 %EOF + cmp_rax, !-4 + je %EOF # deal with line comments starting with # - CMP_RAX_Immediate8 !0x23 - JE32 %ascii_comment + cmp_rax, !0x23 + je %ascii_comment # deal with line comments starting with ; - CMP_RAX_Immediate8 !0x3B - JE32 %ascii_comment + cmp_rax, !0x3B + je %ascii_comment # deal all ascii less than 0 - CMP_RAX_Immediate8 !0x30 - JL32 %ascii_other + cmp_rax, !0x30 + jl %ascii_other # deal with 0-9 - CMP_RAX_Immediate8 !0x3A - JL32 %ascii_num + cmp_rax, !0x3A + jl %ascii_num # deal with all ascii less than A - CMP_RAX_Immediate8 !0x41 - JL32 %ascii_other + cmp_rax, !0x41 + jl %ascii_other # deal with A-F - CMP_RAX_Immediate8 !0x47 - JL32 %ascii_high + cmp_rax, !0x47 + jl %ascii_high # deal with all ascii less than a - CMP_RAX_Immediate8 !0x61 - JL32 %ascii_other + cmp_rax, !0x61 + jl %ascii_other # deal with a-f - CMP_RAX_Immediate8 !0x67 - JL32 %ascii_low + cmp_rax, !0x67 + jl %ascii_low # The rest that remains needs to be ignored - JMP32 %ascii_other + jmp %ascii_other :Second_pass - CALLI32 %Read_byte + call %Read_byte # Deal with EOF - CMP_RAX_Immediate8 !-4 - JE32 %Second_pass_done + cmp_rax, !-4 + je %Second_pass_done # Simply drop the label - CMP_RAX_Immediate8 !0x3A - JNE32 %Second_pass_0 + cmp_rax, !0x3A + jne %Second_pass_0 - LOAD64_rel_RBX %scratch # Using scratch - CALLI32 %consume_token # Read token - CALLI32 %ClearScratch # Throw away token + mov_rbx,[rip+DWORD] %scratch # Using scratch + call %consume_token # Read token + call %ClearScratch # Throw away token - JMP32 %Second_pass + jmp %Second_pass :Second_pass_0 # Deal with % pointer - CMP_RAX_Immediate8 !0x25 - JE32 %StorePointer_rel4 + cmp_rax, !0x25 + je %StorePointer_rel4 # Deal with @ pointer - CMP_RAX_Immediate8 !0x40 - JE32 %StorePointer_rel2 + cmp_rax, !0x40 + je %StorePointer_rel2 # Deal with ! pointer - CMP_RAX_Immediate8 !0x21 - JE32 %StorePointer_rel1 + cmp_rax, !0x21 + je %StorePointer_rel1 # Deal with & pointer - CMP_RAX_Immediate8 !0x26 - JE32 %StorePointer_abs4 + cmp_rax, !0x26 + je %StorePointer_abs4 # Deal with $ pointer - CMP_RAX_Immediate8 !0x24 - JE32 %StorePointer_abs2 + cmp_rax, !0x24 + je %StorePointer_abs2 :Second_pass_1 # Deal with everything else - CALLI32 %hex # Process our char + call %hex # Process our char # Deal with EOF - CMP_RAX_Immediate8 !-4 - JE32 %Second_pass_done + cmp_rax, !-4 + je %Second_pass_done # deal with -1 values - CMP_RAX_Immediate8 !0 - JL32 %Second_pass + cmp_rax, !0 + jl %Second_pass # deal with toggle - CMP_R15_Immediate8 !0 - JE32 %print + cmp_r15, !0 + je %print # process first byte of pair - COPY_RAX_to_R14 - LOADI32_R15 %0 - JMP32 %Second_pass + mov_r14,rax + mov_r15, %0 + jmp %Second_pass :Second_pass_done :EOF - RET + ret :ascii_num - SUBI8_RAX !0x30 - RET + sub_rax, !0x30 + ret :ascii_low - SUBI8_RAX !0x57 - RET + sub_rax, !0x57 + ret :ascii_high - SUBI8_RAX !0x37 - RET + sub_rax, !0x37 + ret :ascii_other - LOADI32_RAX %-1 - RET + mov_rax, %-1 + ret :ascii_comment - CALLI32 %Read_byte - CMP_RAX_Immediate8 !0x0D - JE32 %ascii_comment_cr - CMP_RAX_Immediate8 !0x0A - JNE32 %ascii_comment + call %Read_byte + cmp_rax, !0x0D + je %ascii_comment_cr + cmp_rax, !0x0A + jne %ascii_comment :ascii_comment_cr - LOADI32_RAX %-1 - RET + mov_rax, %-1 + ret # process second byte of pair :print # update the sum and store in output - SHL_R14_Immediate8 !4 - ADD_R14_to_RAX + shl_r14, !4 + add_rax,r14 # flip the toggle - NOT_R15 # r15 = -1 + not_r15 # r15 = -1 # Print our first Hex - LOADI32_RDX %1 # set the size of chars we want - CALLI32 %print_chars + mov_rdx, %1 # set the size of chars we want + call %print_chars - ADDI8_to_R13 !1 # Increment IP - JMP32 %Second_pass + add_r13, !1 # Increment IP + jmp %Second_pass :Read_byte - PUSH_R10 # Protect r10 - PUSH_R11 # Protect r11 - LOAD64_rel_RCX %fin # arg1 = fin - PUSH !1 # size = 1 - COPY_RSP_to_RDX # arg2 = &size - XOR_ESI_ESI # zero rsi - PUSH_RSI # allocate stack - COPY_RSP_to_R8 # arg3 = &input - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !32 # fin->read() - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RAX # deallocate stack - POP_RAX # save input to rax - POP_RSI # save size to rsi - POP_R11 # restore r11 - POP_R10 # restore r10 + push_r11 # Protect r11 + mov_rcx,[rip+DWORD] %fin # arg1 = fin + push !1 # size = 1 + mov_rdx,rsb # arg2 = &size + xor_esi_esi # zero rsi + push_rsi # allocate stack + mov_rsp,r8 # arg3 = &input + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !32 # fin->read() + pop_rax # deallocate stack + pop_rax # deallocate stack + pop_rax # deallocate stack + pop_rax # save input to rax + pop_rsi # save size to rsi + pop_r11 # restore r11 # If the file ended (0 bytes read) return EOF - TEST_ESI_ESI - JNE32 %Read_byte_1 - LOADI32_RAX %-4 # Put EOF in rax + test_esi_esi + jne %Read_byte_1 + mov_rax, %-4 # Put EOF in rax :Read_byte_1 - RET + ret # Writes bytes stored in rax :print_chars - PUSH_R10 # Protect r10 - PUSH_R11 # Protect r11 - COPY_R10_to_RCX # arg1 = fout - PUSH_RDX # set size - COPY_RSP_to_RDX # arg2 = &size - PUSH_RAX # allocate stack - COPY_RSP_to_R8 # arg3 = &output - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !40 # fout->write() - ADDI8_RSP !40 # deallocate stack - POP_R11 # restore r11 - POP_R10 # restore r10 + push_r11 # Protect r11 + mov_rcx,[rip+DWORD] %fout # arg1 = fout + push_rdx # set size + mov_rdx,rsp # arg2 = &size + push_rax # allocate stack + mov_rsp,r8 # arg3 = &output + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !40 # fout->write() + add_rsp, !40 # deallocate stack + pop_r11 # restore r11 - RET # return + ret # return # Receives pointer in RBX # Writes out char and updates RBX :consume_token - CALLI32 %Read_byte # Consume_token + call %Read_byte # Consume_token # Check for \t - CMP_RAX_Immediate8 !0x09 - JE32 %consume_token_done + cmp_rax, !0x09 + je %consume_token_done # Check for \n - CMP_RAX_Immediate8 !0x0A - JE32 %consume_token_done + cmp_rax, !0x0A + je %consume_token_done # Check for ' ' - CMP_RAX_Immediate8 !0x20 - JE32 %consume_token_done + cmp_rax, !0x20 + je %consume_token_done # Check for '>' - CMP_RAX_Immediate8 !0x3E - JE32 %consume_token_done + cmp_rax, !0x3E + je %consume_token_done # Looks like we are still reading token - STORE8_al_into_Address_RBX # Store char - ADDI8_RBX !1 # Point to next spot - JMP32 %consume_token # loop until done + mov_[rbx],al # Store char + add_rbx, !1 # Point to next spot + jmp %consume_token # loop until done :consume_token_done - LOADI32_RCX %0 # Pad with nulls - STORE32_RCX_into_Address_RBX - ADDI8_RBX !8 - RET + mov_rcx, %0 # Pad with nulls + mov_[rbx],rcx + add_rbx, !8 + ret :StoreLabel - COPY_R12_to_RAX # ENTRY - ADDI8_to_R12 !24 # CALLOC - STORE32_R13_into_Address_RAX_Immediate8 !8 # ENTRY->TARGET = IP - STORE32_R11_into_Address_RAX # ENTRY->NEXT = JUMP_TABLE - COPY_RAX_to_R11 # JUMP_TABLE = ENTRY - STORE32_R12_into_Address_R11_Immediate8 !16 # ENTRY->NAME = TOKEN - COPY_R12_to_RBX # Write Starting after struct - CALLI32 %consume_token # Collect whole string - COPY_RBX_to_R12 # Update HEAP - JMP32 %First_pass + mov_rax,r12 # ENTRY + add_r12, !24 # CALLOC + mov_[rax+BYTE],r13 !8 # ENTRY->TARGET = IP + mov_[rax],r11 # ENTRY->NEXT = JUMP_TABLE + mov_r11,rax # JUMP_TABLE = ENTRY + mov_[r11+BYTE],r12 !16 # ENTRY->NAME = TOKEN + mov_rbx,r12 # Write Starting after struct + call %consume_token # Collect whole string + mov_r12,rbx # Update HEAP + jmp %First_pass :GetTarget - LOAD64_rel_RDI %scratch # Reset scratch - COPY_R11_to_RCX # Grab JUMP_TABLE - LOAD32_into_RSI_from_Address_RCX_Immediate8 !16 # I->NAME + mov_rdi,[rip+DWORD] %scratch # Reset scratch + mov_rcx,r11 # Grab JUMP_TABLE + mov_rsi,[rcx+BYTE] !16 # I->NAME :GetTarget_loop - LOAD8_AL_from_Address_RSI # I->NAME[0] - LOAD8_BL_from_Address_RDI # scratch[0] - ZERO_EXTEND_BL # Zero extend - ZERO_EXTEND_AL # Zero extend - CMP_AL_to_BL # IF TOKEN == I->NAME - JNE32 %GetTarget_miss # Oops + mov_al,[rsi] # I->NAME[0] + mov_bl,[rdi] # scratch[0] + movzx_rbx,bl # Zero extend + movzx_rax,al # Zero extend + cmp_al,bl # IF TOKEN == I->NAME + jne %GetTarget_miss # Oops - ADDI8_to_RSI !1 - ADDI8_to_RDI !1 - CMPI8_AL !0 - JNE32 %GetTarget_loop # Loop until - JMP32 %GetTarget_done # Match + add_rsi, !1 + add_rdi, !1 + cmp_al, !0 + jne %GetTarget_loop # Loop until + jmp %GetTarget_done # Match # Miss :GetTarget_miss - LOAD32_into_RCX_from_Address_RCX # I = I->NEXT - CMP_RCX_Immediate8 !0 # IF NULL == I - JE32 %fail # Abort hard + mov_rcx,[rcx] # I = I->NEXT + cmp_rcx, !0 # IF NULL == I + je %fail # Abort hard - LOAD32_into_RSI_from_Address_RCX_Immediate8 !16 # I->NAME - LOAD64_rel_RDI %scratch # Reset scratch - JMP32 %GetTarget_loop + mov_rsi,[rcx+BYTE] !16 # I->NAME + mov_rdi,[rip+DWORD] %scratch # Reset scratch + jmp %GetTarget_loop :GetTarget_done - LOAD32_into_RAX_from_Address_RCX_Immediate8 !8 # Get address - RET + mov_rax,[rcx+BYTE] !8 # Get address + ret :ClearScratch - PUSH_RAX # Protect against changes - PUSH_RBX # And overwrites - PUSH_RCX - PUSH_RDX # While we work - LOAD64_rel_RBX %scratch # Where our table is - LOADI8_AL !0 # Using null + push_rax # Protect against changes + push_rbx # And overwrites + push_rcx + push_rdx # While we work + mov_rbx,[rip+DWORD] %scratch # Where our table is + mov_al, !0 # Using null - COPY_RBX_to_RDX # Get scratch - ADDI32_RDX %0x800 # end of scratch area + mov_rdx,rbx # Get scratch + add_rdx, %0x800 # end of scratch area :ClearScratch_loop - CMP_RBX_RDX # Make sure - JE32 %ClearScratch_end # we do not overflow + cmp_rbx,rdx # Make sure + je %ClearScratch_end # we do not overflow - LOAD32_into_RCX_from_Address_RBX # Get current value - STORE8_al_into_Address_RBX # Because we want null - ADDI8_RBX !1 # Increment - CMP_RCX_Immediate8 !0 # Check if we hit null - JNE32 %ClearScratch_loop # Keep looping + mov_rcx,[rbx] # Get current value + mov_[rbx],al # Because we want null + add_rbx, !1 # Increment + cmp_rcx, !0 # Check if we hit null + jne %ClearScratch_loop # Keep looping :ClearScratch_end - POP_RDX - POP_RCX # Don't Forget to - POP_RBX # Restore Damage - POP_RAX # Entirely - RET + pop_rdx + pop_rcx # Don't Forget to + pop_rbx # Restore Damage + pop_rax # Entirely + ret :StorePointer - CALLI32 %Update_Pointer # Increment IP - LOAD64_rel_RBX %scratch # Write to scratch - CALLI32 %consume_token # get token - PUSH_RAX # Protect base_sep_p - LOAD64_rel_RAX %scratch # Pointer to scratch - CALLI32 %GetTarget # Get address of pointer - CALLI32 %ClearScratch # Clean up after ourselves - COPY_R13_to_RDX # base = IP - POP_RBX # Restore base_sep_p - CMP_RBX_Immediate8 !0x3E # If base_sep_p == '>' - JNE32 %StorePointer_done # If not + call %Update_Pointer # Increment IP + mov_rbx,[rip+DWORD] %scratch # Write to scratch + call %consume_token # get token + push_rax # Protect base_sep_p + mov_rax,[rip+DWORD] %scratch # Pointer to scratch + call %GetTarget # Get address of pointer + call %ClearScratch # Clean up after ourselves + mov_rdx,r13 # base = IP + pop_rbx # Restore base_sep_p + cmp_rbx, !0x3E # If base_sep_p == '>' + jne %StorePointer_done # If not # Deal with %label>label case - PUSH_RAX # We need to preserve main target - LOAD64_rel_RBX %scratch # Write to scratch - CALLI32 %consume_token # get token - LOAD64_rel_RAX %scratch # Pointer to scratch - CALLI32 %GetTarget # Get address of pointer - CALLI32 %ClearScratch # Clean up after ourselves - COPY_RAX_to_RDX # Use our new base - POP_RAX # Restore main target + push_rax # We need to preserve main target + mov_rbx,[rip+DWORD] %scratch # Write to scratch + call %consume_token # get token + mov_rax,[rip+DWORD] %scratch # Pointer to scratch + call %GetTarget # Get address of pointer + call %ClearScratch # Clean up after ourselves + mov_rdx,rax # Use our new base + pop_rax # Restore main target :StorePointer_done - RET + ret :StorePointer_rel4 - CALLI32 %StorePointer # Do Common - SUB_RDX_from_RAX # target - ip - LOADI32_RDX %4 # set the size of chars we want - CALLI32 %print_chars - JMP32 %Second_pass + call %StorePointer # Do Common + sub_rax,rdx # target - ip + mov_rdx, %4 # set the size of chars we want + call %print_chars + jmp %Second_pass :StorePointer_rel2 - CALLI32 %StorePointer # Do Common - SUB_RDX_from_RAX # target - ip - LOADI32_RDX %2 # set the size of chars we want - CALLI32 %print_chars - JMP32 %Second_pass + call %StorePointer # Do Common + sub_rax,rdx # target - ip + mov_rdx, %2 # set the size of chars we want + call %print_chars + jmp %Second_pass :StorePointer_rel1 - CALLI32 %StorePointer # Do Common - SUB_RDX_from_RAX # target - ip - LOADI32_RDX %1 # set the size of chars we want - CALLI32 %print_chars - JMP32 %Second_pass + call %StorePointer # Do Common + sub_rax,rdx # target - ip + mov_rdx, %1 # set the size of chars we want + call %print_chars + jmp %Second_pass :StorePointer_abs4 - CALLI32 %StorePointer # Do Common - LOADI32_RDX %4 # set the size of chars we want - CALLI32 %print_chars - JMP32 %Second_pass + call %StorePointer # Do Common + mov_rdx, %4 # set the size of chars we want + call %print_chars + jmp %Second_pass :StorePointer_abs2 - CALLI32 %StorePointer # Do Common - LOADI32_RDX %2 # set the size of chars we want - CALLI32 %print_chars - JMP32 %Second_pass + call %StorePointer # Do Common + mov_rdx, %2 # set the size of chars we want + call %print_chars + jmp %Second_pass :fail - LOADI32_RAX %1 # Set exit code 1 - JMP32 %terminate + mov_rax, %1 # Set exit code 1 + jmp %terminate :Done - XOR_EAX_EAX # Set exit code 0 + xor_eax_eax # Set exit code 0 :terminate - PUSH_RAX # save exit code - PUSH_R10 # protect fout + push_rax # save exit code - PUSH_RAX # allocate shadow stack space for UEFI function - LOAD64_rel_R14 %SystemBoot # get system->boot - LOAD64_rel_RCX %scratch # arg1 = scratch - CALL_R14_Immediate8 !72 # system->boot->free_pool(scratch) - POP_RAX # deallocate stack + mov_r14,[rip+DWORD] %SystemBoot # get system->boot + mov_rcx,[rip+DWORD] %scratch # arg1 = scratch + push_rax # allocate shadow stack space for UEFI function + call_[r14+BYTE] !72 # system->boot->free_pool(scratch) + pop_rax # deallocate stack - LOAD64_rel_RCX %fin # arg1 = fin - CALLI32 %close_file # close fin + mov_rcx,[rip+DWORD] %fout # get fout + call %close_file # close fout - POP_RCX # restore fout - CALLI32 %close_file # close fout +:failed_output + mov_rcx,[rip+DWORD] %fin # get fin + call %close_file # close fin - LOAD64_rel_RCX %rootdir # get rootdir - CALLI32 %close_file # close rootdir + mov_rcx,[rip+DWORD] %rootdir # get rootdir + call %close_file # close rootdir - POP_RAX # restore exit code + mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle + lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + mov_rcx,[rip+DWORD] %root_device # arg1 = root_device + call %close_protocol # close protocol - COPY_RBP_to_RSP # restore stack - RET # return to UEFI + mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle + lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + mov_rcx,r8 # arg1 = image_handle + call %close_protocol # close protocol + + pop_rax # restore exit code +:abort + mov_rsp,rbp # restore stack + ret # return to UEFI # rcx: file handle :close_file - PUSH_RAX # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !16 # file_handle->close(file_handle) - POP_RAX # deallocate stack - RET + push_rax # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !16 # file_handle->close(file_handle) + pop_rax # deallocate stack + ret + +# rcx: handle +# rdx: &guid +# r9: agent_handle +# returns interface +:open_protocol + push_rax # allocate stack for interface + mov_r8,rsp # arg3 = &interface + push !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + push !0 # arg5 = NULL + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[r14+DWORD] %280 # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + add_rsp, !48 # deallocate stack + pop_rax # get interface + ret + +# rcx: handle +# rdx: &guid +# r8: agent_handle +:close_protocol + xor_r9,r9 # arg4 = NULL + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[r14+DWORD] %288 # system->boot->close_protocol(handle, &guid, agent_handle, 0) + add_rsp, !32 # deallocate stack + ret # rdx: number of bytes to allocate # r14: system->boot # returns pointer in rax :allocate_pool - PUSH_RDX # allocate stack for pool pointer - COPY_RSP_to_R8 # arg3 = &pool - PUSH !2 - POP_RCX # arg1 = EFI_LOADER_DATA - SUBI8_RSP !24 # allocate shadow stack space for UEFI - CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) - ADDI8_RSP !24 # deallocate stack - POP_RAX # get pool - RET + push_rdx # allocate stack for pool pointer + mov_r8,rsp # arg3 = &pool + push !2 + pop_rcx # arg1 = EFI_LOADER_DATA + sub_rsp, !24 # allocate shadow stack space for UEFI + call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) + add_rsp, !24 # deallocate stack + pop_rax # get pool + ret # Protocol GUIDs @@ -783,13 +784,22 @@ DEFINE ZERO_EXTEND_BL 480FB6DB :fin %0 %0 -:scratch +:fout %0 %0 -:SystemBoot +:scratch %0 %0 :rootdir %0 %0 +:SystemBoot + %0 %0 + +:image_handle + %0 %0 + +:root_device + %0 %0 + :PE32_end diff --git a/amd64/Development/hex2.S b/amd64/Development/hex2.S index f13272d..a114a1a 100644 --- a/amd64/Development/hex2.S +++ b/amd64/Development/hex2.S @@ -21,101 +21,76 @@ # efi_main(void *image_handle, struct efi_system_table *system) _start: mov rbp, rsp # save stack pointer - mov r15, rcx # save image_handle + mov [rip+image_handle], rcx # save image_handle mov r14, [rdx+96] # system->boot mov [rip+SystemBoot], r14 # save system->boot # Open Loaded Image protocol - push rax # allocate stack for image - mov r8, rsp # arg3 = &image - mov rdx, [rip+LOADED_IMAGE_PROTOCOL+8] # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) - push rdx # push last 64 bits onto stack - mov rdx, [rip+LOADED_IMAGE_PROTOCOL] # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) - push rdx # push first 64 bits onto stack - mov rdx, rsp # arg2 = &guid - push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - push 0 # arg5 = NULL - mov r9, r15 # arg4 = image_handle - mov rcx, r15 # arg1 = image_handle - sub rsp, 32 # allocate shadow stack space for UEFI function - call [r14+280] # system->boot->open_protocol(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - mov rax, [rsp+64] # get image - mov rcx, rax # save image - - # Command line args - mov rbx, [rax+56] # options = image->load_options - -loop_options1: # Skip application name - add rbx, 2 # ++options - mov al, [rbx] # *options - cmp al, 0x20 # if *options != ' ' - jne loop_options1 # then jump - - add rbx, 2 # ++options - mov r12, rbx # save input file - -loop_options2: # Skip argv[1] - add rbx, 2 # ++options - mov al, [rbx] # *options - cmp al, 0x20 # if *options != ' ' - jne loop_options2 # then jump - - mov byte ptr [rbx], 0 # *options = 0 - add rbx, 2 # ++options - mov r13, rbx # save output file + mov r9, [rip+image_handle] # arg4 = image_handle + lea rdx, [rip+LOADED_IMAGE_PROTOCOL] # guid = &LOADED_IMAGE_PROTOCOL + mov rcx, r9 # arg1 = image_handle + call open_protocol # open protocol + mov rdi, rax # save image # Get root file system - push rax # allocate stack for rootfs - mov r8, rsp # arg3 = &rootfs - mov rdx, [rip+SIMPLE_FS_PROTOCOL+8] # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (last 64 bits) - push rdx # push last 64 bits onto stack - mov rdx, [rip+SIMPLE_FS_PROTOCOL] # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (first 64 bits) - push rdx # push first 64 bits onto stack - mov rdx, rsp # arg2 = &guid - push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - push 0 # arg5 = NULL - mov r9, r15 # arg4 = image_handle - mov rcx, [rcx+24] # arg1 = root_device = image->device - sub rsp, 32 # allocate shadow stack space for UEFI function - call [r14+280] # system->boot->open_protocol(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - mov rcx, [rsp+64] # get rootfs + mov r9, [rip+image_handle] # arg4 = image_handle + lea rdx, [rip+SIMPLE_FS_PROTOCOL] # guid = &SIMPLE_FS_PROTOCOL + mov rcx, [rdi+24] # arg1 = root_device = image->device + mov [rip+root_device], rdi # save root_device + call open_protocol # open protocol + mov rcx, rax # get rootfs # Get root directory - push rdx # allocate stack for rootdir - mov rdx, rsp # arg2 = &rootdir + lea rdx, [rip+rootdir] # arg2 = &rootdir push rax # allocate shadow stack space for UEFI function push rax # allocate shadow stack space for UEFI function call [rcx+8] # rootfs->open_volume(rootfs, &rootdir) pop rax # deallocate stack pop rax # deallocate stack - pop rbx # get rootdir - mov [rip+rootdir], rbx # save rootdir + + # Push command line arguments onto stack + mov rbx, [rdi+56] # options = image->load_options + mov rdx, rbx # save beginning of load_options + add rbx, [rdi+48] # go to the end of load_options + push 0 # Save end of arguments (NULL) onto stack +loop_options: + cmp rbx, rdx # Check if we are done + je loop_options_done # We are done + sub rbx, 2 # --options + mov al, [rbx] # *options + cmp al, 0x20 # if *options != ' ' + jne loop_options # then continue looping + mov BYTE PTR [rbx], 0 # zero it + add rbx, 2 # ++options + push rbx # push another argument onto stack + jmp loop_options # next argument +loop_options_done: # Open file for reading - push rdx # allocate stack for fin - mov rdx, rsp # arg2 = &fin + lea rdx, [rip+fin] # arg2 = &fin + pop r8 # arg3 = in push 1 # arg5 = EFI_FILE_READ_ONLY push 1 # prepare to set arg4 to EFI_FILE_MODE_READ pop r9 # arg4 = EFI_FILE_MODE_READ - mov r8, r12 # arg3 = in - mov rcx, rbx # arg1 = rootdir + mov rcx, [rip+rootdir] # arg1 = rootdir sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+8] # rootdir->open() - mov rax, [rsp+40] # get fin - mov [rip+fin], rax # save fin + add rsp, 40 # deallocate stack # Open file for writing - push rdx # allocate stack for fout - mov rdx, rsp # arg2 = &fout + pop r8 # arg3 = out + push 1 # Set exit code in case of failure + cmp r8, 0 # If NULL + je failed_output # then exit + lea rdx, [rip+fout] # arg2 = &fout push 0 # arg5 = 0 push 7 # to get 0x8000000000000003 we set the rightmost 3 bits pop r9 # and then do right rotation by 1 ror r9 # arg4 = EFI_FILE_MODE_CREATE| EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ - mov r8, r13 # arg3 = out - mov rcx, rbx # arg1 = rootdir + mov rcx, [rip+rootdir] # arg1 = rootdir sub rsp, 32 # allocate shadow stack space for UEFI function call [rcx+8] # rootdir->open() - mov r10, [rsp+40] # get fout + add rsp, 40 # deallocate stack # Allocate ourselves 16 MiB of memory mov rdx, 0x1000000 # allocate 16 MiB of memory @@ -132,7 +107,6 @@ loop_options2: # Skip argv[1] call First_pass # Process it # rewind input file - push r10 # Protect r10 push r11 # Protect r11 mov rcx, [rip+fin] # Using our input file xor edx, edx # Offset Zero @@ -142,7 +116,6 @@ loop_options2: # Skip argv[1] pop rax # deallocate stack pop rax # deallocate stack pop r11 # restore r11 - pop r10 # restore r10 mov r15, -1 # Our flag for byte processing mov r14, 0 # temp storage for the sum @@ -389,7 +362,6 @@ print: Read_byte: - push r10 # Protect r10 push r11 # Protect r11 mov rcx, [rip+fin] # arg1 = fin push 1 # size = 1 @@ -407,7 +379,6 @@ Read_byte: pop rax # save input to rax pop rsi # save size to rsi pop r11 # restore r11 - pop r10 # restore r10 # If the file ended (0 bytes read) return EOF test esi, esi # if size == 0 @@ -419,9 +390,8 @@ Read_byte_1: # Writes bytes stored in rax print_chars: - push r10 # Protect r10 push r11 # Protect r11 - mov rcx, r10 # arg1 = fout + mov rcx, [rip+fout] # arg1 = fout push rdx # set size mov rdx, rsp # arg2 = &size push rax # allocate stack @@ -432,7 +402,6 @@ print_chars: call [rcx+40] # fout->write() add rsp, 40 # deallocate stack pop r11 # restore r11 - pop r10 # restore r10 ret # return @@ -609,23 +578,33 @@ Done: terminate: # Free pool push rax # save exit code - push r10 # protect fout - push rax # allocate shadow stack space for UEFI function mov r14, [rip+SystemBoot] # get system->boot mov rcx, [rip+scratch] # arg1 = scratch + push rax # allocate shadow stack space for UEFI function call [r14+72] # system->boot->free_pool(scratch) pop rax # deallocate stack - mov rcx, [rip+fin] # arg1 = fin - call close_file # close fin - - pop rcx # restore fout + mov rcx, [rip+fout] # get fout call close_file # close fout +failed_output: + mov rcx, [rip+fin] # get fin + call close_file # close fin + mov rcx, [rip+rootdir] # get rootdir call close_file # close rootdir + mov r8, [rip+image_handle] # arg3 = image_handle + lea rdx, [rip+SIMPLE_FS_PROTOCOL] # guid = &SIMPLE_FS_PROTOCOL + mov rcx, [rip+root_device] # arg1 = root_device + call close_protocol # close protocol + + mov r8, [rip+image_handle] # arg3 = image_handle + lea rdx, [rip+LOADED_IMAGE_PROTOCOL] # guid = &LOADED_IMAGE_PROTOCOL + mov rcx, r8 # arg1 = image_handle + call close_protocol # close protocol + pop rax # restore exit code abort: # used for debugging only @@ -639,6 +618,31 @@ close_file: pop rax # deallocate stack ret +# rcx: handle +# rdx: &guid +# r9: agent_handle +# returns interface +open_protocol: + push rax # allocate stack for interface + mov r8, rsp # arg3 = &interface + push 1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + push 0 # arg5 = NULL + sub rsp, 32 # allocate shadow stack space for UEFI function + call [r14+280] # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + add rsp, 48 # deallocate stack + pop rax # get interface + ret + +# rcx: handle +# rdx: &guid +# r8: agent_handle +close_protocol: + xor r9, r9 # arg4 = NULL + sub rsp, 32 # allocate shadow stack space for UEFI function + call [r14+288] # system->boot->close_protocol(handle, &guid, agent_handle, 0) + add rsp, 32 # deallocate stack + ret + # rdx: number of bytes to allocate # r14: system->boot # returns pointer in rax @@ -671,6 +675,9 @@ SIMPLE_FS_PROTOCOL: fin: .long 0, 0 +fout: +.long 0, 0 + scratch: .long 0, 0 @@ -679,3 +686,9 @@ rootdir: SystemBoot: .long 0, 0 + +image_handle: +.long 0, 0 + +root_device: +.long 0, 0 diff --git a/amd64/catm.hex2 b/amd64/catm.hex2 index f5090b7..148ef70 100644 --- a/amd64/catm.hex2 +++ b/amd64/catm.hex2 @@ -138,14 +138,14 @@ F0 00 # SizeOfOptionalHeader :_start 4889E5 ; mov_rbp,rsp # save stack pointer 4989CC ; mov_r12,rcx # save image_handle - 4C8B72 60 ; mov_r14,[rdx+BYTE] !96 # system->boot + 4C8B72 60 ; mov_r14,[rdx+BYTE] !96 # save system->boot # Open Loaded Image protocol 4D89E1 ; mov_r9,r12 # arg4 = image_handle 488D15 %LOADED_IMAGE_PROTOCOL ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL 4C89E1 ; mov_rcx,r12 # arg1 = image_handle E8 %open_protocol ; call %open_protocol # open protocol - 4889C7 ; mov_rax,rdi # save image + 4889C7 ; mov_rdi,rax # save image # Get root file system 4D89E1 ; mov_r9,r12 # arg4 = image_handle diff --git a/amd64/hex2.hex1 b/amd64/hex2.hex1 index b930d2d..48c1efd 100644 --- a/amd64/hex2.hex1 +++ b/amd64/hex2.hex1 @@ -132,9 +132,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" -75 06 00 00 ; VirtualSize +C7 06 00 00 ; VirtualSize 00 10 00 00 ; VirtualAddress -75 06 00 00 ; SizeOfRawData +C7 06 00 00 ; SizeOfRawData 70 01 00 00 ; PointerToRawData 00 00 00 00 ; PointerToRelocations 00 00 00 00 ; PointerToLinenumbers @@ -148,664 +148,675 @@ F0 00 # SizeOfOptionalHeader # efi_main(void *image_handle, struct efi_system_table *system) #:_start - 4889E5 ; COPY_RSP_to_RBP # save stack pointer - 4989CF ; COPY_RCX_to_R15 # save image_handle - 4C8B72 60 ; LOAD64_into_R14_from_Address_RDX_Immediate8 !96 # system->boot - 4C8935 %1 ; STORE64_rel_R14 %SystemBoot # save system->boot + 4889E5 ; mov_rbp,rsp # save stack pointer + 48890D %5 ; mov_[rip+DWORD],rcx %image_handle # save image_handle + 4C8B72 60 ; mov_r14,[rdx+BYTE] !96 # system->boot + 4C8935 %4 ; mov_[rip+DWORD],r14 %SystemBoot # save system->boot # Open Loaded Image protocol - 50 ; PUSH_RAX # allocate stack for image - 4989E0 ; COPY_RSP_to_R8 # arg3 = &image - 488B15 %W ; LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL_8 # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) - 52 ; PUSH_RDX # push last 64 bits onto stack - 488B15 %V ; LOAD64_rel_RDX %LOADED_IMAGE_PROTOCOL # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) - 52 ; PUSH_RDX # push first 64 bits onto stack - 4889E2 ; COPY_RSP_to_RDX # arg2 = &guid - 6A 01 ; PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - 6A 00 ; PUSH !0 # arg5 = NULL - 4D89F9 ; COPY_R15_to_R9 # arg4 = image_handle - 4C89F9 ; COPY_R15_to_RCX # arg1 = image_handle - 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function - 41FF96 18010000 ; CALL_R14_Immediate32 %280 # system->boot->open_protocol(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - 488B4424 40 ; LOAD64_into_RAX_from_Address_RSP_Immediate8 !64 # get_image - 4889C1 ; COPY_RCX_to_RAX # save image - - # Command line args - 488B58 38 ; LOAD64_into_RBX_from_Address_RAX_Immediate8 !56 # options = image->load_options - -:a #:loop_options1 # Skip application name - 4883C3 02 ; ADDI8_RBX !2 # ++options - 8A03 ; LOAD8_AL_from_Address_RBX # *options - 3C 20 ; CMPI8_AL !0x20 # if *options != ' ' - 0F85 %a ; JNE32 %loop_options1 # then jump - - 4883C3 02 ; ADDI8_RBX !2 # ++options - 4989DC ; COPY_RBX_to_R12 # save input file - -:b #:loop_options2 # Skip argv[1] - 4883C3 02 ; ADDI8_RBX !2 # ++options - 8A03 ; LOAD8_AL_from_Address_RBX # *options - 3C 20 ; CMPI8_AL !0x20 # if *options != ' ' - 0F85 %b ; JNE32 %loop_options2 # then jump - - C603 00 ; STOREI8_into_Address_RBX !0 # *options = 0; - 4883C3 02 ; ADDI8_RBX !2 # ++options - 4989DD ; COPY_RBX_to_R13 # save output file + 4C8B0D %5 ; mov_r9,[rip+DWORD] %image_handle # arg4 = image_handle + 488D15 %Y ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4C89C9 ; mov_rcx,r9 # arg1 = image_handle + E8 %V ; call %open_protocol # open protocol + 4889C7 ; mov_rdi,rax # save image # Get root file system - 50 ; PUSH_RAX # allocate stack for rootfs - 4989E0 ; COPY_RSP_to_R8 # arg3 = &rootfs - 488B15 %Y ; LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL_8 # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (last 64 bits) - 52 ; PUSH_RDX # push last 64 bits onto stack - 488B15 %X ; LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (first 64 bits) - 52 ; PUSH_RDX # push first 64 bits onto stack - 4889E2 ; COPY_RSP_to_RDX # arg2 = &guid - 6A 01 ; PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - 6A 00 ; PUSH !0 # arg5 = NULL - 4D89F9 ; COPY_R15_to_R9 # arg4 = image_handle - 488B49 18 ; LOAD64_into_RCX_from_Address_RCX_Immediate8 !24 # arg1 = root_device = image->device - 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function - 41FF96 18010000 ; CALL_R14_Immediate32 %280 # system->boot->open_protocol(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) - 488B4C24 40 ; LOAD64_into_RCX_from_Address_RSP_Immediate8 !64 # get rootfs + 4C8B0D %5 ; mov_r9,[rip+DWORD] %image_handle # arg4 = image_handle + 488D15 %Z ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B4F 18 ; mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device + 48890D %6 ; mov_[rip+DWORD],rcx %root_device # save root_device + E8 %V ; call %open_protocol # open protocol + 4889C1 ; mov_rcx,rax # get rootfs # Get root directory - 52 ; PUSH_RDX # allocate stack for rootdir - 4889E2 ; COPY_RSP_to_RDX # arg2 = &rootdir - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - FF51 08 ; CALL_RCX_Immediate8 !8 # rootfs->open_volume(rootfs, &rootdir) - 58 ; POP_RAX # deallocate stack - 58 ; POP_RAX # deallocate stack - 5B ; POP_RBX # get rootdir - 48891D %2 ; STORE64_rel_RBX %rootdir # save rootdir + 488D15 %3 ; 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 + FF51 08 ; call_[rcx+BYTE] !8 # rootfs->open_volume(rootfs, &rootdir) + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # deallocate stack + + # Push command line arguments onto stack + 488B5F 38 ; mov_rbx,[rdi+BYTE] !56 # options = image->load_options + 4889DA ; mov_rdx,rbx # save beginning of load_options + 48035F 30 ; add_rbx,[rdi+BYTE] !48 # go to the end of load_options + 6A 00 ; push !0 # Save end of arguments (NULL) onto stack +:a #:loop_options + 4839D3 ; cmp_rbx,rdx # Check if we are done + 0F84 %b ; je %loop_options_done # We are done + 4883EB 02 ; sub_rbx, !2 # --options + 8A03 ; mov_al,[rbx] # *options + 3C 20 ; cmp_al, !0x20 # if *options != ' ' + 0F85 %a ; jne %loop_options # then continue looping + C603 00 ; mov_[rbx], !0 # zero it + 4883C3 02 ; add_rbx, !2 # ++options + 53 ; push_rbx # push another argument onto stack + E9 %a ; jmp %loop_options # next argument +:b #:loop_options_done # Open file for reading - 52 ; PUSH_RDX # allocate stack for fin - 4889E2 ; COPY_RSP_to_RDX # arg2 = &fin - 6A 01 ; PUSH !1 # arg5 = EFI_FILE_READ_ONLY - 6A 01 ; PUSH !1 # prepare to set arg4 to EFI_FILE_MODE_READ - 4159 ; POP_R9 # arg4 = EFI_FILE_MODE_READ - 4D89E0 ; COPY_R12_to_R8 # arg3 = in - 4889D9 ; COPY_RBX_to_RCX # arg1 = rootdir - 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function - FF51 08 ; CALL_RCX_Immediate8 !8 # rootdir->open() - 488B4424 28 ; LOAD64_into_RAX_from_Address_RSP_Immediate8 !40 # get fin - 488905 %Z ; STORE64_rel_RAX %fin # save fin + 488D15 %0 ; lea_rdx,[rip+DWORD] %fin # arg2 = &fin + 4158 ; pop_r8 # arg3 = in + 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 %3 ; 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 # Open file for writing - 52 ; PUSH_RDX # allocate stack for fout - 4889E2 ; COPY_RSP_to_RDX # arg2 = &fout - 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 - 49D1C9 ; ROR_R9 # arg4 = EFI_FILE_MODE_CREATE| EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ - 4D89E8 ; COPY_R13_to_R8 # arg3 = out - 4889D9 ; COPY_RBX_to_RCX # arg1 = rootdir - 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function - FF51 08 ; CALL_RCX_Immediate8 !8 # rootdir->open() - 4C8B5424 28 ; LOAD64_into_R10_from_Address_RSP_Immediate8 !40 # get fout + 4158 ; pop_r8 # arg3 = out + 6A 01 ; push !1 # Set exit code in case of failure + 4983F8 00 ; cmp_r8, !0 # If NULL + 0F84 %7 ; je %failed_output # then exit + 488D15 %1 ; lea_rdx,[rip+DWORD] %fout # arg2 = &fout + 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 + 49D1C9 ; ror_r9 # arg4 = EFI_FILE_MODE_CREATE| EFI_FILE_MODE_WRITE | EFI_FILE_MODE_READ + 488B0D %3 ; 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 # Allocate ourselves 16 MiB of memory - 48C7C2 00000001 ; LOADI32_RDX %0x1000000 # allocate 16 MiB of memory - E8 %U ; CALLI32 %allocate_pool - 488905 %0 ; STORE64_rel_RAX %scratch # Allocate space for scratch area - 4805 00080000 ; ADDI32_RAX %0x800 # 2 KiB of scratch - 4989C4 ; COPY_RAX_to_R12 # save structs pointer + 48C7C2 00000001 ; mov_rdx, %0x1000000 # allocate 16 MiB of memory + E8 %X ; call %allocate_pool + 488905 %2 ; mov_[rip+DWORD],rax %scratch # Allocate space for scratch area + 4805 00080000 ; add_rax, %0x800 # 2 KiB of scratch + 4989C4 ; mov_r12,rax # save structs pointer - E8 %H ; CALLI32 %ClearScratch # Zero scratch - 49C7C7 FFFFFFFF ; LOADI32_R15 %-1 # Our flag for byte processing - 49C7C6 00000000 ; LOADI32_R14 %0 # temp storage for the sum - 49C7C5 00006000 ; LOADI32_R13 %0x00600000 # Our starting IP - 49C7C3 00000000 ; LOADI32_R11 %0 # HEAD = NULL - E8 %c ; CALLI32 %First_pass # Process it + E8 %H ; call %ClearScratch # Zero scratch + 49C7C7 FFFFFFFF ; mov_r15, %-1 # Our flag for byte processing + 49C7C6 00000000 ; mov_r14, %0 # temp storage for the sum + 49C7C5 00006000 ; mov_r13, %0x00600000 # Our starting IP + 49C7C3 00000000 ; mov_r11, %0 # HEAD = NULL + E8 %c ; call %First_pass # Process it # rewind input file - 4152 ; PUSH_R10 # Protect r10 - 4153 ; PUSH_R11 # Protect r11 - 488B0D %Z ; LOAD64_rel_RCX %fin # Using our input file - 31D2 ; XOR_EDX_EDX # Offset Zero - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - FF51 38 ; CALL_RCX_Immediate8 !56 # fin->set_position(fin, 0) - 58 ; POP_RAX # deallocate stack - 58 ; POP_RAX # deallocate stack - 415B ; POP_R11 # restore r11 - 415A ; POP_R10 # restore r10 + 4153 ; push_r11 # Protect r11 + 488B0D %0 ; mov_rcx,[rip+DWORD] %fin # Using our input file + 31D2 ; xor_edx_edx # Offset Zero + 50 ; push_rax # allocate shadow stack space for UEFI function + 50 ; push_rax # allocate shadow stack space for UEFI function + FF51 38 ; call_[rcx+BYTE] !56 # fin->set_position(fin, 0) + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # deallocate stack + 415B ; pop_r11 # restore r11 - 49C7C7 FFFFFFFF ; LOADI32_R15 %-1 # Our flag for byte processing - 49C7C6 00000000 ; LOADI32_R14 %0 # temp storage for the sum - 49C7C5 00006000 ; LOADI32_R13 %0x00600000 # Our starting IP - E8 %m ; CALLI32 %Second_pass # Process it + 49C7C7 FFFFFFFF ; mov_r15, %-1 # Our flag for byte processing + 49C7C6 00000000 ; mov_r14, %0 # temp storage for the sum + 49C7C5 00006000 ; mov_r13, %0x00600000 # Our starting IP + E8 %m ; call %Second_pass # Process it - E9 %S ; JMP32 %Done + E9 %S ; jmp %Done :c #:First_pass - E8 %x ; CALLI32 %Read_byte + E8 %x ; call %Read_byte # Deal with EOF - 4883F8 FC ; CMP_RAX_Immediate8 !-4 - 0F84 %k ; JE32 %First_pass_done + 4883F8 FC ; cmp_rax, !-4 + 0F84 %k ; je %First_pass_done # Check for : - 4883F8 3A ; CMP_RAX_Immediate8 !0x3A - 0F85 %d ; JNE32 %First_pass_0 + 4883F8 3A ; cmp_rax, !0x3A + 0F85 %d ; jne %First_pass_0 # Deal with label - E8 %C ; CALLI32 %StoreLabel + E8 %C ; call %StoreLabel :d #:First_pass_0 # Check for ! - 4883F8 21 ; CMP_RAX_Immediate8 !0x21 - 0F84 %j ; JE32 %First_pass_pointer + 4883F8 21 ; cmp_rax, !0x21 + 0F84 %j ; je %First_pass_pointer # Check for @ - 4883F8 40 ; CMP_RAX_Immediate8 !0x40 - 0F84 %j ; JE32 %First_pass_pointer + 4883F8 40 ; cmp_rax, !0x40 + 0F84 %j ; je %First_pass_pointer # Check for $ - 4883F8 24 ; CMP_RAX_Immediate8 !0x24 - 0F84 %j ; JE32 %First_pass_pointer + 4883F8 24 ; cmp_rax, !0x24 + 0F84 %j ; je %First_pass_pointer # Check for % - 4883F8 25 ; CMP_RAX_Immediate8 !0x25 - 0F84 %j ; JE32 %First_pass_pointer + 4883F8 25 ; cmp_rax, !0x25 + 0F84 %j ; je %First_pass_pointer # Check for & - 4883F8 26 ; CMP_RAX_Immediate8 !0x26 - 0F84 %j ; JE32 %First_pass_pointer + 4883F8 26 ; cmp_rax, !0x26 + 0F84 %j ; je %First_pass_pointer # Deal with everything else - E8 %l ; CALLI32 %hex # Process our char + E8 %l ; call %hex # Process our char # Deal with EOF - 4883F8 FC ; CMP_RAX_Immediate8 !-4 - 0F84 %k ; JE32 %First_pass_done + 4883F8 FC ; cmp_rax, !-4 + 0F84 %k ; je %First_pass_done # deal with -1 values - 4883F8 00 ; CMP_RAX_Immediate8 !0 - 0F8C %c ; JL32 %First_pass + 4883F8 00 ; cmp_rax, !0 + 0F8C %c ; jl %First_pass # deal with toggle - 4983FF 00 ; CMP_R15_Immediate8 !0 - 0F84 %e ; JE32 %First_pass_1 - 4983C5 01 ; ADDI8_to_R13 !1 # Increment IP + 4983FF 00 ; cmp_r15, !0 + 0F84 %e ; je %First_pass_1 + 4983C5 01 ; add_r13, !1 # Increment IP :e #:First_pass_1 - 49F7D7 ; NOT_R15 - E9 %c ; JMP32 %First_pass + 49F7D7 ; not_r15 + E9 %c ; jmp %First_pass :f #:Update_Pointer # Check for ! - 4883F8 21 ; CMP_RAX_Immediate8 !0x21 - 0F84 %i ; JE32 %Update_Pointer_1 + 4883F8 21 ; cmp_rax, !0x21 + 0F84 %i ; je %Update_Pointer_1 # Check for @ - 4883F8 40 ; CMP_RAX_Immediate8 !0x40 - 0F84 %h ; JE32 %Update_Pointer_2 + 4883F8 40 ; cmp_rax, !0x40 + 0F84 %h ; je %Update_Pointer_2 # Check for $ - 4883F8 24 ; CMP_RAX_Immediate8 !0x24 - 0F84 %h ; JE32 %Update_Pointer_2 + 4883F8 24 ; cmp_rax, !0x24 + 0F84 %h ; je %Update_Pointer_2 # Check for % - 4883F8 25 ; CMP_RAX_Immediate8 !0x25 - 0F84 %g ; JE32 %Update_Pointer_4 + 4883F8 25 ; cmp_rax, !0x25 + 0F84 %g ; je %Update_Pointer_4 # Check for & - 4883F8 26 ; CMP_RAX_Immediate8 !0x26 - 0F84 %g ; JE32 %Update_Pointer_4 + 4883F8 26 ; cmp_rax, !0x26 + 0F84 %g ; je %Update_Pointer_4 # deal with bad input - E8 %R ; CALLI32 %fail + E8 %R ; call %fail :g #:Update_Pointer_4 - 4983C5 02 ; ADDI8_to_R13 !2 # Increment IP + 4983C5 02 ; add_r13, !2 # Increment IP :h #:Update_Pointer_2 - 4983C5 01 ; ADDI8_to_R13 !1 # Increment IP + 4983C5 01 ; add_r13, !1 # Increment IP :i #:Update_Pointer_1 - 4983C5 01 ; ADDI8_to_R13 !1 # Increment IP - C3 ; RET + 4983C5 01 ; add_r13, !1 # Increment IP + C3 ; ret :j #:First_pass_pointer # Deal with Pointer to label - E8 %f ; CALLI32 %Update_Pointer # Increment IP - 488B1D %0 ; LOAD64_rel_RBX %scratch # Using scratch - E8 %A ; CALLI32 %consume_token # Read token - E8 %H ; CALLI32 %ClearScratch # Throw away token - 4883F8 3E ; CMP_RAX_Immediate8 !0x3E # check for '>' - 0F85 %c ; JNE32 %First_pass # Loop again + E8 %f ; call %Update_Pointer # Increment IP + 488B1D %2 ; mov_rbx,[rip+DWORD] %scratch # Using scratch + E8 %A ; call %consume_token # Read token + E8 %H ; call %ClearScratch # Throw away token + 4883F8 3E ; cmp_rax, !0x3E # check for '>' + 0F85 %c ; jne %First_pass # Loop again # Deal with %label>label case - 488B1D %0 ; LOAD64_rel_RBX %scratch # Write to scratch - E8 %A ; CALLI32 %consume_token # get token - E8 %H ; CALLI32 %ClearScratch # Clean up after ourselves - E9 %c ; JMP32 %First_pass # Loop again + 488B1D %2 ; mov_rbx,[rip+DWORD] %scratch # Write to scratch + E8 %A ; call %consume_token # get token + E8 %H ; call %ClearScratch # Clean up after ourselves + E9 %c ; jmp %First_pass # Loop again :k #:First_pass_done - C3 ; RET + C3 ; ret :l #:hex # deal with EOF - 4883F8 FC ; CMP_RAX_Immediate8 !-4 - 0F84 %p ; JE32 %EOF + 4883F8 FC ; cmp_rax, !-4 + 0F84 %p ; je %EOF # deal with line comments starting with # - 4883F8 23 ; CMP_RAX_Immediate8 !0x23 - 0F84 %u ; JE32 %ascii_comment + 4883F8 23 ; cmp_rax, !0x23 + 0F84 %u ; je %ascii_comment # deal with line comments starting with ; - 4883F8 3B ; CMP_RAX_Immediate8 !0x3B - 0F84 %u ; JE32 %ascii_comment + 4883F8 3B ; cmp_rax, !0x3B + 0F84 %u ; je %ascii_comment # deal all ascii less than 0 - 4883F8 30 ; CMP_RAX_Immediate8 !0x30 - 0F8C %t ; JL32 %ascii_other + 4883F8 30 ; cmp_rax, !0x30 + 0F8C %t ; jl %ascii_other # deal with 0-9 - 4883F8 3A ; CMP_RAX_Immediate8 !0x3A - 0F8C %q ; JL32 %ascii_num + 4883F8 3A ; cmp_rax, !0x3A + 0F8C %q ; jl %ascii_num # deal with all ascii less than A - 4883F8 41 ; CMP_RAX_Immediate8 !0x41 - 0F8C %t ; JL32 %ascii_other + 4883F8 41 ; cmp_rax, !0x41 + 0F8C %t ; jl %ascii_other # deal with A-F - 4883F8 47 ; CMP_RAX_Immediate8 !0x47 - 0F8C %s ; JL32 %ascii_high + 4883F8 47 ; cmp_rax, !0x47 + 0F8C %s ; jl %ascii_high # deal with all ascii less than a - 4883F8 61 ; CMP_RAX_Immediate8 !0x61 - 0F8C %t ; JL32 %ascii_other + 4883F8 61 ; cmp_rax, !0x61 + 0F8C %t ; jl %ascii_other # deal with a-f - 4883F8 67 ; CMP_RAX_Immediate8 !0x67 - 0F8C %r ; JL32 %ascii_low + 4883F8 67 ; cmp_rax, !0x67 + 0F8C %r ; jl %ascii_low # The rest that remains needs to be ignored - E9 %t ; JMP32 %ascii_other + E9 %t ; jmp %ascii_other :m #:Second_pass - E8 %x ; CALLI32 %Read_byte + E8 %x ; call %Read_byte # Deal with EOF - 4883F8 FC ; CMP_RAX_Immediate8 !-4 - 0F84 %p ; JE32 %Second_pass_done + 4883F8 FC ; cmp_rax, !-4 + 0F84 %p ; je %Second_pass_done # Simply drop the label - 4883F8 3A ; CMP_RAX_Immediate8 !0x3A - 0F85 %n ; JNE32 %Second_pass_0 + 4883F8 3A ; cmp_rax, !0x3A + 0F85 %n ; jne %Second_pass_0 - 488B1D %0 ; LOAD64_rel_RBX %scratch # Using scratch - E8 %A ; CALLI32 %consume_token # Read token - E8 %H ; CALLI32 %ClearScratch # Throw away token + 488B1D %2 ; mov_rbx,[rip+DWORD] %scratch # Using scratch + E8 %A ; call %consume_token # Read token + E8 %H ; call %ClearScratch # Throw away token - E9 %m ; JMP32 %Second_pass + E9 %m ; jmp %Second_pass :n #:Second_pass_0 # Deal with % pointer - 4883F8 25 ; CMP_RAX_Immediate8 !0x25 - 0F84 %M ; JE32 %StorePointer_rel4 + 4883F8 25 ; cmp_rax, !0x25 + 0F84 %M ; je %StorePointer_rel4 # Deal with @ pointer - 4883F8 40 ; CMP_RAX_Immediate8 !0x40 - 0F84 %N ; JE32 %StorePointer_rel2 + 4883F8 40 ; cmp_rax, !0x40 + 0F84 %N ; je %StorePointer_rel2 # Deal with ! pointer - 4883F8 21 ; CMP_RAX_Immediate8 !0x21 - 0F84 %O ; JE32 %StorePointer_rel1 + 4883F8 21 ; cmp_rax, !0x21 + 0F84 %O ; je %StorePointer_rel1 # Deal with & pointer - 4883F8 26 ; CMP_RAX_Immediate8 !0x26 - 0F84 %P ; JE32 %StorePointer_abs4 + 4883F8 26 ; cmp_rax, !0x26 + 0F84 %P ; je %StorePointer_abs4 # Deal with $ pointer - 4883F8 24 ; CMP_RAX_Immediate8 !0x24 - 0F84 %Q ; JE32 %StorePointer_abs2 + 4883F8 24 ; cmp_rax, !0x24 + 0F84 %Q ; je %StorePointer_abs2 :o #:Second_pass_1 # Deal with everything else - E8 %l ; CALLI32 %hex # Process our char + E8 %l ; call %hex # Process our char # Deal with EOF - 4883F8 FC ; CMP_RAX_Immediate8 !-4 - 0F84 %p ; JE32 %Second_pass_done + 4883F8 FC ; cmp_rax, !-4 + 0F84 %p ; je %Second_pass_done # deal with -1 values - 4883F8 00 ; CMP_RAX_Immediate8 !0 - 0F8C %m ; JL32 %Second_pass + 4883F8 00 ; cmp_rax, !0 + 0F8C %m ; jl %Second_pass # deal with toggle - 4983FF 00 ; CMP_R15_Immediate8 !0 - 0F84 %w ; JE32 %print + 4983FF 00 ; cmp_r15, !0 + 0F84 %w ; je %print # process first byte of pair - 4989C6 ; COPY_RAX_to_R14 - 49C7C7 00000000 ; LOADI32_R15 %0 - E9 %m ; JMP32 %Second_pass + 4989C6 ; mov_r14,rax + 49C7C7 00000000 ; mov_r15, %0 + E9 %m ; jmp %Second_pass :p #:Second_pass_done #:EOF - C3 ; RET + C3 ; ret :q #:ascii_num - 83E8 30 ; SUBI8_RAX !0x30 - C3 ; RET + 83E8 30 ; sub_rax, !0x30 + C3 ; ret :r #:ascii_low - 83E8 57 ; SUBI8_RAX !0x57 - C3 ; RET + 83E8 57 ; sub_rax, !0x57 + C3 ; ret :s #:ascii_high - 83E8 37 ; SUBI8_RAX !0x37 - C3 ; RET + 83E8 37 ; sub_rax, !0x37 + C3 ; ret :t #:ascii_other - 48C7C0 FFFFFFFF ; LOADI32_RAX %-1 - C3 ; RET + 48C7C0 FFFFFFFF ; mov_rax, %-1 + C3 ; ret :u #:ascii_comment - E8 %x ; CALLI32 %Read_byte - 4883F8 0D ; CMP_RAX_Immediate8 !0x0D - 0F84 %v ; JE32 %ascii_comment_cr - 4883F8 0A ; CMP_RAX_Immediate8 !0x0A - 0F85 %u ; JNE32 %ascii_comment + E8 %x ; call %Read_byte + 4883F8 0D ; cmp_rax, !0x0D + 0F84 %v ; je %ascii_comment_cr + 4883F8 0A ; cmp_rax, !0x0A + 0F85 %u ; jne %ascii_comment :v #:ascii_comment_cr - 48C7C0 FFFFFFFF ; LOADI32_RAX %-1 - C3 ; RET + 48C7C0 FFFFFFFF ; mov_rax, %-1 + C3 ; ret # process second byte of pair :w #:print # update the sum and store in output - 49C1E6 04 ; SHL_R14_Immediate8 !4 - 4C01F0 ; ADD_R14_to_RAX + 49C1E6 04 ; shl_r14, !4 + 4C01F0 ; add_rax,r14 # flip the toggle - 49F7D7 ; NOT_R15 # r15 = -1 + 49F7D7 ; not_r15 # r15 = -1 # Print our first Hex - 48C7C2 01000000 ; LOADI32_RDX %1 # set the size of chars we want - E8 %z ; CALLI32 %print_chars + 48C7C2 01000000 ; mov_rdx, %1 # set the size of chars we want + E8 %z ; call %print_chars - 4983C5 01 ; ADDI8_to_R13 !1 # Increment IP - E9 %m ; JMP32 %Second_pass + 4983C5 01 ; add_r13, !1 # Increment IP + E9 %m ; jmp %Second_pass :x #:Read_byte - 4152 ; PUSH_R10 # Protect r10 - 4153 ; PUSH_R11 # Protect r11 - 488B0D %Z ; LOAD64_rel_RCX %fin # arg1 = fin - 6A 01 ; PUSH !1 # size = 1 - 4889E2 ; COPY_RSP_to_RDX # arg2 = &size - 31F6 ; XOR_ESI_ESI # zero rsi - 56 ; PUSH_RSI # allocate stack - 4989E0 ; COPY_RSP_to_R8 # arg3 = &input - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - FF51 20 ; CALL_RCX_Immediate8 !32 # fin->read() - 58 ; POP_RAX # deallocate stack - 58 ; POP_RAX # deallocate stack - 58 ; POP_RAX # deallocate stack - 58 ; POP_RAX # save input to rax - 5E ; POP_RSI # save size to rsi - 415B ; POP_R11 # restore r11 - 415A ; POP_R10 # restore r10 + 4153 ; push_r11 # Protect r11 + 488B0D %0 ; mov_rcx,[rip+DWORD] %fin # arg1 = fin + 6A 01 ; push !1 # size = 1 + 4889E2 ; mov_rdx,rsb # arg2 = &size + 31F6 ; xor_esi_esi # zero rsi + 56 ; push_rsi # allocate stack + 4989E0 ; mov_rsp,r8 # arg3 = &input + 50 ; push_rax # allocate shadow stack space for UEFI function + 50 ; push_rax # allocate shadow stack space for UEFI function + 50 ; push_rax # allocate shadow stack space for UEFI function + FF51 20 ; call_[rcx+BYTE] !32 # fin->read() + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # deallocate stack + 58 ; pop_rax # save input to rax + 5E ; pop_rsi # save size to rsi + 415B ; pop_r11 # restore r11 # If the file ended (0 bytes read) return EOF - 85F6 ; TEST_ESI_ESI - 0F85 %y ; JNE32 %Read_byte_1 - 48C7C0 FCFFFFFF ; LOADI32_RAX %-4 # Put EOF in rax + 85F6 ; test_esi_esi + 0F85 %y ; jne %Read_byte_1 + 48C7C0 FCFFFFFF ; mov_rax, %-4 # Put EOF in rax :y #:Read_byte_1 - C3 ; RET + C3 ; ret # Writes bytes stored in rax :z #:print_chars - 4152 ; PUSH_R10 # Protect r10 - 4153 ; PUSH_R11 # Protect r11 - 4C89D1 ; COPY_R10_to_RCX # arg1 = fout - 52 ; PUSH_RDX # set size - 4889E2 ; COPY_RSP_to_RDX # arg2 = &size - 50 ; PUSH_RAX # allocate stack - 4989E0 ; COPY_RSP_to_R8 # arg3 = &output - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - FF51 28 ; CALL_RCX_Immediate8 !40 # fout->write() - 4883C4 28 ; ADDI8_RSP !40 # deallocate stack - 415B ; POP_R11 # restore r11 - 415A ; POP_R10 # restore r10 + 4153 ; push_r11 # Protect r11 + 488B0D %1 ; mov_rcx,[rip+DWORD] %fout # arg1 = fout + 52 ; push_rdx # set size + 4889E2 ; mov_rdx,rsp # arg2 = &size + 50 ; push_rax # allocate stack + 4989E0 ; mov_rsp,r8 # arg3 = &output + 50 ; push_rax # allocate shadow stack space for UEFI function + 50 ; push_rax # allocate shadow stack space for UEFI function + 50 ; push_rax # allocate shadow stack space for UEFI function + FF51 28 ; call_[rcx+BYTE] !40 # fout->write() + 4883C4 28 ; add_rsp, !40 # deallocate stack + 415B ; pop_r11 # restore r11 - C3 ; RET + C3 ; ret # Receives pointer in RBX # Writes out char and updates RBX :A #:consume_token - E8 %x ; CALLI32 %Read_byte # Consume_token + E8 %x ; call %Read_byte # Consume_token # Check for \t - 4883F8 09 ; CMP_RAX_Immediate8 !0x09 - 0F84 %B ; JE32 %consume_token_done + 4883F8 09 ; cmp_rax, !0x09 + 0F84 %B ; je %consume_token_done # Check for \n - 4883F8 0A ; CMP_RAX_Immediate8 !0x0A - 0F84 %B ; JE32 %consume_token_done + 4883F8 0A ; cmp_rax, !0x0A + 0F84 %B ; je %consume_token_done # Check for ' ' - 4883F8 20 ; CMP_RAX_Immediate8 !0x20 - 0F84 %B ; JE32 %consume_token_done + 4883F8 20 ; cmp_rax, !0x20 + 0F84 %B ; je %consume_token_done # Check for '>' - 4883F8 3E ; CMP_RAX_Immediate8 !0x3E - 0F84 %B ; JE32 %consume_token_done + 4883F8 3E ; cmp_rax, !0x3E + 0F84 %B ; je %consume_token_done # Looks like we are still reading token - 8803 ; STORE8_al_into_Address_RBX # Store char - 4883C3 01 ; ADDI8_RBX !1 # Point to next spot - E9 %A ; JMP32 %consume_token # loop until done + 8803 ; mov_[rbx],al # Store char + 4883C3 01 ; add_rbx, !1 # Point to next spot + E9 %A ; jmp %consume_token # loop until done :B #:consume_token_done - 48C7C1 00000000 ; LOADI32_RCX %0 # Pad with nulls - 48890B ; STORE32_RCX_into_Address_RBX - 4883C3 08 ; ADDI8_RBX !8 - C3 ; RET + 48C7C1 00000000 ; mov_rcx, %0 # Pad with nulls + 48890B ; mov_[rbx],rcx + 4883C3 08 ; add_rbx, !8 + C3 ; ret :C #:StoreLabel - 4C89E0 ; COPY_R12_to_RAX # ENTRY - 4983C4 18 ; ADDI8_to_R12 !24 # CALLOC - 4C8968 08 ; STORE32_R13_into_Address_RAX_Immediate8 !8 # ENTRY->TARGET = IP - 4C8918 ; STORE32_R11_into_Address_RAX # ENTRY->NEXT = JUMP_TABLE - 4989C3 ; COPY_RAX_to_R11 # JUMP_TABLE = ENTRY - 4D8963 10 ; STORE32_R12_into_Address_R11_Immediate8 !16 # ENTRY->NAME = TOKEN - 4C89E3 ; COPY_R12_to_RBX # Write Starting after struct - E8 %A ; CALLI32 %consume_token # Collect whole string - 4989DC ; COPY_RBX_to_R12 # Update HEAP - E9 %c ; JMP32 %First_pass + 4C89E0 ; mov_rax,r12 # ENTRY + 4983C4 18 ; add_r12, !24 # CALLOC + 4C8968 08 ; mov_[rax+BYTE],r13 !8 # ENTRY->TARGET = IP + 4C8918 ; mov_[rax],r11 # ENTRY->NEXT = JUMP_TABLE + 4989C3 ; mov_r11,rax # JUMP_TABLE = ENTRY + 4D8963 10 ; mov_[r11+BYTE],r12 !16 # ENTRY->NAME = TOKEN + 4C89E3 ; mov_rbx,r12 # Write Starting after struct + E8 %A ; call %consume_token # Collect whole string + 4989DC ; mov_r12,rbx # Update HEAP + E9 %c ; jmp %First_pass :D #:GetTarget - 488B3D %0 ; LOAD64_rel_RDI %scratch # Reset scratch - 4C89D9 ; COPY_R11_to_RCX # Grab JUMP_TABLE - 488B71 10 ; LOAD32_into_RSI_from_Address_RCX_Immediate8 !16 # I->NAME + 488B3D %2 ; mov_rdi,[rip+DWORD] %scratch # Reset scratch + 4C89D9 ; mov_rcx,r11 # Grab JUMP_TABLE + 488B71 10 ; mov_rsi,[rcx+BYTE] !16 # I->NAME :E #:GetTarget_loop - 8A06 ; LOAD8_AL_from_Address_RSI # I->NAME[0] - 8A1F ; LOAD8_BL_from_Address_RDI # scratch[0] - 480FB6DB ; ZERO_EXTEND_BL # Zero extend - 480FB6C0 ; ZERO_EXTEND_AL # Zero extend - 38D8 ; CMP_AL_to_BL # IF TOKEN == I->NAME - 0F85 %F ; JNE32 %GetTarget_miss # Oops + 8A06 ; mov_al,[rsi] # I->NAME[0] + 8A1F ; mov_bl,[rdi] # scratch[0] + 480FB6DB ; movzx_rbx,bl # Zero extend + 480FB6C0 ; movzx_rax,al # Zero extend + 38D8 ; cmp_al,bl # IF TOKEN == I->NAME + 0F85 %F ; jne %GetTarget_miss # Oops - 4883C6 01 ; ADDI8_to_RSI !1 - 4883C7 01 ; ADDI8_to_RDI !1 - 3C 00 ; CMPI8_AL !0 - 0F85 %E ; JNE32 %GetTarget_loop # Loop until - E9 %G ; JMP32 %GetTarget_done # Match + 4883C6 01 ; add_rsi, !1 + 4883C7 01 ; add_rdi, !1 + 3C 00 ; cmp_al, !0 + 0F85 %E ; jne %GetTarget_loop # Loop until + E9 %G ; jmp %GetTarget_done # Match # Miss :F #:GetTarget_miss - 488B09 ; LOAD32_into_RCX_from_Address_RCX # I = I->NEXT - 4883F9 00 ; CMP_RCX_Immediate8 !0 # IF NULL == I - 0F84 %R ; JE32 %fail # Abort hard + 488B09 ; mov_rcx,[rcx] # I = I->NEXT + 4883F9 00 ; cmp_rcx, !0 # IF NULL == I + 0F84 %R ; je %fail # Abort hard - 488B71 10 ; LOAD32_into_RSI_from_Address_RCX_Immediate8 !16 # I->NAME - 488B3D %0 ; LOAD64_rel_RDI %scratch # Reset scratch - E9 %E ; JMP32 %GetTarget_loop + 488B71 10 ; mov_rsi,[rcx+BYTE] !16 # I->NAME + 488B3D %2 ; mov_rdi,[rip+DWORD] %scratch # Reset scratch + E9 %E ; jmp %GetTarget_loop :G #:GetTarget_done - 488B41 08 ; LOAD32_into_RAX_from_Address_RCX_Immediate8 !8 # Get address - C3 ; RET + 488B41 08 ; mov_rax,[rcx+BYTE] !8 # Get address + C3 ; ret :H #:ClearScratch - 50 ; PUSH_RAX # Protect against changes - 53 ; PUSH_RBX # And overwrites - 51 ; PUSH_RCX - 52 ; PUSH_RDX # While we work - 488B1D %0 ; LOAD64_rel_RBX %scratch # Where our table is - B0 00 ; LOADI8_AL !0 # Using null + 50 ; push_rax # Protect against changes + 53 ; push_rbx # And overwrites + 51 ; push_rcx + 52 ; push_rdx # While we work + 488B1D %2 ; mov_rbx,[rip+DWORD] %scratch # Where our table is + B0 00 ; mov_al, !0 # Using null - 4889DA ; COPY_RBX_to_RDX # Get scratch - 4881C2 00080000 ; ADDI32_RDX %0x800 # end of scratch area + 4889DA ; mov_rdx,rbx # Get scratch + 4881C2 00080000 ; add_rdx, %0x800 # end of scratch area :I #:ClearScratch_loop - 4839D3 ; CMP_RBX_RDX # Make sure - 0F84 %J ; JE32 %ClearScratch_end # we do not overflow + 4839D3 ; cmp_rbx,rdx # Make sure + 0F84 %J ; je %ClearScratch_end # we do not overflow - 488B0B ; LOAD32_into_RCX_from_Address_RBX # Get current value - 8803 ; STORE8_al_into_Address_RBX # Because we want null - 4883C3 01 ; ADDI8_RBX !1 # Increment - 4883F9 00 ; CMP_RCX_Immediate8 !0 # Check if we hit null - 0F85 %I ; JNE32 %ClearScratch_loop # Keep looping + 488B0B ; mov_rcx,[rbx] # Get current value + 8803 ; mov_[rbx],al # Because we want null + 4883C3 01 ; add_rbx, !1 # Increment + 4883F9 00 ; cmp_rcx, !0 # Check if we hit null + 0F85 %I ; jne %ClearScratch_loop # Keep looping :J #:ClearScratch_end - 5A ; POP_RDX - 59 ; POP_RCX # Don't Forget to - 5B ; POP_RBX # Restore Damage - 58 ; POP_RAX # Entirely - C3 ; RET + 5A ; pop_rdx + 59 ; pop_rcx # Don't Forget to + 5B ; pop_rbx # Restore Damage + 58 ; pop_rax # Entirely + C3 ; ret :K #:StorePointer - E8 %f ; CALLI32 %Update_Pointer # Increment IP - 488B1D %0 ; LOAD64_rel_RBX %scratch # Write to scratch - E8 %A ; CALLI32 %consume_token # get token - 50 ; PUSH_RAX # Protect base_sep_p - 488B05 %0 ; LOAD64_rel_RAX %scratch # Pointer to scratch - E8 %D ; CALLI32 %GetTarget # Get address of pointer - E8 %H ; CALLI32 %ClearScratch # Clean up after ourselves - 4C89EA ; COPY_R13_to_RDX # base = IP - 5B ; POP_RBX # Restore base_sep_p - 4883FB 3E ; CMP_RBX_Immediate8 !0x3E # If base_sep_p == '>' - 0F85 %L ; JNE32 %StorePointer_done # If not + E8 %f ; call %Update_Pointer # Increment IP + 488B1D %2 ; mov_rbx,[rip+DWORD] %scratch # Write to scratch + E8 %A ; call %consume_token # get token + 50 ; push_rax # Protect base_sep_p + 488B05 %2 ; mov_rax,[rip+DWORD] %scratch # Pointer to scratch + E8 %D ; call %GetTarget # Get address of pointer + E8 %H ; call %ClearScratch # Clean up after ourselves + 4C89EA ; mov_rdx,r13 # base = IP + 5B ; pop_rbx # Restore base_sep_p + 4883FB 3E ; cmp_rbx, !0x3E # If base_sep_p == '>' + 0F85 %L ; jne %StorePointer_done # If not # Deal with %label>label case - 50 ; PUSH_RAX # We need to preserve main target - 488B1D %0 ; LOAD64_rel_RBX %scratch # Write to scratch - E8 %A ; CALLI32 %consume_token # get token - 488B05 %0 ; LOAD64_rel_RAX %scratch # Pointer to scratch - E8 %D ; CALLI32 %GetTarget # Get address of pointer - E8 %H ; CALLI32 %ClearScratch # Clean up after ourselves - 4889C2 ; COPY_RAX_to_RDX # Use our new base - 58 ; POP_RAX # Restore main target + 50 ; push_rax # We need to preserve main target + 488B1D %2 ; mov_rbx,[rip+DWORD] %scratch # Write to scratch + E8 %A ; call %consume_token # get token + 488B05 %2 ; mov_rax,[rip+DWORD] %scratch # Pointer to scratch + E8 %D ; call %GetTarget # Get address of pointer + E8 %H ; call %ClearScratch # Clean up after ourselves + 4889C2 ; mov_rdx,rax # Use our new base + 58 ; pop_rax # Restore main target :L #:StorePointer_done - C3 ; RET + C3 ; ret :M #:StorePointer_rel4 - E8 %K ; CALLI32 %StorePointer # Do Common - 4829D0 ; SUB_RDX_from_RAX # target - ip - 48C7C2 04000000 ; LOADI32_RDX %4 # set the size of chars we want - E8 %z ; CALLI32 %print_chars - E9 %m ; JMP32 %Second_pass + E8 %K ; call %StorePointer # Do Common + 4829D0 ; sub_rax,rdx # target - ip + 48C7C2 04000000 ; mov_rdx, %4 # set the size of chars we want + E8 %z ; call %print_chars + E9 %m ; jmp %Second_pass :N #:StorePointer_rel2 - E8 %K ; CALLI32 %StorePointer # Do Common - 4829D0 ; SUB_RDX_from_RAX # target - ip - 48C7C2 02000000 ; LOADI32_RDX %2 # set the size of chars we want - E8 %z ; CALLI32 %print_chars - E9 %m ; JMP32 %Second_pass + E8 %K ; call %StorePointer # Do Common + 4829D0 ; sub_rax,rdx # target - ip + 48C7C2 02000000 ; mov_rdx, %2 # set the size of chars we want + E8 %z ; call %print_chars + E9 %m ; jmp %Second_pass :O #:StorePointer_rel1 - E8 %K ; CALLI32 %StorePointer # Do Common - 4829D0 ; SUB_RDX_from_RAX # target - ip - 48C7C2 01000000 ; LOADI32_RDX %1 # set the size of chars we want - E8 %z ; CALLI32 %print_chars - E9 %m ; JMP32 %Second_pass + E8 %K ; call %StorePointer # Do Common + 4829D0 ; sub_rax,rdx # target - ip + 48C7C2 01000000 ; mov_rdx, %1 # set the size of chars we want + E8 %z ; call %print_chars + E9 %m ; jmp %Second_pass :P #:StorePointer_abs4 - E8 %K ; CALLI32 %StorePointer # Do Common - 48C7C2 04000000 ; LOADI32_RDX %4 # set the size of chars we want - E8 %z ; CALLI32 %print_chars - E9 %m ; JMP32 %Second_pass + E8 %K ; call %StorePointer # Do Common + 48C7C2 04000000 ; mov_rdx, %4 # set the size of chars we want + E8 %z ; call %print_chars + E9 %m ; jmp %Second_pass :Q #:StorePointer_abs2 - E8 %K ; CALLI32 %StorePointer # Do Common - 48C7C2 02000000 ; LOADI32_RDX %2 # set the size of chars we want - E8 %z ; CALLI32 %print_chars - E9 %m ; JMP32 %Second_pass + E8 %K ; call %StorePointer # Do Common + 48C7C2 02000000 ; mov_rdx, %2 # set the size of chars we want + E8 %z ; call %print_chars + E9 %m ; jmp %Second_pass :R #:fail - 48C7C0 01000000 ; LOADI32_RAX %1 # Set exit code 1 - E9 %T ; JMP32 %terminate + 48C7C0 01000000 ; mov_rax, %1 # Set exit code 1 + E9 %T ; jmp %terminate :S #:Done - 31C0 ; XOR_EAX_EAX # Set exit code 0 + 31C0 ; xor_eax_eax # Set exit code 0 :T #:terminate - 50 ; PUSH_RAX # save exit code - 4152 ; PUSH_R10 # protect fout + 50 ; push_rax # save exit code - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 4C8B35 %1 ; LOAD64_rel_R14 %SystemBoot # get system->boot - 488B0D %0 ; LOAD64_rel_RCX %scratch # arg1 = scratch - 41FF56 48 ; CALL_R14_Immediate8 !72 # system->boot->free_pool(scratch) - 58 ; POP_RAX # deallocate stack + 4C8B35 %4 ; mov_r14,[rip+DWORD] %SystemBoot # get system->boot + 488B0D %2 ; mov_rcx,[rip+DWORD] %scratch # arg1 = scratch + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !72 # system->boot->free_pool(scratch) + 58 ; pop_rax # deallocate stack - 488B0D %Z ; LOAD64_rel_RCX %fin # arg1 = fin - E8 %3 ; CALLI32 %close_file # close fin + 488B0D %1 ; mov_rcx,[rip+DWORD] %fout # get fout + E8 %U ; call %close_file # close fout - 59 ; POP_RCX # restore fout - E8 %3 ; CALLI32 %close_file # close fout +:7 # :failed_output + 488B0D %0 ; mov_rcx,[rip+DWORD] %fin # get fin + E8 %U ; call %close_file # close fin - 488B0D %2 ; LOAD64_rel_RCX %rootdir # get rootdir - E8 %3 ; CALLI32 %close_file # close rootdir + 488B0D %3 ; mov_rcx,[rip+DWORD] %rootdir # get rootdir + E8 %U ; call %close_file # close rootdir - 58 ; POP_RAX # restore exit code + 4C8B05 %5 ; mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle + 488D15 %Z ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B0D %6 ; mov_rcx,[rip+DWORD] %root_device # arg1 = root_device + E8 %W ; call %close_protocol # close protocol - 4889EC ; COPY_RBP_to_RSP # restore stack - C3 ; RET # return to UEFI + 4C8B05 %5 ; mov_r8,[rip+DWORD] %image_handle # arg3 = image_handle + 488D15 %Y ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4C89C1 ; mov_rcx,r8 # arg1 = image_handle + E8 %W ; call %close_protocol # close protocol + + 58 ; pop_rax # restore exit code + + 4889EC ; mov_rsp,rbp # restore stack + C3 ; ret # return to UEFI # rcx: file handle -:3 #:close_file - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - FF51 10 ; CALL_RCX_Immediate8 !16 # file_handle->close(file_handle) - 58 ; POP_RAX # deallocate stack - C3 ; RET +:U #:close_file + 50 ; push_rax # allocate shadow stack space for UEFI function + FF51 10 ; call_[rcx+BYTE] !16 # file_handle->close(file_handle) + 58 ; pop_rax # deallocate stack + C3 ; ret + +# rcx: handle +# rdx: &guid +# r9: agent_handle +# returns interface +:V #:open_protocol + 50 ; push_rax # allocate stack for interface + 4989E0 ; mov_r8,rsp # arg3 = &interface + 6A 01 ; push !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + 6A 00 ; push !0 # arg5 = NULL + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 18010000 ; call_[r14+DWORD] %280 # system->boot->open_protocol(handle, &guid, &interface, agent_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + 4883C4 30 ; add_rsp, !48 # deallocate stack + 58 ; pop_rax # get interface + C3 ; ret + +# rcx: handle +# rdx: &guid +# r8: agent_handle +:W #:close_protocol + 4D31C9 ; xor_r9,r9 # arg4 = NULL + 4883EC 20 ; sub_rsp, !32 # allocate shadow stack space for UEFI function + 41FF96 20010000 ; call_[r14+DWORD] %288 # system->boot->close_protocol(handle, &guid, agent_handle, 0) + 4883C4 20 ; add_rsp, !32 # deallocate stack + C3 ; ret # rdx: number of bytes to allocate # r14: system->boot # returns pointer in rax -:U #:allocate_pool - 52 ; PUSH_RDX # allocate stack for pool pointer - 4989E0 ; COPY_RSP_to_R8 # arg3 = &pool - 6A 02 ; PUSH !2 - 59 ; POP_RCX # arg1 = EFI_LOADER_DATA - 4883EC 18 ; SUBI8_RSP !24 # allocate shadow stack space for UEFI - 41FF56 40 ; CALL_R14_Immediate8 !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) - 4883C4 18 ; ADDI8_RSP !24 # deallocate stack - 58 ; POP_RAX # get pool - C3 ; RET +:X #:allocate_pool + 52 ; push_rdx # allocate stack for pool pointer + 4989E0 ; mov_r8,rsp # arg3 = &pool + 6A 02 ; push !2 + 59 ; pop_rcx # arg1 = EFI_LOADER_DATA + 4883EC 18 ; sub_rsp, !24 # allocate shadow stack space for UEFI + 41FF56 40 ; call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &pool) + 4883C4 18 ; add_rsp, !24 # deallocate stack + 58 ; pop_rax # get pool + C3 ; ret # Protocol GUIDs -:V #:LOADED_IMAGE_PROTOCOL +:Y #:LOADED_IMAGE_PROTOCOL A1 31 1B 5B ; %0x5b1b31a1 62 95 ; @0x9562 D2 11 ; @0x11d2 -:W #:LOADED_IMAGE_PROTOCOL_8 8E 3F 00 A0 C9 69 72 3B ; !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -:X #:SIMPLE_FS_PROTOCOL +:Z #:SIMPLE_FS_PROTOCOL 22 5B 4E 96 ; %0x0964e5b22 59 64 ; @0x6459 D2 11 ; @0x11d2 -:Y #:SIMPLE_FS_PROTOCOL_8 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -:Z #:fin +:0 #:fin 00000000 00000000 -:0 #:scratch +:1 #:fout 00000000 00000000 -:1 #:SystemBoot +:2 #:scratch 00000000 00000000 -:2 #:rootdir +:3 #:rootdir + 00000000 00000000 + +:4 #:SystemBoot + 00000000 00000000 + +:5 #:image_handle + 00000000 00000000 + +:6 #:root_device 00000000 00000000 # :PE32_end