|
1 | 1 | /******************************************************************************* |
2 | 2 | * |
3 | | -* (C) COPYRIGHT AUTHORS, 2020 - 2021 |
| 3 | +* (C) COPYRIGHT AUTHORS, 2020 - 2025 |
4 | 4 | * |
5 | 5 | * TITLE: FUSUTIL.C |
6 | 6 | * |
7 | | -* VERSION: 3.58 |
| 7 | +* VERSION: 3.69 |
8 | 8 | * |
9 | | -* DATE: 01 Dec 2021 |
| 9 | +* DATE: 07 Jul 2025 |
10 | 10 | * |
11 | 11 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF |
12 | 12 | * ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED |
@@ -376,12 +376,18 @@ BOOL fusUtilReferenceStreamByName( |
376 | 376 |
|
377 | 377 | do { |
378 | 378 | pStorStream = (STORAGESTREAM*)streamPtr; |
| 379 | + if (IsBadReadPtr(pStorStream->rcName, sizeof(CHAR))) |
| 380 | + return FALSE; |
| 381 | + |
379 | 382 | if (_strcmpi_a(pStorStream->rcName, StreamName) == 0) { |
380 | 383 | *StreamRef = pStorStream; |
381 | 384 | return TRUE; |
382 | 385 | } |
383 | 386 |
|
384 | 387 | nameLen = _strlen_a(pStorStream->rcName) + 1; |
| 388 | + if (nameLen > MAXUSHORT) |
| 389 | + return FALSE; |
| 390 | + |
385 | 391 | offset = ALIGN_UP(FIELD_OFFSET(STORAGESTREAM, rcName) + nameLen, ULONG); |
386 | 392 | streamPtr = (PBYTE)RtlOffsetToPointer(streamPtr, offset); |
387 | 393 | i++; |
@@ -435,59 +441,62 @@ BOOL fusUtilGetImageMVID( |
435 | 441 | cliHeader = (IMAGE_COR20_HEADER*)RtlImageDirectoryEntryToData(baseAddress, TRUE, |
436 | 442 | IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR, &sz); |
437 | 443 |
|
438 | | - pStorSign = (STORAGESIGNATURE*)RtlOffsetToPointer(baseAddress, cliHeader->MetaData.VirtualAddress); |
439 | | - if (pStorSign->lSignature == STORAGE_MAGIC_SIG) { |
440 | | - |
441 | | - offset = FIELD_OFFSET(STORAGESIGNATURE, pVersion) + pStorSign->iVersionString; |
442 | | - pStorHeader = (STORAGEHEADER*)RtlOffsetToPointer(pStorSign, offset); |
| 444 | + if (cliHeader && sz >= sizeof(IMAGE_COR20_HEADER)) { |
443 | 445 |
|
444 | | - pStreamTables = NULL; |
445 | | - if (!fusUtilReferenceStreamByName(pStorHeader, "#~", &pStreamTables)) { |
446 | | - FreeLibrary(hModule); |
447 | | - return FALSE; |
448 | | - } |
| 446 | + pStorSign = (STORAGESIGNATURE*)RtlOffsetToPointer(baseAddress, cliHeader->MetaData.VirtualAddress); |
| 447 | + if (pStorSign && !IsBadReadPtr(pStorSign, sizeof(STORAGESIGNATURE)) && |
| 448 | + pStorSign->lSignature == STORAGE_MAGIC_SIG) |
| 449 | + { |
| 450 | + offset = FIELD_OFFSET(STORAGESIGNATURE, pVersion) + pStorSign->iVersionString; |
| 451 | + pStorHeader = (STORAGEHEADER*)RtlOffsetToPointer(pStorSign, offset); |
449 | 452 |
|
450 | | - pStreamGuid = NULL; |
451 | | - if (!fusUtilReferenceStreamByName(pStorHeader, "#GUID", &pStreamGuid)) { |
452 | | - FreeLibrary(hModule); |
453 | | - return FALSE; |
454 | | - } |
| 453 | + pStreamTables = NULL; |
| 454 | + if (!fusUtilReferenceStreamByName(pStorHeader, "#~", &pStreamTables)) { |
| 455 | + FreeLibrary(hModule); |
| 456 | + return FALSE; |
| 457 | + } |
455 | 458 |
|
456 | | - pTablesHeader = (STORAGETABLESHEADER*)RtlOffsetToPointer(pStorSign, pStreamTables->iOffset); |
457 | | - sz = 0; |
458 | | - |
459 | | - // |
460 | | - // __popcnt64 or the garbage code below |
461 | | - // |
462 | | - for (i = 0; i < MAX_CLR_TABLES; i++) |
463 | | - if ((i < 32 && (pTablesHeader->Valid.u.LowPart >> i) & 1) || |
464 | | - (i >= 32 && (pTablesHeader->Valid.u.HighPart >> i) & 1)) |
465 | | - { |
466 | | - sz++; |
| 459 | + pStreamGuid = NULL; |
| 460 | + if (!fusUtilReferenceStreamByName(pStorHeader, "#GUID", &pStreamGuid)) { |
| 461 | + FreeLibrary(hModule); |
| 462 | + return FALSE; |
467 | 463 | } |
468 | 464 |
|
469 | | - offset = FIELD_OFFSET(STORAGETABLESHEADER, Rows) + (sz * sizeof(ULONG)); |
| 465 | + pTablesHeader = (STORAGETABLESHEADER*)RtlOffsetToPointer(pStorSign, pStreamTables->iOffset); |
| 466 | + sz = 0; |
| 467 | + |
| 468 | + // |
| 469 | + // __popcnt64 or the garbage code below |
| 470 | + // |
| 471 | + for (i = 0; i < MAX_CLR_TABLES; i++) |
| 472 | + if ((i < 32 && (pTablesHeader->Valid.u.LowPart >> i) & 1) || |
| 473 | + (i >= 32 && (pTablesHeader->Valid.u.HighPart >> i) & 1)) |
| 474 | + { |
| 475 | + sz++; |
| 476 | + } |
470 | 477 |
|
471 | | - tablesPtr = (PBYTE)RtlOffsetToPointer(pTablesHeader, offset); |
472 | | - tablesPtr += sizeof(WORD); |
| 478 | + offset = FIELD_OFFSET(STORAGETABLESHEADER, Rows) + (sz * sizeof(ULONG)); |
473 | 479 |
|
474 | | - if (pTablesHeader->HeapOffsetSizes & MD_STRINGS_BIT) |
475 | | - tablesPtr += sizeof(DWORD); |
476 | | - else |
| 480 | + tablesPtr = (PBYTE)RtlOffsetToPointer(pTablesHeader, offset); |
477 | 481 | tablesPtr += sizeof(WORD); |
478 | 482 |
|
479 | | - if (pTablesHeader->HeapOffsetSizes & MD_GUIDS_BIT) |
480 | | - mvidIndex = *(PULONG)tablesPtr; |
481 | | - else |
482 | | - mvidIndex = *(PUSHORT)tablesPtr; |
| 483 | + if (pTablesHeader->HeapOffsetSizes & MD_STRINGS_BIT) |
| 484 | + tablesPtr += sizeof(DWORD); |
| 485 | + else |
| 486 | + tablesPtr += sizeof(WORD); |
| 487 | + |
| 488 | + if (pTablesHeader->HeapOffsetSizes & MD_GUIDS_BIT) |
| 489 | + mvidIndex = *(PULONG)tablesPtr; |
| 490 | + else |
| 491 | + mvidIndex = *(PUSHORT)tablesPtr; |
483 | 492 |
|
484 | | - if (mvidIndex) { |
485 | | - guidsPtr = (LPGUID)RtlOffsetToPointer(pStorSign, pStreamGuid->iOffset); |
486 | | - RtlCopyMemory(ModuleVersionId, &guidsPtr[mvidIndex - 1], sizeof(GUID)); |
487 | | - bResult = TRUE; |
| 493 | + if (mvidIndex) { |
| 494 | + guidsPtr = (LPGUID)RtlOffsetToPointer(pStorSign, pStreamGuid->iOffset); |
| 495 | + RtlCopyMemory(ModuleVersionId, &guidsPtr[mvidIndex - 1], sizeof(GUID)); |
| 496 | + bResult = TRUE; |
| 497 | + } |
488 | 498 | } |
489 | 499 | } |
490 | | - |
491 | 500 | FreeLibrary(hModule); |
492 | 501 | } |
493 | 502 |
|
|
0 commit comments