Page 1 of 1

EFI_INVALID_PARAMETER in return requesting getMemoryMap()

Posted: Tue Mar 14, 2023 3:19 am
by abdo
Hello everyone
I want to request
getMemoryMap()
function using assembly language, it gives me as return
8000000000000002
I use
qemu
emulator to show the result in "BOOTX64.efi" file
This is the code that I use:

Code: Select all

BITS 64
org 0x00100000 ;Space for a small stack?

;**************
;*** HEADER ***
;**************

section .header
DOS_HEADER:
        dw 0x5a4d ;DOS Magic number
   times 29 dw 0 ;Zeroes
   dd 0x00000080 ;Address of PE header

DOS_STUB:
        ; I don't know how to write this as text, so you get zeroes
   times 32 dw 0

PE_HEADER:
        dd 0x00004550 ;PE Magic number
   dw 0x8664 ;Building for x86 architecture
   dw 2 ;Two sections (.text, .data)
   dd 0x632F9A00 ;number of seconds between 00:00:00 1st January 1970 and 00:00:00 1st June 2023
   dd 0x0 ;No symbol table
   dd 0x0 ;No symbols in the non-existent symbol table!
   dw oSize ;The size of the entire optional header. See the OPTIONAL_HEADER_END label for the calculation.
   dw 0x1002 ;Is a valid image file, is a system file. No other fancy characteristics.

oSize equ OPTIONAL_HEADER_END - OPTIONAL_HEADER_STANDARD_FIELDS

OPTIONAL_HEADER_STANDARD_FIELDS: ;Not actually optional
        dw 0x020b ;PE32+ Executable. I want my 64-bit registers!
   dw 0x0 ;What linker?
   dd 1024 ;The size of the code segment
   dd 1024 ;The size of the data segment
   dd 0x0 ;No .bss section. All variables to be initialised.
   dd 1024 ;The program's entry point
   dd 1024 ;The program's first instruction. Same as the start of the code execution.

OPTIONAL_HEADER_WINDOWS_FIELDS: ;
        dq 0x00100000 ;The entry point of the image
   dd 0x1024 ;The section alignment
   dd 0x1024 ;The file alignment
   dw 0x0 ;No operating system requirements
   dw 0x0 ;Stil no operating system requirements
   dw 0x0 ;Major image version number
   dw 0x1 ;Minor image version number
   dw 0x0 ;Major subsystem version. Doesn't matter, as long as it supports UEFI.
   dw 0x0 ;Minor subsystem version. Doesn't matter, as long as it supports UEFI.
   dd 0x0 ;A dedicated zero
   dd 3072 ;Image size
   dd 1024 ;Header size
   dd 0x0 ;Checksum //TODO ADD LATER
   dw 0x000A ;UEFI Subsystem number.
   dw 0x0 ;Not a DLL, so this can be zero

   ;Using PE32+ file type, so the following are dqs, not dds
   dq 0x8000 ;Amount of stack space to reserve
   dq 0x8000 ;Amount of stack space to commit immediately
   dq 0x8000 ;Amount of local heap space to reserve
   dq 0x0 ;Amount of local heap space to commit immediately. Hopefully not needed.
   dd 0x0 ;Another four bytes dedicated to being zeroes
   dd 0x0 ;Number of data dictionary entries

;OPTIONAL_HEADER_DATA_DIRECTORIES: ;

OPTIONAL_HEADER_END: ;This label is required for calculating value of oSize

        SECTION_TABLE: ;as if you don't have enough information already :\
.1: ;text section
   dq `.text` ;The name of the text section
   dd 1024 ;virtual size.
   dd 1024 ;virtual entry point address.
   dd 1024 ;actual size.
   dd 1024 ;actual entry point address.
   dd 0 ;No relocations
   dd 0 ;No line numbers
   dw 0 ;No relocations
   dw 0 ;No line numbers
   dd 0x60000020 ;Contains executable code, can be executed as code, can be read.

.2: ;data section
        dq `.data` ;The name of the data section
   dd 1024 ;virtual size.
   dd 2048 ;virtual entry point address.
   dd 1024 ;actual size.
   dd 2048 ;actual entry point address.
   dd 0 ;No relocations
   dd 0 ;No line numbers
   dw 0 ;No relocations
   dw 0 ;No line numbers
   dd 0xc0000040 ;Contains initialised data, can be read, can be written to.

