From 9b9ff9ac52f63fc1b30c3a9f10d4c87e36e90d5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrius=20=C5=A0tikonas?= Date: Thu, 1 Sep 2022 01:00:56 +0100 Subject: [PATCH] hex1: Implement various improvements: * Make sure to close all protocols before exit. * Use more sophisticated command line argument processing that pushes command line arguments onto stack. * Switch to more readable M1 defines. --- amd64/Development/hex1.M1 | 689 ++++++++++++++++--------------- amd64/Development/hex1.S | 219 +++++----- amd64/Development/hex1.hex2 | 529 ++++++++++++------------ amd64/Development/hex2.M1 | 8 +- amd64/Development/hex2.S | 2 +- amd64/hex1.hex0 | 589 +++++++++++++------------- amd64/mescc-tools-mini-kaem.kaem | 2 +- 7 files changed, 1036 insertions(+), 1002 deletions(-) diff --git a/amd64/Development/hex1.M1 b/amd64/Development/hex1.M1 index fcca077..28a8fc8 100644 --- a/amd64/Development/hex1.M1 +++ b/amd64/Development/hex1.M1 @@ -3,474 +3,487 @@ # # SPDX-License-Identifier: GPL-3.0-or-later -DEFINE ADDI32_to_R13 4981C5 -DEFINE ADDI8_RBX 4883C3 -DEFINE ADD_RCX_to_RAX 4801C8 -DEFINE ADD_R14_to_RAX 4C01F0 -DEFINE ADDI8_RSP 4883C4 -DEFINE CALLI32 E8 -DEFINE CALL_RCX_Immediate8 FF51 -DEFINE CALL_R14_Immediate8 41FF56 -DEFINE CALL_R14_Immediate32 41FF96 -DEFINE CMPI8_AL 3C -DEFINE CMPI32_RAX 483D -DEFINE CMPI32_R15 4981FF -DEFINE COPY_RAX_to_R14 4989C6 -DEFINE COPY_RBX_to_R12 4989DC -DEFINE COPY_RBX_to_R13 4989DD -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_RBP_to_RSP 4889EC -DEFINE COPY_RDI_to_RCX 4889F9 -DEFINE COPY_R12_to_R8 4D89E0 -DEFINE COPY_RBX_to_RCX 4889D9 -DEFINE COPY_R13_to_R8 4D89E8 -DEFINE COPY_R14_to_RCX 4C89F1 -DEFINE COPY_R15_to_RCX 4C89F9 -DEFINE COPY_R15_to_R9 4D89F9 -DEFINE JE32 0F84 -DEFINE JL32 0F8C -DEFINE JMP32 E9 -DEFINE JNE8 75 -DEFINE JNE32 0F85 -DEFINE LOAD32_Address_in_RAX_into_RAX 678B00 -DEFINE LOAD64_into_RBX_from_Address_RAX_Immediate8 488B58 -DEFINE LOAD64_into_RAX_from_Address_RSP_Immediate8 488B4424 -DEFINE LOAD64_into_RCX_from_Address_RSP_Immediate8 488B4C24 -DEFINE LOAD64_into_RCX_from_Address_RCX_Immediate8 488B49 -DEFINE LOAD64_into_RDI_from_Address_RSP_Immediate8 488B7C24 -DEFINE LOAD64_into_RBX_from_Address_RSP_Immediate8 488B5C24 -DEFINE LOAD64_into_R14_from_Address_RDX_Immediate8 4C8B72 -DEFINE LOAD64_into_R14_from_Address_R14_Immediate32 4D8BB6 -DEFINE LOAD8_AL_from_Address_RBX 8A03 -DEFINE LOADI8_DH B6 -DEFINE LOADI32_RAX 48C7C0 -DEFINE LOADI32_RDX 48C7C2 -DEFINE LOADI32_R13 49C7C5 -DEFINE LOADI32_R14 49C7C6 -DEFINE LOADI32_R15 49C7C7 -DEFINE LOAD64_rel_RCX 488B0D -DEFINE LOAD64_rel_RDX 488B15 -DEFINE LOAD64_rel_R14 4C8B35 -DEFINE NOT_R15 49F7D7 -DEFINE POP_RAX 58 -DEFINE POP_RCX 59 -DEFINE POP_RSI 5E -DEFINE POP_R9 4159 -DEFINE POP_R14 415E -DEFINE PUSH 6A -DEFINE PUSH_RAX 50 -DEFINE PUSH_RBX 53 -DEFINE PUSH_RDX 52 -DEFINE PUSH_RSI 56 -DEFINE RET C3 -DEFINE ROR_R9 49D1C9 -DEFINE SHL8_R14 49C1E6 -DEFINE SHL8_RAX 48C1E0 -DEFINE STORE32_R13_to_Address_in_RAX 4C8928 -DEFINE STORE64_rel_R14 4C8935 -DEFINE STORE64_rel_RAX 488905 -DEFINE STOREI8_into_Address_RBX C603 -DEFINE SUBI8_RSP 4883EC -DEFINE SUBI8_from_RAX 4883E8 -DEFINE SUB_R13_from_RAX 4C29E8 -DEFINE XOR_EDX_EDX 31D2 -DEFINE TEST_ESI_ESI 85F6 +DEFINE add_rbx, 4883C3 +DEFINE add_rsp, 4883C4 +DEFINE add_r13, 4981C5 +DEFINE add_rax,rcx 4801C8 +DEFINE add_rax,r14 4C01F0 +DEFINE add_rbx,[rdi+BYTE] 48035F +DEFINE call E8 +DEFINE call_[rcx+BYTE] FF51 +DEFINE call_[r14+BYTE] 41FF56 +DEFINE call_[r14+DWORD] 41FF96 +DEFINE cmp_al, 3C +DEFINE cmp_rax, 483D +DEFINE cmp_r15, 4981FF +DEFINE cmp_rbx,rdx 4839D3 +DEFINE je 0F84 +DEFINE je8 74 +DEFINE jl 0F8C +DEFINE jmp E9 +DEFINE jmp8 EB +DEFINE jne 0F85 +DEFINE jne8 75 +DEFINE lea_rdx,[rip+DWORD] 488D15 +DEFINE mov_dh, B6 +DEFINE mov_rax, 48C7C0 +DEFINE mov_rdx, 48C7C2 +DEFINE mov_r13, 49C7C5 +DEFINE mov_r14, 49C7C6 +DEFINE mov_r15, 49C7C7 +DEFINE mov_rbp,rsp 4889E5 +DEFINE mov_rcx,rbx 4889D9 +DEFINE mov_rcx,rdi 4889F9 +DEFINE mov_rcx,rsi 4889F1 +DEFINE mov_rcx,r8 4C89C1 +DEFINE mov_rcx,r9 4C89C9 +DEFINE mov_rcx,r13 4C89E9 +DEFINE mov_rdx,rbx 4889DA +DEFINE mov_rdx,rsp 4889E2 +DEFINE mov_rsp,rbp 4889EC +DEFINE mov_r8,rsp 4989E0 +DEFINE mov_r8,r15 4D89F8 +DEFINE mov_r9,r15 4D89F9 +DEFINE mov_r13,rcx 4989CD +DEFINE mov_r14,rax 4989C6 +DEFINE mov_r15,rcx 4989CF +DEFINE mov_al,[rbx] 8A03 +DEFINE mov_rax,[rax] 488B00 +DEFINE mov_[rbx], C603 +DEFINE mov_rbx,[rdi+BYTE] 488B5F +DEFINE mov_rcx,[rdi+BYTE] 488B4F +DEFINE mov_rcx,[rsp+BYTE] 488B4C24 +DEFINE mov_rdi,[rsp+BYTE] 488B7C24 +DEFINE mov_r14,[rdx+BYTE] 4C8B72 +DEFINE mov_[rax],r13 4C8928 +DEFINE not_r15 49F7D7 +DEFINE pop_rax 58 +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_r13 415D +DEFINE pop_r14 415E +DEFINE pop_r15 415F +DEFINE push 6A +DEFINE push_rax 50 +DEFINE push_rbx 53 +DEFINE push_rdx 52 +DEFINE push_rsi 56 +DEFINE push_r13 4155 +DEFINE push_r14 4156 +DEFINE push_r15 4157 +DEFINE ret C3 +DEFINE ror_r9 49D1C9 +DEFINE shl_rax, 48C1E0 +DEFINE shl_r14, 49C1E6 +DEFINE sub_rax, 4883E8 +DEFINE sub_rbx, 4883EB +DEFINE sub_rsp, 4883EC +DEFINE sub_rax,r13 4C29E8 +DEFINE test_esi,esi 85F6 +DEFINE xor_edx,edx 31D2 +DEFINE xor_esi,esi 31F6 +DEFINE xor_r9,r9 4D31C9 + # 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 - - # Allocate pool for single-character label table - PUSH_RDX # allocate stack for table - COPY_RSP_to_R8 # arg3 = &table - XOR_EDX_EDX # zero rdx - LOADI8_DH !0x8 # arg2 = 256 * 8 = 2048 = 0x800 - 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, &table) - ADDI8_RSP !24 # deallocate stack - POP_RAX # get table - STORE64_rel_RAX %table # save table + mov_rbp,rsp # save stack pointer + mov_r15,rcx # save image_handle + mov_r14,[rdx+BYTE] !96 # 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 != ' ' - JNE8 !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 != ' ' - JNE8 !loop_options2 # then jump - - STOREI8_into_Address_RBX !0 # *options = 0; - ADDI8_RBX !2 # ++options - COPY_RBX_to_R13 # save output file + mov_r9,r15 # arg4 = image_handle + lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + mov_rcx,r9 # arg1 = image_handle + push_rax # allocate stack for image + mov_r8,rsp # arg3 = &image + 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(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + mov_rdi,[rsp+BYTE] !48 # 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,r15 # 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_r13,rcx # save root_device + push_rax # allocate stack for rootfs + mov_r8,rsp # arg3 = &rootfs + 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(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + mov_rcx,[rsp+BYTE] !48 # 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_R14 # save rootdir + push_rax # allocate stack for rootdir + mov_rdx,rsp # 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 + pop_rsi # get rootdir + + # Push command line arguments onto stack + mov_rbx,[rdi+BYTE] !56 # options = image->load_options + mov_rdx,rbx # save beginning of load_options + add_rbx,[rdi+BYTE] !48 # go to the end of load_options + push !0 # Save end of arguments (NULL) onto stack +:loop_options + cmp_rbx,rdx # Check if we are done + je8 !loop_options_done # We are done + sub_rbx, !2 # --options + mov_al,[rbx] # *options + cmp_al, !0x20 # if *options != ' ' + jne8 !loop_options # then continue looping + mov_[rbx], !0 # zero it + add_rbx, !2 # ++options + push_rbx # push another argument onto stack + jmp8 !loop_options # next argument +:loop_options_done # 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_R14_to_RCX # arg1 = rootdir - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # rootdir->open() - LOAD64_into_RDI_from_Address_RSP_Immediate8 !40 # get fin + pop_r8 # arg3 = in + push_rdx # allocate stack for fin + mov_rdx,rsp # arg2 = &fin + push !1 # arg5 = EFI_FILE_READ_ONLY + push !1 # prepare to set arg4 to EFI_FILE_MODE_READ + pop_r9 # arg4 = EFI_FILE_MODE_READ + mov_rcx,rsi # arg1 = rootdir + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !8 # rootdir->open() + add_rsp, !40 # deallocate stack + pop_rdi # get fin # 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_R14_to_RCX # arg1 = rootdir - SUBI8_RSP !32 # allocate shadow stack space for UEFI function - CALL_RCX_Immediate8 !8 # rootdir->open() - LOAD64_into_RBX_from_Address_RSP_Immediate8 !40 # get fout + pop_r8 # arg3 = out + push_rdx # allocate stack for fout + mov_rdx,rsp # 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,rsi # arg1 = rootdir + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[rcx+BYTE] !8 # rootdir->open() + add_rsp, !40 # deallocate stack + pop_rbx # get fout - LOADI32_R15 %-1 # Our flag for byte processing - LOADI32_R14 %0 # temp storage for the sum - LOADI32_R13 %0 # Our starting IP - CALLI32 %First_pass # Process it + # Save variables that are needed for cleanup + push_r13 # save root_device + push_r14 # save system->boot + push_r15 # save image_handle + push_rsi # save rootdir + + # Allocate pool for single-character label table + # pointer to table will be stored at the top of the stack + push_rdx # allocate stack for table + mov_r8,rsp # arg3 = &table + xor_edx,edx # zero rdx + mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800 + push !2 + pop_rcx # arg1 = EFI_LOADER_DATA + sub_rsp, !24 # allocate shadow stack space for UEFI function + call_[r14+BYTE] !64 # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table) + add_rsp, !24 # deallocate stack + + mov_r15, %-1 # Our flag for byte processing + mov_r14, %0 # temp storage for the sum + mov_r13, %0 # Our starting IP + call %First_pass # Process it # rewind input file - COPY_RDI_to_RCX # 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 + mov_rcx,rdi # 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 - LOADI32_R15 %-1 # Our flag for byte processing - LOADI32_R14 %0 # temp storage for the sum - LOADI32_R13 %0 # 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, %0 # Our starting IP + call %Second_pass # Process it - JMP32 %Done + jmp %Done :First_pass - CALLI32 %Read_byte + call %Read_byte # Deal with EOF - CMPI32_RAX %-4 - JE32 %First_pass_done + cmp_rax, %-4 + je %First_pass_done # Check for : - CMPI32_RAX %0x3a - JNE32 %First_pass_0 + cmp_rax, %0x3a + jne %First_pass_0 # Deal with label - CALLI32 %StoreLabel + call %StoreLabel :First_pass_0 # Check for % - CMPI32_RAX %0x25 - JE32 %First_pass_pointer + cmp_rax, %0x25 + je %First_pass_pointer # Deal with everything else - CALLI32 %hex # Process our char + call %hex # Process our char # Deal with EOF - CMPI32_RAX %-4 - JE32 %First_pass_done + cmp_rax, %-4 + je %First_pass_done # deal with -1 values - CMPI32_RAX %0 - JL32 %First_pass + cmp_rax, %0 + jl %First_pass # deal with toggle - CMPI32_R15 %0 - JE32 %First_pass_1 - ADDI32_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 :First_pass_pointer # Deal with Pointer to label - CALLI32 %Read_byte # Drop the char - ADDI32_to_R13 %4 # Increment IP - JMP32 %First_pass # Loop again + call %Read_byte # Drop the char + add_r13, %4 # Increment IP + jmp %First_pass # Loop again :First_pass_done - RET + ret :hex # deal with EOF - CMPI32_RAX %-4 - JE32 %EOF + cmp_rax, %-4 + je %EOF # deal with line comments starting with # - CMPI32_RAX %0x23 - JE32 %ascii_comment + cmp_rax, %0x23 + je %ascii_comment # deal with line comments starting with ; - CMPI32_RAX %0x3b - JE32 %ascii_comment + cmp_rax, %0x3b + je %ascii_comment # deal all ascii less than 0 - CMPI32_RAX %0x30 - JL32 %ascii_other + cmp_rax, %0x30 + jl %ascii_other # deal with 0-9 - CMPI32_RAX %0x3a - JL32 %ascii_num + cmp_rax, %0x3a + jl %ascii_num # deal with all ascii less than A - CMPI32_RAX %0x41 - JL32 %ascii_other + cmp_rax, %0x41 + jl %ascii_other # deal with A-F - CMPI32_RAX %0x47 - JL32 %ascii_high + cmp_rax, %0x47 + jl %ascii_high # deal with all ascii less than a - CMPI32_RAX %0x61 - JL32 %ascii_other + cmp_rax, %0x61 + jl %ascii_other # deal with a-f - CMPI32_RAX %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 - CMPI32_RAX %-4 - JE32 %Second_pass_done + cmp_rax, %-4 + je %Second_pass_done # Simply drop the label - CMPI32_RAX %0x3a - JNE32 %Second_pass_0 + cmp_rax, %0x3a + jne %Second_pass_0 - CALLI32 %Read_byte - JMP32 %Second_pass + call %Read_byte + jmp %Second_pass :Second_pass_0 # Deal with % pointer - CMPI32_RAX %0x25 - JNE32 %Second_pass_1 + cmp_rax, %0x25 + jne %Second_pass_1 - CALLI32 %StorePointer - JMP32 %Second_pass + call %StorePointer + jmp %Second_pass :Second_pass_1 # Deal with everything else - CALLI32 %hex # Process our char + call %hex # Process our char # Deal with EOF - CMPI32_RAX %-4 - JE32 %Second_pass_done + cmp_rax, %-4 + je %Second_pass_done # deal with -1 values - CMPI32_RAX %0 - JL32 %Second_pass + cmp_rax, %0 + jl %Second_pass # deal with toggle - CMPI32_R15 %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 - RET - :EOF - RET + ret :ascii_num - SUBI8_from_RAX !0x30 - RET + sub_rax, !0x30 + ret :ascii_low - SUBI8_from_RAX !0x57 - RET + sub_rax, !0x57 + ret :ascii_high - SUBI8_from_RAX !0x37 - RET + sub_rax, !0x37 + ret :ascii_other - LOADI32_RAX %-1 - RET + mov_rax, %-1 + ret :ascii_comment - CALLI32 %Read_byte - CMPI32_RAX %0xd - JE32 %ascii_comment_cr - CMPI32_RAX %0xa - JNE32 %ascii_comment + call %Read_byte + cmp_rax, %0xd + je %ascii_comment_cr + cmp_rax, %0xa + 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 - SHL8_R14 !4 - ADD_R14_to_RAX + shl_r14, !4 + add_rax,r14 # flip the toggle - NOT_R15 # R15 = -1 + not_r15 # R15 = -1 - 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 - ADDI32_to_R13 %1 # Increment IP - JMP32 %Second_pass + add_r13, %1 # Increment IP + jmp %Second_pass :Read_byte - COPY_RDI_to_RCX # arg1 = fin - PUSH !1 # size = 1 - COPY_RSP_to_RDX # arg2 = &size - 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 + mov_rcx,rdi # arg1 = fin + push !1 # size = 1 + mov_rdx,rsp # arg2 = &size + xor_esi,esi # zero rsi + push_rsi # allocate stack + mov_r8,rsp # 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 # If the file ended (0 bytes read) return EOF - TEST_ESI_ESI # if size = 0 - JNE8 !Read_byte_1 - LOADI32_RAX %-4 # Put EOF in rax + test_esi,esi # if size = 0 + jne8 !Read_byte_1 + mov_rax, %-4 # Put EOF in rax :Read_byte_1 - RET # return + ret # return # Writes bytes stored in rax :print_chars - COPY_RBX_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 + mov_rcx,rbx # arg1 = fout + push_rdx # set size + mov_rdx,rsp # arg2 = &size + push_rax # allocate stack + mov_r8,rsp # 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 - RET # return + ret # return :Get_table_target - CALLI32 %Read_byte # Get single char label - SHL8_RAX !3 # Each label in table takes 8 bytes to store - LOAD64_rel_RCX %table # Get table - ADD_RCX_to_RAX # Calculate offset - RET + call %Read_byte # Get single char label + shl_rax, !3 # Each label in table takes 8 bytes to store + mov_rcx,[rsp+BYTE] !24 # Get table + add_rax,rcx # Calculate offset + ret :StoreLabel - CALLI32 %Get_table_target - STORE32_R13_to_Address_in_RAX # Write out pointer to table - RET + call %Get_table_target + mov_[rax],r13 # Write out pointer to table + ret :StorePointer - ADDI32_to_R13 %4 # Increment IP - CALLI32 %Get_table_target # Get address of pointer - LOAD32_Address_in_RAX_into_RAX # Get pointer - SUB_R13_from_RAX # target - ip - LOADI32_RDX %4 # set the size of chars we want - CALLI32 %print_chars - RET + add_r13, %4 # Increment IP + call %Get_table_target # Get address of pointer + mov_rax,[rax] # Get pointer + sub_rax,r13 # target - ip + mov_rdx, %4 # set the size of chars we want + call %print_chars + ret :Done + pop_rcx # restore table + pop_rsi # restore rootdir + pop_r15 # restore image_handle + pop_r14 # restore system->boot + pop_r13 # restore root_device + # Free pool - LOAD64_rel_RCX %table # arg1 = table - PUSH_RAX # allocate shadow stack space for UEFI function - LOAD64_rel_R14 %SystemBoot # get system->boot - CALL_R14_Immediate8 !72 # system->boot->free_pool(table) + # arg1 = table + push_rax # allocate shadow stack space for UEFI function + call_[r14+BYTE] !72 # system->boot->free_pool(table) - COPY_RDI_to_RCX # arg1 = fin - CALL_RCX_Immediate8 !16 # fin->close() - COPY_RBX_to_RCX # arg1 = fout - CALL_RCX_Immediate8 !16 # fout->close() + mov_rcx,rdi # arg1 = fin + call_[rcx+BYTE] !16 # fin->close() + mov_rcx,rbx # arg1 = fout + call_[rcx+BYTE] !16 # fout->close() + mov_rcx,rsi # arg1 = rootdir + call_[rcx+BYTE] !16 # rootdir->close() - COPY_RBP_to_RSP # restore stack - RET # return to UEFI + mov_r8,r15 # arg3 = image_handle + lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + mov_rcx,r13 # arg1 = root_device + xor_r9,r9 # arg4 = NULL + sub_rsp, !32 # allocate shadow stack space for UEFI function + call_[r14+DWORD] %288 # system->boot->close_protocol(root_device, &guid, image_handle, 0) + mov_r8,r15 # arg3 = image_handle + lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + mov_rcx,r8 # arg1 = image_handle + xor_r9,r9 # arg4 = NULL + call_[r14+DWORD] %288 # system->boot->close_protocol(image_handle, &guid, image_handle, 0) + + mov_rsp,rbp # restore stack + ret # return to UEFI # Protocol GUIDs :LOADED_IMAGE_PROTOCOL %0x5b1b31a1 @0x9562 @0x11d2 -:LOADED_IMAGE_PROTOCOL_8 !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :SIMPLE_FS_PROTOCOL %0x0964e5b22 @0x6459 @0x11d2 -:SIMPLE_FS_PROTOCOL_8 !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -:table - %0 %0 - -:SystemBoot - %0 %0 - :PE32_end diff --git a/amd64/Development/hex1.S b/amd64/Development/hex1.S index ccf36fc..592789a 100644 --- a/amd64/Development/hex1.S +++ b/amd64/Development/hex1.S @@ -3,6 +3,9 @@ # # SPDX-License-Identifier: GPL-3.0-or-later +# Some of the functions are deliberately inlined at the slight expense of +# binary size to avoid tricky jump calculations in hex0 code. + .global _start .text @@ -11,9 +14,95 @@ _start: mov rbp, rsp # save stack pointer mov r15, rcx # save image_handle mov r14, [rdx+96] # system->boot - mov [rip+SystemBoot], r14 # save system->boot + + # Open Loaded Image protocol + mov r9, r15 # arg4 = image_handle + lea rdx, [rip+LOADED_IMAGE_PROTOCOL] # guid = &LOADED_IMAGE_PROTOCOL + mov rcx, r9 # arg1 = image_handle + push rax # allocate stack for image + mov r8, rsp # arg3 = &image + 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(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + mov rdi, [rsp+48] # save image + + # Get root file system + mov r9, r15 # arg4 = image_handle + lea rdx, [rip+SIMPLE_FS_PROTOCOL] # guid = &SIMPLE_FS_PROTOCOL + mov rcx, [rdi+24] # arg1 = root_device = image->device + mov r13, rcx # save root_device + push rax # allocate stack for rootfs + mov r8, rsp # arg3 = &rootfs + 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(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + mov rcx, [rsp+48] # get rootfs + + # Get root directory + push rax # allocate stack for rootdir + mov rdx, rsp # 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 rsi # get 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 + pop r8 # arg3 = in + push rdx # allocate stack for fin + mov rdx, rsp # arg2 = &fin + push 1 # arg5 = EFI_FILE_READ_ONLY + push 1 # prepare to set arg4 to EFI_FILE_MODE_READ + pop r9 # arg4 = EFI_FILE_MODE_READ + mov rcx, rsi # arg1 = rootdir + sub rsp, 32 # allocate shadow stack space for UEFI function + call [rcx+8] # rootdir->open() + add rsp, 40 # deallocate stack + pop rdi # get fin + + # Open file for writing + pop r8 # arg3 = out + push rdx # allocate stack for fout + mov rdx, rsp # 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, rsi # arg1 = rootdir + sub rsp, 32 # allocate shadow stack space for UEFI function + call [rcx+8] # rootdir->open() + add rsp, 40 # deallocate stack + pop rbx # get fout + + # Save variables that are needed for cleanup + push r13 # save root_device + push r14 # save system->boot + push r15 # save image_handle + push rsi # save rootdir # Allocate pool for single-character label table + # pointer to table will be stored at the top of the stack push rdx # allocate stack for table mov r8, rsp # arg3 = &table xor edx, edx # zero rdx @@ -23,98 +112,6 @@ _start: sub rsp, 24 # allocate shadow stack space for UEFI call [r14+64] # system->boot->allocate_pool(EFI_LOADER_DATA, 2048, &table) add rsp, 24 # deallocate stack - pop rax # get table - mov [rip+table], rax # save table - - # 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 - - # 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 - - # Get root directory - push rdx # allocate stack for rootdir - mov rdx, rsp # 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 r14 # save rootdir - - # Open file for reading - push rdx # allocate stack for fin - mov rdx, rsp # arg2 = &fin - push 1 # arg5 = EFI_FILE_READ_ONLY - push 1 # prepare to set arg4 to EFI_FILE_MODE_READ - pop r9 # arg4 = EFI_FILE_MODE_READ - mov r8, r12 # arg3 = in - mov rcx, r14 # arg1 = rootdir - sub rsp, 32 # allocate shadow stack space for UEFI function - call [rcx+8] # rootdir->open() - mov rdi, [rsp+40] # get fin - - # Open file for writing - push rdx # allocate stack for fout - mov rdx, rsp # 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, r14 # arg1 = rootdir - sub rsp, 32 # allocate shadow stack space for UEFI function - call [rcx+8] # rootdir->open() - mov rbx, [rsp+40] # get fout mov r15, -1 # Our flag for byte processing mov r14, 0 # temp storage for the sum @@ -261,8 +258,6 @@ Second_pass_1: jmp Second_pass Second_pass_done: - ret - EOF: ret ascii_num: @@ -307,6 +302,7 @@ Read_byte: mov rcx, rdi # arg1 = fin push 1 # size = 1 mov rdx, rsp # arg2 = &size + xor esi, esi # zero rsi push rsi # allocate stack mov r8, rsp # arg3 = &input push rax # allocate shadow stack space for UEFI function @@ -345,7 +341,7 @@ print_chars: Get_table_target: call Read_byte # Get single char label shl rax, 3 # Each label in table takes 8 bytes to store - mov rcx, [rip+table] # Get table + mov rcx, [rsp+24] # Get table add rax, rcx # Calculate offset ret @@ -364,16 +360,37 @@ StorePointer: ret Done: + pop rcx # restore table + pop rsi # restore rootdir + pop r15 # restore image_handle + pop r14 # restore system->boot + pop r13 # restore root_device + # Free pool - mov rcx, [rip+table] # arg1 = table + # arg1 = table push rax # allocate shadow stack space for UEFI function - mov r14, [rip+SystemBoot] # get system->boot call [r14+72] # system->boot->free_pool(table) mov rcx, rdi # arg1 = fin call [rcx+16] # fin->close() mov rcx, rbx # arg1 = fout call [rcx+16] # fout->close() + mov rcx, rsi # arg1 = rootdir + call [rcx+16] # rootdir->close() + + mov r8, r15 # arg3 = image_handle + lea rdx, [rip+SIMPLE_FS_PROTOCOL] # guid = &SIMPLE_FS_PROTOCOL + mov rcx, r13 # arg1 = root_device + xor r9, r9 # arg4 = NULL + sub rsp, 32 # allocate shadow stack space for UEFI function + call [r14+288] # system->boot->close_protocol(root_device, &guid, image_handle, 0) + + mov r8, r15 # arg3 = image_handle + lea rdx, [rip+LOADED_IMAGE_PROTOCOL] # guid = &LOADED_IMAGE_PROTOCOL + mov rcx, r8 # arg1 = image_handle + xor r9, r9 # arg4 = NULL + call [r14+288] # system->boot->close_protocol(image_handle, &guid, image_handle, 0) + abort: # used for debugging only mov rsp, rbp # restore stack ret # return to UEFI @@ -391,9 +408,3 @@ SIMPLE_FS_PROTOCOL: .short 0x6459 .short 0x11d2 .byte 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b - -table: -.long 0, 0 - -SystemBoot: -.long 0, 0 diff --git a/amd64/Development/hex1.hex2 b/amd64/Development/hex1.hex2 index a79a455..1a904d9 100644 --- a/amd64/Development/hex1.hex2 +++ b/amd64/Development/hex1.hex2 @@ -6,374 +6,387 @@ # 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 %SystemBoot ; STORE64_rel_R14 %SystemBoot # save system->boot - - # Allocate pool for single-character label table - 52 ; PUSH_RDX # allocate stack for table - 4989E0 ; COPY_RSP_to_R8 # arg3 = &table - 31D2 ; XOR_EDX_EDX # zero rdx - B6 08 ; LOADI8_DH !0x8 # arg2 = 256 * 8 = 2048 = 0x800 - 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, &table) - 4883C4 18 ; ADDI8_RSP !24 # deallocate stack - 58 ; POP_RAX # get table - 488905 %table ; STORE64_rel_RAX %table # save table + 4889E5 ; mov_rbp,rsp # save stack pointer + 4989CF ; mov_r15,rcx # save image_handle + 4C8B72 60 ; mov_r14,[rdx+BYTE] !96 # system->boot # Open Loaded Image protocol - 50 ; PUSH_RAX # allocate stack for image - 4989E0 ; COPY_RSP_to_R8 # arg3 = &image - 488B15 %LOADED_IMAGE_PROTOCOL_8 ; LOAD64_rel_RDX !LOADED_IMAGE_PROTOCOL_8 # EFI_LOADED_IMAGE_PROTOCOL_GUID (last 64 bits) - 52 ; PUSH_RDX # push last 64 bits onto stack - 488B15 %LOADED_IMAGE_PROTOCOL ; LOAD64_rel_RDX !LOADED_IMAGE_PROTOCOL # EFI_LOADED_IMAGE_PROTOCOL_GUID (first 64 bits) - 52 ; PUSH_RDX # push first 64 bits onto 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 - -: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 != ' ' - 75 !loop_options1 ; JNE8 !loop_options1 # then jump - - 4883C3 02 ; ADDI8_RBX !2 # ++options - 4989DC ; COPY_RBX_to_R12 # save input file - -: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 != ' ' - 75 !loop_options2 ; JNE8 !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 + 4D89F9 ; mov_r9,r15 # arg4 = image_handle + 488D15 %LOADED_IMAGE_PROTOCOL ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4C89C9 ; mov_rcx,r9 # arg1 = image_handle + 50 ; push_rax # allocate stack for image + 4989E0 ; mov_r8,rsp # arg3 = &image + 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(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + 488B7C24 30 ; mov_rdi,[rsp+BYTE] !48 # save image # Get root file system - 50 ; PUSH_RAX # allocate stack for rootfs - 4989E0 ; COPY_RSP_to_R8 # arg3 = &rootfs - 488B15 %SIMPLE_FS_PROTOCOL_8 ; LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL_8 # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (last 64 bits) - 52 ; PUSH_RDX # push last 64 bits onto stack - 488B15 %SIMPLE_FS_PROTOCOL ; LOAD64_rel_RDX %SIMPLE_FS_PROTOCOL # EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID (first 64 bits) - 52 ; PUSH_RDX # push first 64 bits onto stack - 4889E2 ; COPY_RSP_to_RDX # arg2 = &guid - 6A 01 ; PUSH !1 # arg6 = EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - 6A 00 ; PUSH !0 # arg5 = NULL - 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 + 4D89F9 ; mov_r9,r15 # arg4 = image_handle + 488D15 %SIMPLE_FS_PROTOCOL ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B4F 18 ; mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device + 4989CD ; mov_r13,rcx # save root_device + 50 ; push_rax # allocate stack for rootfs + 4989E0 ; mov_r8,rsp # arg3 = &rootfs + 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(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + 488B4C24 30 ; mov_rcx,[rsp+BYTE] !48 # 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 - 415E ; POP_R14 # save rootdir + 50 ; push_rax # allocate stack for rootdir + 4889E2 ; mov_rdx,rsp # 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 + 5E ; pop_rsi # save rootdir + + # Push command line arguments onto stack + 488B5F 38 ; mov_rbx,[rdi+BYTE] !56 # options = image->load_options + 4889DA ; mov_rdx,rbx # save beginning of load_options + 48035F 30 ; add_rbx,[rdi+BYTE] !48 # go to the end of load_options + 6A 00 ; push !0 # Save end of arguments (NULL) onto stack +:loop_options + 4839D3 ; cmp_rbx,rdx # Check if we are done + 74 !loop_options_done ; je8 !loop_options_done # We are done + 4883EB 02 ; sub_rbx, !2 # --options + 8A03 ; mov_al,[rbx] # *options + 3C 20 ; cmp_al, !0x20 # if *options != ' ' + 75 !loop_options ; jne8 !loop_options # then continue looping + C603 00 ; mov_[rbx], !0 # zero it + 4883C3 02 ; add_rbx, !2 # ++options + 53 ; push_rbx # push another argument onto stack + EB !loop_options ; jmp8 !loop_options # next argument +:loop_options_done # 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 - 4C89F1 ; COPY_R14_to_RCX # arg1 = rootdir - 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function - FF51 08 ; CALL_RCX_Immediate8 !8 # rootdir->open() - 488B7C24 28 ; LOAD64_into_RDI_from_Address_RSP_Immediate8 !40 # get fin + 4158 ; pop_r8 # arg3 = in + 52 ; push_rdx # allocate stack for fin + 4889E2 ; mov_rdx,rsp # arg2 = &fin + 6A 01 ; push !1 # arg5 = EFI_FILE_READ_ONLY + 6A 01 ; push !1 # prepare to set arg4 to EFI_FILE_MODE_READ + 4159 ; pop_r9 # arg4 = EFI_FILE_MODE_READ + 4889F1 ; mov_rcx,rsi # 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 + 5F ; pop_rdi # get fin # 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 - 4C89F1 ; COPY_R14_to_RCX # arg1 = rootdir - 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function - FF51 08 ; CALL_RCX_Immediate8 !8 # rootdir->open() - 488B5C24 28 ; LOAD64_into_RBX_from_Address_RSP_Immediate8 !40 # get fout + 4158 ; pop_r8 # arg3 = out + 52 ; push_rdx # allocate stack for fout + 4889E2 ; mov_rdx,rsp # 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 + 4889F1 ; mov_rcx,rsi # 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 + 5B ; pop_rbx # get fout - 49C7C7 FFFFFFFF ; LOADI32_R15 %-1 # Our flag for byte processing - 49C7C6 00000000 ; LOADI32_R14 %0 # temp storage for the sum - 49C7C5 00000000 ; LOADI32_R13 %0 # Our starting IP - E8 %First_pass ; CALLI32 %First_pass # Process it + # Save variables that are needed for cleanup + 4155 ; push_r13 # save root_device + 4156 ; push_r14 # save system->boot + 4157 ; push_r15 # save image_handle + 56 ; push_rsi # save rootdir + + # Allocate pool for single-character label table + # pointer to table will be stored at the top of the stack + 52 ; push_rdx # allocate stack for table + 4989E0 ; mov_r8,rsp # arg3 = &table + 31D2 ; xor_edx,edx # zero rdx + B6 08 ; mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800 + 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, &table) + 4883C4 18 ; add_rsp, !24 # deallocate stack + + 49C7C7 FFFFFFFF ; mov_r15, %-1 # Our flag for byte processing + 49C7C6 00000000 ; mov_r14, %0 # temp storage for the sum + 49C7C5 00000000 ; mov_r13, %0 # Our starting IP + E8 %First_pass ; call %First_pass # Process it # rewind input file - 4889F9 ; COPY_RDI_to_RCX # 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 + 4889F9 ; mov_rcx,rdi # 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 - 49C7C7 FFFFFFFF ; LOADI32_R15 %-1 # Our flag for byte processing - 49C7C6 00000000 ; LOADI32_R14 %0 # temp storage for the sum - 49C7C5 00000000 ; LOADI32_R13 %0 # Our starting IP - E8 %Second_pass ; 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 00000000 ; mov_r13, %0 # Our starting IP + E8 %Second_pass ; call %Second_pass # Process it - E9 %Done ; JMP32 %Done + E9 %Done ; jmp %Done :First_pass - E8 %Read_byte ; CALLI32 %Read_byte + E8 %Read_byte ; call %Read_byte # Deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 %First_pass_done ; JE32 %First_pass_done + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 %First_pass_done ; je %First_pass_done # Check for : - 483D 3A000000 ; CMPI32_RAX %0x3a - 0F85 %First_pass_0 ; JNE32 %First_pass_0 + 483D 3A000000 ; cmp_rax, %0x3a + 0F85 %First_pass_0 ; jne %First_pass_0 # Deal with label - E8 %StoreLabel ; CALLI32 %StoreLabel + E8 %StoreLabel ; call %StoreLabel :First_pass_0 # Check for % - 483D 25000000 ; CMPI32_RAX %0x25 - 0F84 %First_pass_pointer ; JE32 %First_pass_pointer + 483D 25000000 ; cmp_rax, %0x25 + 0F84 %First_pass_pointer ; je %First_pass_pointer # Deal with everything else - E8 %hex ; CALLI32 %hex # Process our char + E8 %hex ; call %hex # Process our char # Deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 %First_pass_done ; JE32 %First_pass_done + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 %First_pass_done ; je %First_pass_done # deal with -1 values - 483D 00000000 ; CMPI32_RAX %0 - 0F8C %First_pass ; JL32 %First_pass + 483D 00000000 ; cmp_rax, %0 + 0F8C %First_pass ; jl %First_pass # deal with toggle - 4981FF 00000000 ; CMPI32_R15 %0 - 0F84 %First_pass_1 ; JE32 %First_pass_1 - 4981C5 01000000 ; ADDI32_to_R13 %1 # Increment IP + 4981FF 00000000 ; cmp_r15, %0 + 0F84 %First_pass_1 ; je %First_pass_1 + 4981C5 01000000 ; add_r13, %1 # Increment IP :First_pass_1 - 49F7D7 ; NOT_R15 - E9 %First_pass ; JMP32 %First_pass + 49F7D7 ; not_r15 + E9 %First_pass ; jmp %First_pass :First_pass_pointer # Deal with Pointer to label - E8 %Read_byte ; CALLI32 %Read_byte # Drop the char - 4981C5 04000000 ; ADDI32_to_R13 %4 # Increment IP - E9 %First_pass ; JMP32 %First_pass # Loop again + E8 %Read_byte ; call %Read_byte # Drop the char + 4981C5 04000000 ; add_r13, %4 # Increment IP + E9 %First_pass ; jmp %First_pass # Loop again :First_pass_done - C3 ; RET + C3 ; ret :hex # deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 %EOF ; JE32 %EOF + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 %EOF ; je %EOF # deal with line comments starting with # - 483D 23000000 ; CMPI32_RAX %0x23 - 0F84 %ascii_comment ; JE32 %ascii_comment + 483D 23000000 ; cmp_rax, %0x23 + 0F84 %ascii_comment ; je %ascii_comment # deal with line comments starting with ; - 483D 3B000000 ; CMPI32_RAX %0x3b - 0F84 %ascii_comment ; JE32 %ascii_comment + 483D 3B000000 ; cmp_rax, %0x3b + 0F84 %ascii_comment ; je %ascii_comment # deal all ascii less than 0 - 483D 30000000 ; CMPI32_RAX %0x30 - 0F8C %ascii_other ; JL32 %ascii_other + 483D 30000000 ; cmp_rax, %0x30 + 0F8C %ascii_other ; jl %ascii_other # deal with 0-9 - 483D 3A000000 ; CMPI32_RAX %0x3a - 0F8C %ascii_num ; JL32 %ascii_num + 483D 3A000000 ; cmp_rax, %0x3a + 0F8C %ascii_num ; jl %ascii_num # deal with all ascii less than A - 483D 41000000 ; CMPI32_RAX %0x41 - 0F8C %ascii_other ; JL32 %ascii_other + 483D 41000000 ; cmp_rax, %0x41 + 0F8C %ascii_other ; jl %ascii_other # deal with A-F - 483D 47000000 ; CMPI32_RAX %0x47 - 0F8C %ascii_high ; JL32 %ascii_high + 483D 47000000 ; cmp_rax, %0x47 + 0F8C %ascii_high ; jl %ascii_high # deal with all ascii less than a - 483D 61000000 ; CMPI32_RAX %0x61 - 0F8C %ascii_other ; JL32 %ascii_other + 483D 61000000 ; cmp_rax, %0x61 + 0F8C %ascii_other ; jl %ascii_other # deal with a-f - 483D 67000000 ; CMPI32_RAX %0x67 - 0F8C %ascii_low ; JL32 %ascii_low + 483D 67000000 ; cmp_rax, %0x67 + 0F8C %ascii_low ; jl %ascii_low # The rest that remains needs to be ignored - E9 %ascii_other ; JMP32 %ascii_other + E9 %ascii_other ; jmp %ascii_other :Second_pass - E8 %Read_byte ; CALLI32 %Read_byte + E8 %Read_byte ; call %Read_byte # Deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 %Second_pass_done ; JE32 %Second_pass_done + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 %Second_pass_done ; je %Second_pass_done # Simply drop the label - 483D 3A000000 ; CMPI32_RAX %0x3a - 0F85 %Second_pass_0 ; JNE32 %Second_pass_0 + 483D 3A000000 ; cmp_rax, %0x3a + 0F85 %Second_pass_0 ; jne %Second_pass_0 - E8 %Read_byte ; CALLI32 %Read_byte - E9 %Second_pass ; JMP32 %Second_pass + E8 %Read_byte ; call %Read_byte + E9 %Second_pass ; jmp %Second_pass :Second_pass_0 # Deal with % pointer - 483D 25000000 ; CMPI32_RAX %0x25 - 0F85 %Second_pass_1 ; JNE32 %Second_pass_1 + 483D 25000000 ; cmp_rax, %0x25 + 0F85 %Second_pass_1 ; jne %Second_pass_1 - E8 %StorePointer ; CALLI32 %StorePointer - E9 %Second_pass ; JMP32 %Second_pass + E8 %StorePointer ; call %StorePointer + E9 %Second_pass ; jmp %Second_pass :Second_pass_1 # Deal with everything else - E8 %hex ; CALLI32 %hex # Process our char + E8 %hex ; call %hex # Process our char # Deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 %Second_pass_done ; JE32 %Second_pass_done + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 %Second_pass_done ; je %Second_pass_done # deal with -1 values - 483D 00000000 ; CMPI32_RAX %0 - 0F8C %Second_pass ; JL32 %Second_pass + 483D 00000000 ; cmp_rax, %0 + 0F8C %Second_pass ; jl %Second_pass # deal with toggle - 4981FF 00000000 ; CMPI32_R15 %0 - 0F84 %print ; JE32 %print + 4981FF 00000000 ; cmp_r15, %0 + 0F84 %print ; je %print # process first byte of pair - 4989C6 ; COPY_RAX_to_R14 - 49C7C7 00000000 ; LOADI32_R15 %0 - E9 %Second_pass ; JMP32 %Second_pass + 4989C6 ; mov_r14,rax + 49C7C7 00000000 ; mov_r15, %0 + E9 %Second_pass ; jmp %Second_pass :Second_pass_done - C3 ; RET - :EOF - C3 ; RET + C3 ; ret :ascii_num - 4883E8 30 ; SUBI8_from_RAX !0x30 - C3 ; RET + 4883E8 30 ; sub_rax, !0x30 + C3 ; ret :ascii_low - 4883E8 57 ; SUBI8_from_RAX !0x57 - C3 ; RET + 4883E8 57 ; sub_rax, !0x57 + C3 ; ret :ascii_high - 4883E8 37 ; SUBI8_from_RAX !0x37 - C3 ; RET + 4883E8 37 ; sub_rax, !0x37 + C3 ; ret :ascii_other - 48C7C0 FFFFFFFF ; LOADI32_RAX %-1 - C3 ; RET + 48C7C0 FFFFFFFF ; mov_rax, %-1 + C3 ; ret :ascii_comment - E8 %Read_byte ; CALLI32 %Read_byte - 483D 0D000000 ; CMPI32_RAX %0xd - 0F84 %ascii_comment_cr ; JE32 %ascii_comment_cr - 483D 0A000000 ; CMPI32_RAX %0xa - 0F85 %ascii_comment ; JNE32 %ascii_comment + E8 %Read_byte ; call %Read_byte + 483D 0D000000 ; cmp_rax, %0xd + 0F84 %ascii_comment_cr ; je %ascii_comment_cr + 483D 0A000000 ; cmp_rax, %0xa + 0F85 %ascii_comment ; jne %ascii_comment :ascii_comment_cr - 48C7C0 FFFFFFFF ; LOADI32_RAX %-1 - C3 ; RET + 48C7C0 FFFFFFFF ; mov_rax, %-1 + C3 ; ret # process second byte of pair :print # update the sum and store in output - 49C1E6 04 ; SHL8_R14 !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 - 48C7C2 01000000 ; LOADI32_RDX %1 # set the size of chars we want - E8 %print_chars ; CALLI32 %print_chars + 48C7C2 01000000 ; mov_rdx, %1 # set the size of chars we want + E8 %print_chars ; call %print_chars - 4981C5 01000000 ; ADDI32_to_R13 %1 # Increment IP - E9 %Second_pass ; JMP32 %Second_pass + 4981C5 01000000 ; add_r13, %1 # Increment IP + E9 %Second_pass ; jmp %Second_pass :Read_byte - 4889F9 ; COPY_RDI_to_RCX # arg1 = fin - 6A 01 ; PUSH !1 # size = 1 - 4889E2 ; COPY_RSP_to_RDX # arg2 = &size - 56 ; PUSH_RSI # allocate stack - 4989E0 ; COPY_RSP_to_R8 # arg3 = &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 + 4889F9 ; mov_rcx,rdi # arg1 = fin + 6A 01 ; push !1 # size = 1 + 4889E2 ; mov_rdx,rsp # arg2 = &size + 31F6 ; xor_esi,esi # zero rsi + 56 ; push_rsi # allocate stack + 4989E0 ; mov_r8,rsp # 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 # If the file ended (0 bytes read) return EOF - 85F6 ; TEST_ESI_ESI # if size = 0 - 75 !Read_byte_1 ; JNE8 !Read_byte_1 - 48C7C0 FCFFFFFF ; LOADI32_RAX %-4 # Put EOF in rax + 85F6 ; test_esi,esi # if size = 0 + 75 !Read_byte_1 ; jne8 !Read_byte_1 + 48C7C0 FCFFFFFF ; mov_rax, %-4 # Put EOF in rax :Read_byte_1 - C3 ; RET # return + C3 ; ret # return # Writes bytes stored in rax :print_chars - 4889D9 ; COPY_RBX_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 + 4889D9 ; mov_rcx,rbx # arg1 = fout + 52 ; push_rdx # set size + 4889E2 ; mov_rdx,rsp # arg2 = &size + 50 ; push_rax # allocate stack + 4989E0 ; mov_r8,rsp # 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 - C3 ; RET # return + C3 ; ret # return :Get_table_target - E8 %Read_byte ; CALLI32 %Read_byte # Get single char label - 48C1E0 03 ; SHL8_RAX !3 # Each label in table takes 8 bytes to store - 488B0D %table ; LOAD64_rel_RCX %table # Get table - 4801C8 ; ADD_RCX_to_RAX # Calculate offset - C3 ; RET + E8 %Read_byte ; call %Read_byte # Get single char label + 48C1E0 03 ; shl_rax, !3 # Each label in table takes 8 bytes to store + 488B4C24 18 ; mov_rcx,[rsp+BYTE] !24 # Get table + 4801C8 ; add_rax,rcx # Calculate offset + C3 ; ret :StoreLabel - E8 %Get_table_target ; CALLI32 %Get_table_target - 4C8928 ; STORE32_R13_to_Address_in_RAX # Write out pointer to table - C3 ; RET + E8 %Get_table_target ; call %Get_table_target + 4C8928 ; mov_[rax],r13 # Write out pointer to table + C3 ; ret :StorePointer - 4981C5 04000000 ; ADDI32_to_R13 %4 # Increment IP - E8 %Get_table_target ; CALLI32 %Get_table_target # Get address of pointer - 678B00 ; LOAD32_Address_in_RAX_into_RAX # Get pointer - 4C29E8 ; SUB_R13_from_RAX # target - ip - 48C7C2 04000000 ; LOADI32_RDX %4 # set the size of chars we want - E8 %print_chars ; CALLI32 %print_chars - C3 ; RET + 4981C5 04000000 ; add_r13, %4 # Increment IP + E8 %Get_table_target ; call %Get_table_target # Get address of pointer + 488B00 ; mov_rax,[rax] # Get pointer + 4C29E8 ; sub_rax,r13 # target - ip + 48C7C2 04000000 ; mov_rdx, %4 # set the size of chars we want + E8 %print_chars ; call %print_chars + C3 ; ret :Done + 59 ; pop_rcx # restore table + 5E ; pop_rsi # restore rootdir + 415F ; pop_r15 # restore image_handle + 415E ; pop_r14 # restore system->boot + 415D ; pop_r13 # restore root_device + # Free pool - 488B0D %table ; LOAD64_rel_RCX %table # arg1 = table - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 4C8B35 %SystemBoot ; LOAD64_rel_R14 %SystemBoot # get system->boot - 41FF56 48 ; CALL_R14_Immediate8 !72 # system->boot->free_pool(table) + # arg1 = table + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !72 # system->boot->free_pool(table) - 4889F9 ; COPY_RDI_to_RCX # arg1 = fin - FF51 10 ; CALL_RCX_Immediate8 !16 # fin->close() - 4889D9 ; COPY_RBX_to_RCX # arg1 = fout - FF51 10 ; CALL_RCX_Immediate8 !16 # fout->close() + 4889F9 ; mov_rcx,rdi # arg1 = fin + FF51 10 ; call_[rcx+BYTE] !16 # fin->close() + 4889D9 ; mov_rcx,rbx # arg1 = fout + FF51 10 ; call_[rcx+BYTE] !16 # fout->close() + 4889F1 ; mov_rcx,rsi # arg1 = rootdir + FF51 10 ; call_[rcx+BYTE] !16 # rootdir->close() - 4889EC ; COPY_RBP_to_RSP # restore stack - C3 ; RET # return to UEFI + 4D89F8 ; mov_r8,r15 # arg3 = image_handle + 488D15 %SIMPLE_FS_PROTOCOL ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 4C89E9 ; mov_rcx,r13 # arg1 = root_device + 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(root_device, &guid, image_handle, 0) + + 4D89F8 ; mov_r8,r15 # arg3 = image_handle + 488D15 %LOADED_IMAGE_PROTOCOL ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4C89C1 ; mov_rcx,r8 # arg1 = image_handle + 4D31C9 ; xor_r9,r9 # arg4 = NULL + 41FF96 20010000 ; call_[r14+DWORD] %288 # system->boot->close_protocol(image_handle, &guid, image_handle, 0) + + 4889EC ; mov_rsp,rbp # restore stack + C3 ; ret # return to UEFI # Protocol GUIDs @@ -381,20 +394,12 @@ A1 31 1B 5B ; %0x5b1b31a1 62 95 ; @0x9562 D2 11 ; @0x11d2 -:LOADED_IMAGE_PROTOCOL_8 8E 3F 00 A0 C9 69 72 3B ; !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b :SIMPLE_FS_PROTOCOL 22 5B 4E 96 ; %0x0964e5b22 59 64 ; @0x6459 D2 11 ; @0x11d2 -:SIMPLE_FS_PROTOCOL_8 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -:table - 00000000 00000000 - -:SystemBoot - 00000000 00000000 - :PE32_end diff --git a/amd64/Development/hex2.M1 b/amd64/Development/hex2.M1 index 4e0e38c..9d0c2cb 100644 --- a/amd64/Development/hex2.M1 +++ b/amd64/Development/hex2.M1 @@ -63,6 +63,10 @@ DEFINE mov_al,[rsi] 8A06 DEFINE mov_bl,[rdi] 8A1F DEFINE mov_rcx,[rbx] 488B0B DEFINE mov_rcx,[rcx] 488B09 +DEFINE mov_[rax],r11 4C8918 +DEFINE mov_[rbx], C603 +DEFINE mov_[rbx],al 8803 +DEFINE mov_[rbx],rcx 48890B DEFINE mov_rax,[rcx+BYTE] 488B41 DEFINE mov_rbx,[rdi+BYTE] 488B5F DEFINE mov_rcx,[rdi+BYTE] 488B4F @@ -80,10 +84,6 @@ 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 diff --git a/amd64/Development/hex2.S b/amd64/Development/hex2.S index 5248cb9..7b0953f 100644 --- a/amd64/Development/hex2.S +++ b/amd64/Development/hex2.S @@ -36,7 +36,7 @@ _start: 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 + mov [rip+root_device], rcx # save root_device call open_protocol # open protocol mov rcx, rax # get rootfs diff --git a/amd64/hex1.hex0 b/amd64/hex1.hex0 index fbb9a38..93e7e8d 100644 --- a/amd64/hex1.hex0 +++ b/amd64/hex1.hex0 @@ -120,9 +120,9 @@ F0 00 # SizeOfOptionalHeader # [0x148] # Start of section headers 00 00 00 00 00 00 00 00 ; Name of the section (empty) but could set to ".text" -D4 03 00 00 ; VirtualSize +CF 03 00 00 ; VirtualSize 00 10 00 00 ; VirtualAddress -D4 03 00 00 ; SizeOfRawData +CF 03 00 00 ; SizeOfRawData 70 01 00 00 ; PointerToRawData 00 00 00 00 ; PointerToRelocations 00 00 00 00 ; PointerToLinenumbers @@ -134,396 +134,401 @@ D4 03 00 00 ; SizeOfRawData # 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 BB030000 ; STORE64_rel_R14 %SystemBoot # save system->boot - - # Allocate pool for single-character label table - 52 ; PUSH_RDX # allocate stack for table - 4989E0 ; COPY_RSP_to_R8 # arg3 = &table - 31D2 ; XOR_EDX_EDX # zero rdx - B6 08 ; LOADI8_DH !0x8 # arg2 = 256 * 8 = 2048 = 0x800 - 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, &table) - 4883C4 18 ; ADDI8_RSP !24 # deallocate stack - 58 ; POP_RAX # get table - 488905 94030000 ; STORE64_rel_RAX %table # save table + 4889E5 ; mov_rbp,rsp # save stack pointer + 4989CF ; mov_r15,rcx # save image_handle + 4C8B72 60 ; mov_r14,[rdx+BYTE] !96 # system->boot # Open Loaded Image protocol - 50 ; PUSH_RAX # allocate stack for image - 4989E0 ; COPY_RSP_to_R8 # arg3 = &image - 488B15 71030000 ; 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 61030000 ; 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 - -# :loop_options1 [_start+0x68] # Skip application name - 4883C3 02 ; ADDI8_RBX !2 # ++options - 8A03 ; LOAD8_AL_from_Address_RBX # *options - 3C 20 ; CMPI8_AL !0x20 # if *options != ' ' - 75 F6 ; JNE8 !loop_options1 # then jump - - 4883C3 02 ; ADDI8_RBX !2 # ++options - 4989DC ; COPY_RBX_to_R12 # save input file - -# :loop_options2 [_start+0x79] # Skip argv[1] - 4883C3 02 ; ADDI8_RBX !2 # ++options - 8A03 ; LOAD8_AL_from_Address_RBX # *options - 3C 20 ; CMPI8_AL !0x20 # if *options != ' ' - 75 F6 ; JNE8 !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 + 4D89F9 ; mov_r9,r15 # arg4 = image_handle + 488D15 9B030000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4C89C9 ; mov_rcx,r9 # arg1 = image_handle + 50 ; push_rax # allocate stack for image + 4989E0 ; mov_r8,rsp # arg3 = &image + 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(image_handle, &guid, &image, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + 488B7C24 30 ; mov_rdi,[rsp+BYTE] !48 # save image # Get root file system - 50 ; PUSH_RAX # allocate stack for rootfs - 4989E0 ; COPY_RSP_to_R8 # arg3 = &rootfs - 488B15 24030000 ; 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 14030000 ; 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 + 4D89F9 ; mov_r9,r15 # arg4 = image_handle + 488D15 86030000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 488B4F 18 ; mov_rcx,[rdi+BYTE] !24 # arg1 = root_device = image->device + 4989CD ; mov_r13,rcx # save root_device + 50 ; push_rax # allocate stack for rootfs + 4989E0 ; mov_r8,rsp # arg3 = &rootfs + 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(root_device, &guid, &rootfs, image_handle, 0, EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL) + 488B4C24 30 ; mov_rcx,[rsp+BYTE] !48 # 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 - 415E ; POP_R14 # save rootdir + 50 ; push_rax # allocate stack for rootdir + 4889E2 ; mov_rdx,rsp # 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 + 5E ; pop_rsi # save rootdir + + # Push command line arguments onto stack + 488B5F 38 ; mov_rbx,[rdi+BYTE] !56 # options = image->load_options + 4889DA ; mov_rdx,rbx # save beginning of load_options + 48035F 30 ; add_rbx,[rdi+BYTE] !48 # go to the end of load_options + 6A 00 ; push !0 # Save end of arguments (NULL) onto stack +# :loop_options + 4839D3 ; cmp_rbx,rdx # Check if we are done + 74 14 ; je8 !loop_options_done # We are done + 4883EB 02 ; sub_rbx, !2 # --options + 8A03 ; mov_al,[rbx] # *options + 3C 20 ; cmp_al, !0x20 # if *options != ' ' + 75 F1 ; jne8 !loop_options # then continue looping + C603 00 ; mov_[rbx], !0 # zero it + 4883C3 02 ; add_rbx, !2 # ++options + 53 ; push_rbx # push another argument onto stack + EB E7 ; jmp8 !loop_options # next argument +# :loop_options_done # 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 - 4C89F1 ; COPY_R14_to_RCX # arg1 = rootdir - 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function - FF51 08 ; CALL_RCX_Immediate8 !8 # rootdir->open() - 488B7C24 28 ; LOAD64_into_RDI_from_Address_RSP_Immediate8 !40 # get fin + 4158 ; pop_r8 # arg3 = in + 52 ; push_rdx # allocate stack for fin + 4889E2 ; mov_rdx,rsp # arg2 = &fin + 6A 01 ; push !1 # arg5 = EFI_FILE_READ_ONLY + 6A 01 ; push !1 # prepare to set arg4 to EFI_FILE_MODE_READ + 4159 ; pop_r9 # arg4 = EFI_FILE_MODE_READ + 4889F1 ; mov_rcx,rsi # 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 + 5F ; pop_rdi # get fin # 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 - 4C89F1 ; COPY_R14_to_RCX # arg1 = rootdir - 4883EC 20 ; SUBI8_RSP !32 # allocate shadow stack space for UEFI function - FF51 08 ; CALL_RCX_Immediate8 !8 # rootdir->open() - 488B5C24 28 ; LOAD64_into_RBX_from_Address_RSP_Immediate8 !40 # get fout + 4158 ; pop_r8 # arg3 = out + 52 ; push_rdx # allocate stack for fout + 4889E2 ; mov_rdx,rsp # 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 + 4889F1 ; mov_rcx,rsi # 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 + 5B ; pop_rbx # get fout -# [_start+0x107] - 49C7C7 FFFFFFFF ; LOADI32_R15 %-1 # Our flag for byte processing - 49C7C6 00000000 ; LOADI32_R14 %0 # temp storage for the sum - 49C7C5 00000000 ; LOADI32_R13 %0 # Our starting IP - E8 2B000000 ; CALLI32 %First_pass # Process it + # Save variables that are needed for cleanup + 4155 ; push_r13 # save root_device + 4156 ; push_r14 # save system->boot + 4157 ; push_r15 # save image_handle + 56 ; push_rsi # save rootdir + + # Allocate pool for single-character label table + # pointer to table will be stored at the top of the stack + 52 ; push_rdx # allocate stack for table + 4989E0 ; mov_r8,rsp # arg3 = &table + 31D2 ; xor_edx,edx # zero rdx + B6 08 ; mov_dh, !0x8 # arg2 = 256 * 8 = 2048 = 0x800 + 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, &table) + 4883C4 18 ; add_rsp, !24 # deallocate stack + +# [_start+0xe1] + 49C7C7 FFFFFFFF ; mov_r15, %-1 # Our flag for byte processing + 49C7C6 00000000 ; mov_r14, %0 # temp storage for the sum + 49C7C5 00000000 ; mov_r13, %0 # Our starting IP + E8 2B000000 ; call %First_pass # Process it # rewind input file - 4889F9 ; COPY_RDI_to_RCX # 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 + 4889F9 ; mov_rcx,rdi # 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 - 49C7C7 FFFFFFFF ; LOADI32_R15 %-1 # Our flag for byte processing - 49C7C6 00000000 ; LOADI32_R14 %0 # temp storage for the sum - 49C7C5 00000000 ; LOADI32_R13 %0 # Our starting IP - E8 EF000000 ; 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 00000000 ; mov_r13, %0 # Our starting IP + E8 EF000000 ; call %Second_pass # Process it - E9 35020000 ; JMP32 %Done + E9 34020000 ; jmp %Done -# :First_pass [_start+0x14C] - E8 BB010000 ; CALLI32 %Read_byte +# :First_pass [_start+0x126] + E8 BA010000 ; call %Read_byte # Deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 67000000 ; JE32 %First_pass_done + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 67000000 ; je %First_pass_done # Check for : - 483D 3A000000 ; CMPI32_RAX %0x3a - 0F85 05000000 ; JNE32 %First_pass_0 + 483D 3A000000 ; cmp_rax, %0x3a + 0F85 05000000 ; jne %First_pass_0 # Deal with label - E8 EB010000 ; CALLI32 %StoreLabel + E8 EA010000 ; call %StoreLabel -# :First_pass_0 [_start+0x16E] +# :First_pass_0 [_start+0x148] # Check for % - 483D 25000000 ; CMPI32_RAX %0x25 - 0F84 39000000 ; JE32 %First_pass_pointer + 483D 25000000 ; cmp_rax, %0x25 + 0F84 39000000 ; je %First_pass_pointer # Deal with everything else - E8 46000000 ; CALLI32 %hex # Process our char + E8 46000000 ; call %hex # Process our char # Deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 39000000 ; JE32 %First_pass_done + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 39000000 ; je %First_pass_done # deal with -1 values - 483D 00000000 ; CMPI32_RAX %0 - 0F8C B5FFFFFF ; JL32 %First_pass + 483D 00000000 ; cmp_rax, %0 + 0F8C B5FFFFFF ; jl %First_pass # deal with toggle - 4981FF 00000000 ; CMPI32_R15 %0 - 0F84 07000000 ; JE32 %First_pass_1 - 4981C5 01000000 ; ADDI32_to_R13 %1 # Increment IP + 4981FF 00000000 ; cmp_r15, %0 + 0F84 07000000 ; je %First_pass_1 + 4981C5 01000000 ; add_r13, %1 # Increment IP -# :First_pass_1 [_start+0xAB] - 49F7D7 ; NOT_R15 - E9 99FFFFFF ; JMP32 %First_pass +# :First_pass_1 [_start+0x185] + 49F7D7 ; not_r15 + E9 99FFFFFF ; jmp %First_pass -# :First_pass_pointer [_start+0x1B3] +# :First_pass_pointer [_start+0x18D] # Deal with Pointer to label - E8 54010000 ; CALLI32 %Read_byte # Drop the char - 4981C5 04000000 ; ADDI32_to_R13 %4 # Increment IP - E9 88FFFFFF ; JMP32 %First_pass # Loop again + E8 53010000 ; call %Read_byte # Drop the char + 4981C5 04000000 ; add_r13, %4 # Increment IP + E9 88FFFFFF ; jmp %First_pass # Loop again -# :First_pass_done [_start+0x1C4] - C3 ; RET +# :First_pass_done [_start+0x19E] + C3 ; ret -# :hex [_start+0x1C5] +# :hex [_start+0x19F] # deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 DC000000 ; JE32 %EOF + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 DB000000 ; je %EOF # deal with line comments starting with # - 483D 23000000 ; CMPI32_RAX %0x23 - 0F84 E8000000 ; JE32 %ascii_comment + 483D 23000000 ; cmp_rax, %0x23 + 0F84 E7000000 ; je %ascii_comment # deal with line comments starting with ; - 483D 3B000000 ; CMPI32_RAX %0x3b - 0F84 DC000000 ; JE32 %ascii_comment + 483D 3B000000 ; cmp_rax, %0x3b + 0F84 DB000000 ; je %ascii_comment # deal all ascii less than 0 - 483D 30000000 ; CMPI32_RAX %0x30 - 0F8C C8000000 ; JL32 %ascii_other + 483D 30000000 ; cmp_rax, %0x30 + 0F8C C7000000 ; jl %ascii_other # deal with 0-9 - 483D 3A000000 ; CMPI32_RAX %0x3a - 0F8C AD000000 ; JL32 %ascii_num + 483D 3A000000 ; cmp_rax, %0x3a + 0F8C AC000000 ; jl %ascii_num # deal with all ascii less than A - 483D 41000000 ; CMPI32_RAX %0x41 - 0F8C B0000000 ; JL32 %ascii_other + 483D 41000000 ; cmp_rax, %0x41 + 0F8C AF000000 ; jl %ascii_other # deal with A-F - 483D 47000000 ; CMPI32_RAX %0x47 - 0F8C 9F000000 ; JL32 %ascii_high + 483D 47000000 ; cmp_rax, %0x47 + 0F8C 9E000000 ; jl %ascii_high # deal with all ascii less than a - 483D 61000000 ; CMPI32_RAX %0x61 - 0F8C 98000000 ; JL32 %ascii_other + 483D 61000000 ; cmp_rax, %0x61 + 0F8C 97000000 ; jl %ascii_other # deal with a-f - 483D 67000000 ; CMPI32_RAX %0x67 - 0F8C 82000000 ; JL32 %ascii_low + 483D 67000000 ; cmp_rax, %0x67 + 0F8C 81000000 ; jl %ascii_low # The rest that remains needs to be ignored - E9 87000000 ; JMP32 %ascii_other + E9 86000000 ; jmp %ascii_other -# :Second_pass [_start+0x236] - E8 D1000000 ; CALLI32 %Read_byte +# :Second_pass [_start+0x210] + E8 D0000000 ; call %Read_byte # Deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 65000000 ; JE32 %Second_pass_done + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 65000000 ; je %Second_pass_done # Simply drop the label - 483D 3A000000 ; CMPI32_RAX %0x3a - 0F85 0A000000 ; JNE32 %Second_pass_0 + 483D 3A000000 ; cmp_rax, %0x3a + 0F85 0A000000 ; jne %Second_pass_0 - E8 B4000000 ; CALLI32 %Read_byte - E9 D9FFFFFF ; JMP32 %Second_pass + E8 B3000000 ; call %Read_byte + E9 D9FFFFFF ; jmp %Second_pass -# :Second_pass_0 [_start+0x25D] +# :Second_pass_0 [_start+0x237] # Deal with % pointer - 483D 25000000 ; CMPI32_RAX %0x25 - 0F85 0A000000 ; JNE32 %Second_pass_1 + 483D 25000000 ; cmp_rax, %0x25 + 0F85 0A000000 ; jne %Second_pass_1 - E8 F4000000 ; CALLI32 %StorePointer - E9 C3FFFFFF ; JMP32 %Second_pass + E8 F3000000 ; call %StorePointer + E9 C3FFFFFF ; jmp %Second_pass -# :Second_pass_1 [_start+0x273] +# :Second_pass_1 [_start+0x24D] # Deal with everything else - E8 4DFFFFFF ; CALLI32 %hex # Process our char + E8 4DFFFFFF ; call %hex # Process our char # Deal with EOF - 483D FCFFFFFF ; CMPI32_RAX %-4 - 0F84 28000000 ; JE32 %Second_pass_done + 483D FCFFFFFF ; cmp_rax, %-4 + 0F84 28000000 ; je %Second_pass_done # deal with -1 values - 483D 00000000 ; CMPI32_RAX %0 - 0F8C A6FFFFFF ; JL32 %Second_pass + 483D 00000000 ; cmp_rax, %0 + 0F8C A6FFFFFF ; jl %Second_pass # deal with toggle - 4981FF 00000000 ; CMPI32_R15 %0 - 0F84 4D000000 ; JE32 %print + 4981FF 00000000 ; cmp_r15, %0 + 0F84 4C000000 ; je %print # process first byte of pair - 4989C6 ; COPY_RAX_to_R14 - 49C7C7 00000000 ; LOADI32_R15 %0 + 4989C6 ; mov_r14,rax + 49C7C7 00000000 ; mov_r15, %0 E9 8AFFFFFF ; JMP32 %Second_pass -# :Second_pass_done [_start+0x2AC] - C3 ; RET - -# :EOF [_start+0x2AD] - C3 ; RET -# :ascii_num [_start+0x2AE] - 4883E8 30 ; SUBI8_from_RAX !0x30 - C3 ; RET -# :ascii_low [_start+0x2B3] - 4883E8 57 ; SUBI8_from_RAX !0x57 - C3 ; RET -# :ascii_high [_start+0x2B8] - 4883E8 37 ; SUBI8_from_RAX !0x37 - C3 ; RET -# :ascii_other [_start+0x2BD] - 48C7C0 FFFFFFFF ; LOADI32_RAX %-1 - C3 ; RET -# :ascii_comment [_start+0x2C5] - E8 42000000 ; CALLI32 %Read_byte - 483D 0D000000 ; CMPI32_RAX %0xd - 0F84 0C000000 ; JE32 %ascii_comment_cr - 483D 0A000000 ; CMPI32_RAX %0xa - 0F85 E3FFFFFF ; JNE32 %ascii_comment -# :ascii_comment_cr [_start+0x2E2] - 48C7C0 FFFFFFFF ; LOADI32_RAX %-1 - C3 ; RET +# :Second_pass_done [_start+0x286] +# :EOF + C3 ; ret +# :ascii_num [_start+0x287] + 4883E8 30 ; sub_rax, !0x30 + C3 ; ret +# :ascii_low [_start+0x28C] + 4883E8 57 ; sub_rax, !0x57 + C3 ; ret +# :ascii_high [_start+0x291] + 4883E8 37 ; sub_rax, !0x37 + C3 ; ret +# :ascii_other [_start+0x296] + 48C7C0 FFFFFFFF ; mov_rax, %-1 + C3 ; ret +# :ascii_comment [_start+0x29E] + E8 42000000 ; call %Read_byte + 483D 0D000000 ; cmp_rax, %0xd + 0F84 0C000000 ; je %ascii_comment_cr + 483D 0A000000 ; cmp_rax, %0xa + 0F85 E3FFFFFF ; jne %ascii_comment +# :ascii_comment_cr [_start+0x2BB] + 48C7C0 FFFFFFFF ; mov_rax, %-1 + C3 ; ret # process second byte of pair -# :print [_start+0x2EA] +# :print [_start+0x2C3] # update the sum and store in output - 49C1E6 04 ; SHL8_R14 !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 - 48C7C2 01000000 ; LOADI32_RDX %1 # set the size of chars we want - E8 2F000000 ; CALLI32 %print_chars + 48C7C2 01000000 ; mov_rdx, %1 # set the size of chars we want + E8 31000000 ; call %print_chars - 4981C5 01000000 ; ADDI32_to_R13 %1 # Increment IP - E9 2AFFFFFF ; JMP32 %Second_pass + 4981C5 01000000 ; add_r13, %1 # Increment IP + E9 2BFFFFFF ; jmp %Second_pass -# :Read_byte [_start+0x30C] - 4889F9 ; COPY_RDI_to_RCX # arg1 = fin - 6A 01 ; PUSH !1 # size = 1 - 4889E2 ; COPY_RSP_to_RDX # arg2 = &size - 56 ; PUSH_RSI # allocate stack - 4989E0 ; COPY_RSP_to_R8 # arg3 = &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 +# :Read_byte [_start+0x2E5] + 4889F9 ; mov_rcx,rdi # arg1 = fin + 6A 01 ; push !1 # size = 1 + 4889E2 ; mov_rdx,rsp # arg2 = &size + 31F6 ; xor_esi,esi # zero rsi + 56 ; push_rsi # allocate stack + 4989E0 ; mov_r8,rsp # 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 # If the file ended (0 bytes read) return EOF - 85F6 ; TEST_ESI_ESI # if size = 0 - 75 07 ; JNE8 !Read_byte_1 - 48C7C0 FCFFFFFF ; LOADI32_RAX %-4 # Put EOF in rax + 85F6 ; test_esi,esi # if size = 0 + 75 07 ; jne8 !Read_byte_1 + 48C7C0 FCFFFFFF ; mov_rax, %-4 # Put EOF in rax -# :Read_byte_1 [_start+0x32E] - C3 ; RET # return +# :Read_byte_1 [_start+0x309] + C3 ; ret # return # Writes bytes stored in rax -# :print_chars [_start+0x32F] - 4889D9 ; COPY_RBX_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 +# :print_chars [_start+0x30A] + 4889D9 ; mov_rcx,rbx # arg1 = fout + 52 ; push_rdx # set size + 4889E2 ; mov_rdx,rsp # arg2 = &size + 50 ; push_rax # allocate stack + 4989E0 ; mov_r8,rsp # 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 - C3 ; RET # return + C3 ; ret # return -# :Get_table_target [_start+0x345] - E8 C2FFFFFF ; CALLI32 %Read_byte # Get single char label - 48C1E0 03 ; SHL8_RAX !3 # Each label in table takes 8 bytes to store - 488B0D 6F000000 ; LOAD64_rel_RCX %table # Get table - 4801C8 ; ADD_RCX_to_RAX # Calculate offset - C3 ; RET +# :Get_table_target [_start+0x320] + E8 C0FFFFFF ; call %Read_byte # Get single char label + 48C1E0 03 ; shl_rax, !3 # Each label in table takes 8 bytes to store + 488B4C24 18 ; mov_rcx,[rsp+BYTE] !24 # Get table + 4801C8 ; add_rax,rcx # Calculate offset + C3 ; ret -# :StoreLabel [_start+0x359] - E8 E7FFFFFF ; CALLI32 %Get_table_target - 4C8928 ; STORE32_R13_to_Address_in_RAX # Write out pointer to table - C3 ; RET +# :StoreLabel [_start+0x332] + E8 E9FFFFFF ; call %Get_table_target + 4C8928 ; mov_[rax],r13 # Write out pointer to table + C3 ; ret -# :StorePointer [_start+0x362] - 4981C5 04000000 ; ADDI32_to_R13 %4 # Increment IP - E8 D7FFFFFF ; CALLI32 %Get_table_target # Get address of pointer - 678B00 ; LOAD32_Address_in_RAX_into_RAX # Get pointer - 4C29E8 ; SUB_R13_from_RAX # target - ip - 48C7C2 04000000 ; LOADI32_RDX %4 # set the size of chars we want - E8 AFFFFFFF ; CALLI32 %print_chars - C3 ; RET +# :StorePointer [_start+0x33B] + 4981C5 04000000 ; add_r13, %4 # Increment IP + E8 D9FFFFFF ; call %Get_table_target # Get address of pointer + 488B00 ; mov_rax,[rax] # Get pointer + 4C29E8 ; sub_rax,r13 # target - ip + 48C7C2 04000000 ; mov_rdx, %4 # set the size of chars we want + E8 B1FFFFFF ; call %print_chars + C3 ; ret + +# :Done [_start+0x35A] + 59 ; pop_rcx # restore table + 5E ; pop_rsi # restore rootdir + 415F ; pop_r15 # restore image_handle + 415E ; pop_r14 # restore system->boot + 415D ; pop_r13 # restore root_device -# :Done [_start+0x381] # Free pool - 488B0D 3C000000 ; LOAD64_rel_RCX %table # arg1 = table - 50 ; PUSH_RAX # allocate shadow stack space for UEFI function - 4C8B35 3C000000 ; LOAD64_rel_R14 %SystemBoot # get system->boot - 41FF56 48 ; CALL_R14_Immediate8 !72 # system->boot->free_pool(table) + # arg1 = table + 50 ; push_rax # allocate shadow stack space for UEFI function + 41FF56 48 ; call_[r14+BYTE] !72 # system->boot->free_pool(table) - 4889F9 ; COPY_RDI_to_RCX # arg1 = fin - FF51 10 ; CALL_RCX_Immediate8 !16 # fin->close() - 4889D9 ; COPY_RBX_to_RCX # arg1 = fout - FF51 10 ; CALL_RCX_Immediate8 !16 # fout->close() + 4889F9 ; mov_rcx,rdi # arg1 = fin + FF51 10 ; call_[rcx+BYTE] !16 # fin->close() + 4889D9 ; mov_rcx,rbx # arg1 = fout + FF51 10 ; call_[rcx+BYTE] !16 # fout->close() + 4889F1 ; mov_rcx,rsi # arg1 = rootdir + FF51 10 ; call_[rcx+BYTE] !16 # rootdir->close() - 4889EC ; COPY_RBP_to_RSP # restore stack - C3 ; RET # return to UEFI + 4D89F8 ; mov_r8,r15 # arg3 = image_handle + 488D15 3C000000 ; lea_rdx,[rip+DWORD] %SIMPLE_FS_PROTOCOL # guid = &SIMPLE_FS_PROTOCOL + 4C89E9 ; mov_rcx,r13 # arg1 = root_device + 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(root_device, &guid, image_handle, 0) + + 4D89F8 ; mov_r8,r15 # arg3 = image_handle + 488D15 11000000 ; lea_rdx,[rip+DWORD] %LOADED_IMAGE_PROTOCOL # guid = &LOADED_IMAGE_PROTOCOL + 4C89C1 ; mov_rcx,r8 # arg1 = image_handle + 4D31C9 ; xor_r9,r9 # arg4 = NULL + 41FF96 20010000 ; call_[r14+DWORD] %288 # system->boot->close_protocol(image_handle, &guid, image_handle, 0) + + 4889EC ; mov_rsp,rbp # restore stack + C3 ; ret # return to UEFI # Protocol GUIDs -# :LOADED_IMAGE_PROTOCOL [_start+0x3A4] +# :LOADED_IMAGE_PROTOCOL [_start+0x3AF] A1 31 1B 5B ; %0x5b1b31a1 62 95 ; @0x9562 D2 11 ; @0x11d2 -# :LOADED_IMAGE_PROTOCOL_8 [_start+0x3AC] 8E 3F 00 A0 C9 69 72 3B ; !0x8e !0x3f !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -# :SIMPLE_FS_PROTOCOL [_start+0x3B4] +# :SIMPLE_FS_PROTOCOL [_start+0x3BF] 22 5B 4E 96 ; %0x0964e5b22 59 64 ; @0x6459 D2 11 ; @0x11d2 -# :SIMPLE_FS_PROTOCOL_8 [_start+0x3BC] 8E 39 00 A0 C9 69 72 3B ; !0x8e !0x39 !0 !0xa0 !0xc9 !0x69 !0x72 !0x3b -# :table [_start+0x3C4] - 00000000 00000000 - -# :SystemBoot [_start+0x3CC] - 00000000 00000000 - -# :PE32_end [_start+0x3D4] +# :PE32_end [_start+0x3CF] diff --git a/amd64/mescc-tools-mini-kaem.kaem b/amd64/mescc-tools-mini-kaem.kaem index 41340a7..9aa32d0 100644 --- a/amd64/mescc-tools-mini-kaem.kaem +++ b/amd64/mescc-tools-mini-kaem.kaem @@ -14,7 +14,7 @@ amd64\artifact\hex0.efi amd64\hex1.hex0 amd64\artifact\hex1.efi ################################# # Phase-2 Build hex2 from hex1 # ################################# -amd64\artifact\hex1.efi amd64\hex2.hex1 amd64\artifact\hex2-0.efi +amd64\artifact\hex1.efi amd64\hex2.hex1 amd64\artifact\hex2-0.efi # hex2 adds support for long labels and absolute addresses thus allowing it # to function as an effective linker for later stages of the bootstrap # This is a minimal version which will be used to bootstrap a much more advanced