UEFI LoadImage不支持的类型 [英] UEFI LoadImage Unsupported Type

查看:247
本文介绍了UEFI LoadImage不支持的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Bootservices.loadImage从内存中加载UEFI应用程序映像.内存中的缓冲区加载了HellowWorld.efi应用程序的二进制内容.当我尝试从内存中加载它时,得到的是不受支持的文件类型.

但是,在运行时挖掘UDK内核时,我发现到处理文件头时,我无法正确地从缓冲区读取内容.他们之前的所有魔术数字都不会对齐,因此它将其视为无法识别的文件格式.但是我一直无法追踪到指向源的指针弄乱的地方.

我猜这个问题在UDK源代码中是inint,所以在我如何调用该函数方面就如此.

代码:

    #define SIZEOF_HELLO_EFI 39679
    UINT8 hexData[SIZEOF_HELLO_EFI] =  {//CONTENTS OF helloworld.efi
  0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
 0xFF, 0xFF, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 
0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 
0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 
0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 
0x6E, 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, 0x6D, 0x6F, 0x64, 0x65, 
0x2E, 0x0D, 0x0D, 0x0A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 
0x45, 0x00, 0x00, 0x4C, 0x01, 0x07, 0x00, 0x24, 0x80, 0x00, 0x00, 0x00, 0x7E, 
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x06, 0x03, 0x0B, 0x01, 0x02, 
0x18, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0xB8, 0x84, 0x00, 
0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
    //CONTINUES FOR MANY MORE BYTES, BUT HERE IS THE HEADER INFO};
void copy_helloefi(UINT8* buff)
{
    int counter = 0;
    while(counter < SIZEOF_HELLO_EFI){
        buff[counter] = hexData[counter];
        counter++;
    }

}

EFI_STATUS
efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
        EFI_BOOT_SERVICES *BootServicesTable;
        UINT8* buff_ptr;
        EFI_STATUS status;
        MEMMAP_DEVICE_PATH mempath[2];
       EFI_HANDLE myLoadedImage = NULL;
        BootServicesTable = SystemTable->BootServices;
        BootServicesTable->AllocatePool(EfiLoaderCode, SIZEOF_HELLO_EFI, (void **)&buff_ptr);
        mempath[0].Header.Type = HARDWARE_DEVICE_PATH;
        mempath[0].Header.SubType = HW_MEMMAP_DP;
        mempath[0].Header.Length[0] = (UINT8)sizeof(MEMMAP_DEVICE_PATH);
        mempath[0].Header.Length[1] = (UINT8)(sizeof(MEMMAP_DEVICE_PATH)>> 8);
        mempath[0].MemoryType = EfiLoaderCode;
        mempath[0].StartingAddress = (UINT32)buff_ptr;
        mempath[0].EndingAddress = (UINT32)(buff_ptr + SIZEOF_HELLO_EFI);

        mempath[1].Header.Type = END_DEVICE_PATH_TYPE;
        mempath[1].Header.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
        mempath[1].Header.Length[0] = (UINT8)sizeof(EFI_DEVICE_PATH);
        mempath[1].Header.Length[1] = (UINT8)(sizeof(EFI_DEVICE_PATH)>> 8);

        copy_helloefi(buff_ptr); //put the contents of helloworld.efi in buffer

        status = BootServicesTable->LoadImage(FALSE, ImageHandle, (EFI_DEVICE_PATH*)&mempath, &buff_ptr, SIZEOF_HELLO_EFI, &myLoadedImage);
        if (EFI_ERROR(status)) {
            Print((CHAR16*)L"Could not LoadImage %r %x \r\n", status, status);
        }
        Print((CHAR16*)L"Loaded Image Handle %x\r\n", myLoadedImage);

        //__debugbreak();
        BootServicesTable->FreePool(buff_ptr);
    return EFI_SUCCESS;
}

我做错了什么? HelloWorld.efi是PE/COFF,如果我直接调用它,它将运行良好,因此我知道它是有效的efi二进制文件.

解决方案

解决了这个问题,正如预期的那样,它很小但很烦人,但希望在此处发布以希望对其他人有所帮助.

修正是将buff_ptr作为无效值*而不是无效值发送给

因此将loadimage的调用更新为:

status = BootServicesTable->LoadImage(FALSE, ImageHandle, 
(EFI_DEVICE_PATH*)&mempath, buff_ptr, SIZEOF_HELLO_EFI, &myLoadedImage);

然后在其后添加它以实际运行加载的图像

status = BootServicesTable->StartImage( myLoadedImage, (UINTN*)NULL, (CHAR16**)NULL);