times 1024 - ($-$$) db 0 ;alignment

;*****************
;*** MAIN CODE ***
;*****************

section .text follows=.header
vars:
        ;Function return codes.
   EFI_SUCCESS equ 0

   ;Offsets for loading function addresses
   OFFSET_TABLE_BOOT_SERVICES equ 96
   OFFSET_TABLE_ERROR_CONSOLE equ 80
   OFFSET_TABLE_OUTPUT_CONSOLE equ 64
   OFFSET_TABLE_RUNTIME_SERVICES equ 88
   OFFSET_BOOT_EXIT_PROGRAM equ 216
   OFFSET_BOOT_STALL equ 248
   OFFSET_CONSOLE_OUTPUT_STRING equ 8

start:
        sub rsp, 6*8+8 
        mov [r_RDX], rdx
        mov [r_RCX], rcx
        mov rcx, [rdx+OFFSET_TABLE_BOOT_SERVICES]
        mov rax, [rcx+40]
        mov rcx, pointerSize ; first argument
        call rax
        call reg_to_hex ; show function's return value
        
        jmp $
; --------- read register's content in hex
reg_to_hex:
        ; rax is argument of the content 
        ; 'quadword' that we want to show
        push rsi
        push rdi
        push rbx
        mov rdi, reg_hex_converted
        mov rcx, 64
        .loop:
                push rax
                sub rcx, 4
                sar rax, cl
                and rax, 0xf
                lea rsi, [codes + rax]
                mov rbx, 0
                mov byte bl, [rsi]
                mov word [rdi], bx
                add rdi, 2
                pop rax
                test rcx, rcx
                jnz .loop
        mov rcx, [r_RDX]
        mov rcx, [rcx + 64]
        mov rax, [rcx+8]
        mov rdx, reg_hex_converted
        call rax
        pop rbx
        pop rdi
        pop rsi
        ret

; ----------------------------------------
times 1024 - ($-$$) db 0 ;alignment
    

;************
;*** DATA ***
;************

section .data follows=.text

dataStart:
    r_RDX: dq 0
    r_RCX: dq 0
    r_RAX: dq 0
    reg_hex_converted: db __utf16__ `XXXXXXXXXXXXXXXX\r\n\0`
    codes: db '0123456789ABCDEF'
    pointerSize: dq 4096
times 1024 - ($-$$) db 0 ;alignment
Please, can you tell me where is the problem here !?

Re: EFI_INVALID_PARAMETER in return requesting getMemoryMap(

Posted: Mon Apr 03, 2023 6:29 pm
by Octocontrabass

Code: Select all

   dd 0 ;No relocations
   dw 0 ;No relocations
   dd 0 ;No relocations
   dw 0 ;No relocations
EFI binaries must be relocatable. Your code has absolute addresses without relocations, so your binary will fail on some PCs.

Code: Select all

        mov rax, [rcx+40]
That's AllocatePages(), not GetMemoryMap().

Code: Select all

        mov rcx, pointerSize ; first argument
Where are the other arguments?

Re: EFI_INVALID_PARAMETER in return requesting getMemoryMap(

Posted: Mon Apr 03, 2023 6:59 pm
by zaval

Code: Select all

    dd 0x1024 ;The section alignment
    dd 0x1024 ;The file alignment
uhm, really?

it's actually a miracle, this thing even got to the function call and getting its result, I'd say, it shouldn't be even started. kudos to EDK2/OVMF for tolerating such an abysmal piece. I got lost, trying to find ImageBase in that mess. you are not supposed to make PE constructing manually. and you can't as can be easily seen. your nasm or whateverasm can do it for you. at least for x64.
Please, can you tell me where is the problem here !?
if you ask. but don't get offended. the problem is in the whole file. threw it away. learn UEFI, get/make UEFI headers and write your loader in C, because no offense, it didn't work out in assembly with you (and trying to be funny/overly selfconfident in comments doesn't help with writing correct programs). I'd be embarrassed to show such files publicly, even though I think of myself as of a lamer.