VirtualBox

Changeset 68743 in vbox for trunk


Ignore:
Timestamp:
Sep 13, 2017 1:14:39 PM (7 years ago)
Author:
vboxsync
Message:

WINNT/InstallHelper: Resolved a todo; rewritten FileGetArchitecture() to make use of IPRT's RTLdr API to retrieve the architecture and validate the PE signature.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp

    r64292 r68743  
    55
    66/*
    7  * Copyright (C) 2011-2016 Oracle Corporation
     7 * Copyright (C) 2011-2017 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    3131#include <iprt/err.h>
    3232#include <iprt/initterm.h>
     33#include <iprt/ldr.h>
    3334#include <iprt/localipc.h>
    3435#include <iprt/mem.h>
     
    268269    if (SUCCEEDED(hr))
    269270    {
    270         /* See: http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx */
    271         FILE *pFh = fopen(szFile, "rb");
    272         if (pFh)
    273         {
    274             /* Assume the file is invalid. */
    275             hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
    276 
    277             BYTE offPeHdr = 0; /* Absolute offset of PE signature. */
    278 
    279             /* Do some basic validation. */
    280             /* Check for "MZ" header (DOS stub). */
    281             BYTE byBuf[255];
    282             if (   fread(&byBuf, sizeof(BYTE), 2, pFh) == 2
    283                 && !memcmp(&byBuf, "MZ", 2))
    284             {
    285                 /* Seek to 0x3C to get the PE offset. */
    286                 if (!fseek(pFh, 60L /*0x3C*/, SEEK_SET))
     271        RTLDRMOD hLdrMod;
     272        int rc = RTLdrOpen(szFile, RTLDR_O_FOR_VALIDATION, RTLDRARCH_WHATEVER, &hLdrMod);
     273        if (RT_SUCCESS(rc))
     274        {
     275            if (RTLdrGetFormat(hLdrMod) == RTLDRFMT_PE)
     276            {
     277                RTLDRARCH enmLdrArch = RTLdrGetArch(hLdrMod);
     278                switch (enmLdrArch)
    287279                {
    288                     /* Read actual offset of PE signature. */
    289 /** @todo r=bird: You've obviously no clue about the structure you're messing with here.  The field is NOT a BYTE
    290  * field but a int32_t/uint32_t!  The MZ header is defined as IMAGE_DOS_HEADER by windows.h (well, winnt.h), and the
    291  * field you're accessing is e_lfanew.  Please rewrite this hack to use the structures!  (Also, the MZ structure is
    292  * OPTIONAL, just in case you didn't know.)  */
    293 #ifdef DEBUG_andy
    294 # error "Fix this"
    295 #endif
    296                     if (fread(&offPeHdr, sizeof(BYTE), 1, pFh) == 1)
    297                     {
    298                         /* ... and seek to it. */
    299                         if (!fseek(pFh, offPeHdr, SEEK_SET))
    300                         {
    301                             /* Validate PE signature. */
    302                             if (fread(byBuf, sizeof(BYTE), 4, pFh) == 4)
    303                             {
    304                                 if (!memcmp(byBuf, "PE\0\0", 4))
    305                                     hr = S_OK;
    306                             }
    307                         }
    308                     }
     280                    case RTLDRARCH_X86_32:
     281                        pushstring("x86");
     282                        break;
     283
     284                    case RTLDRARCH_AMD64:
     285                        pushstring("amd64");
     286                        break;
     287
     288                    default:
     289                        pushstring("Error: Unknown / invalid architecture");
     290                        break;
    309291                }
    310292            }
    311 
    312             /* Validation successful? */
    313             if (SUCCEEDED(hr))
    314             {
    315                 BYTE offFileHeaderMachineField = offPeHdr + 0x4; /* Skip PE signature. */
    316 
    317                 /** @todo When we need to do more stuff here, we probably should
    318                  *        mmap the file w/ a struct so that we easily could access
    319                  *        all the fixed size stuff. Later. */
    320 
    321                 /* Jump to machine type (first entry, 2 bytes):
    322                  * Use absolute PE offset retrieved above. */
    323                 if (!fseek(pFh, offFileHeaderMachineField, SEEK_SET))
    324                 {
    325                     WORD wMachineType;
    326                     if (fread(&wMachineType, 1,
    327                               sizeof(wMachineType), pFh) == 2)
    328                     {
    329                         switch (wMachineType)
    330                         {
    331                             case 0x14C: /* Intel 86 */
    332                                 pushstring("x86");
    333                                 break;
    334 
    335                             case 0x8664: /* AMD64 / x64 */
    336                                 pushstring("amd64");
    337                                 break;
    338 
    339                             default:
    340                                 hr = __HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
    341                                 break;
    342                         }
    343                     }
    344                     else
    345                         hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
    346                 }
    347                 else
    348                     hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
    349             }
    350 
    351             fclose(pFh);
    352         }
    353         else
    354             hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
    355     }
    356 
    357     if (FAILED(hr))
     293            else
     294                pushstring("Error: Unknown / invalid PE signature");
     295
     296            RTLdrClose(hLdrMod);
     297        }
     298        else
     299        {
     300            char szMsg[64];
     301            RTStrPrintf(szMsg, sizeof(szMsg), "Error: Could not open file: %Rrc", rc);
     302
     303            pushstring(szMsg);
     304        }
     305    }
     306    else
    358307        vboxPushResultAsString(hr);
    359308}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette