- Timestamp:
- Sep 13, 2017 1:14:39 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp
r64292 r68743 5 5 6 6 /* 7 * Copyright (C) 2011-201 6Oracle Corporation7 * Copyright (C) 2011-2017 Oracle Corporation 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 31 31 #include <iprt/err.h> 32 32 #include <iprt/initterm.h> 33 #include <iprt/ldr.h> 33 34 #include <iprt/localipc.h> 34 35 #include <iprt/mem.h> … … 268 269 if (SUCCEEDED(hr)) 269 270 { 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) 287 279 { 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; 309 291 } 310 292 } 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 358 307 vboxPushResultAsString(hr); 359 308 }
Note:
See TracChangeset
for help on using the changeset viewer.