I am trying to load an UEFI application image from memory using Bootservices.loadImage. The buffer in memory is loaded with the binary contents of the HellowWorld.efi application. When I try to load it from memory I get that is an unsupported filetype.

However in digging through the UDK core while running I find that by the time I get to processing the fileheader I am not reading from my buffer correctly. Theirfore all of the magic numbers don't line up, so it sees it as an unrecognized file format. But I haven't been able to trace where along the way my pointer to my source gets messed up.

Im guessing the problem isint in the UDK source, so its in how i'm calling the function.

Code:

    #define SIZEOF_HELLO_EFI 39679
    UINT8 hexData[SIZEOF_HELLO_EFI] =  {//CONTENTS OF helloworld.efi
  0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
 0xFF, 0xFF, 0x00, 0x00, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 
0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, 0x21, 0xB8, 0x01, 0x4C, 0xCD, 
0x21, 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 
0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 
0x6E, 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, 0x6D, 0x6F, 0x64, 0x65, 
0x2E, 0x0D, 0x0D, 0x0A, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 
0x45, 0x00, 0x00, 0x4C, 0x01, 0x07, 0x00, 0x24, 0x80, 0x00, 0x00, 0x00, 0x7E, 
0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x06, 0x03, 0x0B, 0x01, 0x02, 
0x18, 0x00, 0x4C, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 0xB8, 0x84, 0x00, 
0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
    //CONTINUES FOR MANY MORE BYTES, BUT HERE IS THE HEADER INFO};
void copy_helloefi(UINT8* buff)
{
    int counter = 0;
    while(counter < SIZEOF_HELLO_EFI){
        buff[counter] = hexData[counter];
        counter++;
    }

}

EFI_STATUS
efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
        EFI_BOOT_SERVICES *BootServicesTable;
        UINT8* buff_ptr;
        EFI_STATUS status;
        MEMMAP_DEVICE_PATH mempath[2];
       EFI_HANDLE myLoadedImage = NULL;
        BootServicesTable = SystemTable->BootServices;
        BootServicesTable->AllocatePool(EfiLoaderCode, SIZEOF_HELLO_EFI, (void **)&buff_ptr);
        mempath[0].Header.Type = HARDWARE_DEVICE_PATH;
        mempath[0].Header.SubType = HW_MEMMAP_DP;
        mempath[0].Header.Length[0] = (UINT8)sizeof(MEMMAP_DEVICE_PATH);
        mempath[0].Header.Length[1] = (UINT8)(sizeof(MEMMAP_DEVICE_PATH)>> 8);
        mempath[0].MemoryType = EfiLoaderCode;
        mempath[0].StartingAddress = (UINT32)buff_ptr;
        mempath[0].EndingAddress = (UINT32)(buff_ptr + SIZEOF_HELLO_EFI);

        mempath[1].Header.Type = END_DEVICE_PATH_TYPE;
        mempath[1].Header.SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
        mempath[1].Header.Length[0] = (UINT8)sizeof(EFI_DEVICE_PATH);
        mempath[1].Header.Length[1] = (UINT8)(sizeof(EFI_DEVICE_PATH)>> 8);

        copy_helloefi(buff_ptr); //put the contents of helloworld.efi in buffer

        status = BootServicesTable->LoadImage(FALSE, ImageHandle, (EFI_DEVICE_PATH*)&mempath, &buff_ptr, SIZEOF_HELLO_EFI, &myLoadedImage);
        if (EFI_ERROR(status)) {
            Print((CHAR16*)L"Could not LoadImage %r %x \r\n", status, status);
        }
        Print((CHAR16*)L"Loaded Image Handle %x\r\n", myLoadedImage);

        //__debugbreak();
        BootServicesTable->FreePool(buff_ptr);
    return EFI_SUCCESS;
}

What am I doing wrong? HelloWorld.efi is PE/COFF, and if I directly invoke it it runs fine so I know its a valid efi binary.

解决方案

solved it, as expected it was something small and annoying but posting here to hopefully help others.

Fix was to send it buff_ptr as a void* not a void**

So update the invocation of loadimage to:

status = BootServicesTable->LoadImage(FALSE, ImageHandle, 
(EFI_DEVICE_PATH*)&mempath, buff_ptr, SIZEOF_HELLO_EFI, &myLoadedImage);

Then add this after it to actually run the loaded image

status = BootServicesTable->StartImage( myLoadedImage, (UINTN*)NULL, (CHAR16**)NULL);

这篇关于UEFI LoadImage不支持的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