Skip to content

Commit 7b624d1

Browse files
committed
Add second prodid hash for PhGetMappedImageProdIdHeader
1 parent 0ad5517 commit 7b624d1

File tree

2 files changed

+64
-9
lines changed

2 files changed

+64
-9
lines changed

phlib/include/mapimg.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ PhMappedImageRvaToSection(
9393
);
9494

9595
PHLIBAPI
96-
_Success_(return != NULL)
96+
_Must_inspect_result_
97+
_Ret_maybenull_
9798
PVOID
9899
NTAPI
99100
PhMappedImageRvaToVa(
@@ -103,7 +104,8 @@ PhMappedImageRvaToVa(
103104
);
104105

105106
PHLIBAPI
106-
_Success_(return != NULL)
107+
_Must_inspect_result_
108+
_Ret_maybenull_
107109
PVOID
108110
NTAPI
109111
PhMappedImageVaToVa(
@@ -534,6 +536,7 @@ typedef struct _PH_MAPPED_IMAGE_PRODID
534536
//WCHAR Key[PH_PTR_STR_LEN_1];
535537
BOOLEAN Valid;
536538
PPH_STRING Key;
539+
PPH_STRING RawHash;
537540
PPH_STRING Hash;
538541
ULONG NumberOfEntries;
539542
PPH_MAPPED_IMAGE_PRODID_ENTRY ProdIdEntries;

phlib/mapimg.c

Lines changed: 59 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,6 @@ PIMAGE_SECTION_HEADER PhMappedImageRvaToSection(
335335
return NULL;
336336
}
337337

338-
_Success_(return != NULL)
339338
PVOID PhMappedImageRvaToVa(
340339
_In_ PPH_MAPPED_IMAGE MappedImage,
341340
_In_ ULONG Rva,
@@ -358,7 +357,6 @@ PVOID PhMappedImageRvaToVa(
358357
));
359358
}
360359

361-
_Success_(return != NULL)
362360
PVOID PhMappedImageVaToVa(
363361
_In_ PPH_MAPPED_IMAGE MappedImage,
364362
_In_ ULONG Va,
@@ -2343,7 +2341,8 @@ NTSTATUS PhGetMappedImageProdIdHeader(
23432341

23442342
if (richStartSignature == ProdIdTagStart && richEndSignature == ProdIdTagEnd)
23452343
{
2346-
PPH_STRING hashString = NULL;
2344+
PPH_STRING hashRawContentString = NULL;
2345+
PPH_STRING hashContentString = NULL;
23472346
ULONG currentCount = 0;
23482347
PBYTE currentAddress;
23492348
PBYTE currentEnd;
@@ -2362,17 +2361,69 @@ NTSTATUS PhGetMappedImageProdIdHeader(
23622361

23632362
if (PhFinalHash(&hashContext, hash, 16, NULL))
23642363
{
2365-
hashString = PhBufferToHexString(hash, 16);
2364+
hashRawContentString = PhBufferToHexString(hash, 16);
23662365
}
23672366
}
23682367
__except (EXCEPTION_EXECUTE_HANDLER)
23692368
{
23702369
return GetExceptionCode();
23712370
}
23722371

2373-
if (PhIsNullOrEmptyString(hashString))
2372+
if (PhIsNullOrEmptyString(hashRawContentString))
23742373
return STATUS_FAIL_CHECK;
2375-
2374+
2375+
// VT creates a different hash based on the decrypted header while other tools
2376+
// (including this one) create the hash based on the raw header. So create a second hash
2377+
// from the decrypted header so we can show and search both hashes (dmex)
2378+
{
2379+
PVOID richHeaderContentEnd;
2380+
ULONG richHeaderContentLength;
2381+
PULONG richHeaderContentBuffer;
2382+
PULONG richHeaderContentOffset;
2383+
PH_HASH_CONTEXT hashContext;
2384+
UCHAR hash[32];
2385+
2386+
// Recalculate the length needed for the hash since VT doesn't include the remaining entry.
2387+
richHeaderContentEnd = PTR_ADD_OFFSET(MappedImage->ViewBase, richHeaderEndOffset);
2388+
richHeaderContentLength = PtrToUlong(PTR_SUB_OFFSET(richHeaderContentEnd, richHeaderStart));
2389+
2390+
// We already probed above so this isn't really needed but probe again just to be sure.
2391+
__try
2392+
{
2393+
PhpMappedImageProbe(MappedImage, richHeaderStart, richHeaderContentLength);
2394+
}
2395+
__except (EXCEPTION_EXECUTE_HANDLER)
2396+
{
2397+
return GetExceptionCode();
2398+
}
2399+
2400+
richHeaderContentBuffer = PhAllocateZero(richHeaderContentLength);
2401+
memcpy(richHeaderContentBuffer, richHeaderStart, richHeaderContentLength);
2402+
2403+
// Walk the buffer and decrypt the entire thing.
2404+
for (
2405+
richHeaderContentOffset = richHeaderContentBuffer;
2406+
richHeaderContentOffset < (PULONG)PTR_ADD_OFFSET(richHeaderContentBuffer, richHeaderContentLength);
2407+
richHeaderContentOffset++
2408+
)
2409+
{
2410+
*richHeaderContentOffset ^= richHeaderKey;
2411+
}
2412+
2413+
PhInitializeHash(&hashContext, Md5HashAlgorithm);
2414+
PhUpdateHash(&hashContext, richHeaderContentBuffer, richHeaderContentLength);
2415+
2416+
if (PhFinalHash(&hashContext, hash, 16, NULL))
2417+
{
2418+
hashContentString = PhBufferToHexString(hash, 16);
2419+
}
2420+
2421+
PhFree(richHeaderContentBuffer);
2422+
}
2423+
2424+
if (PhIsNullOrEmptyString(hashContentString))
2425+
return STATUS_FAIL_CHECK;
2426+
23762427
// Do a scan to determine how many entries there are.
23772428
for (offset = currentAddress; offset < currentEnd; offset += sizeof(PRODITEM))
23782429
{
@@ -2466,7 +2517,8 @@ NTSTATUS PhGetMappedImageProdIdHeader(
24662517
//PhPrintPointer(ProdIdHeader->Key, UlongToPtr(richHeaderKey));
24672518
ProdIdHeader->Valid = richHeaderKey == richHeaderValue;
24682519
ProdIdHeader->Key = PhFormatString(L"%lx", richHeaderKey);
2469-
ProdIdHeader->Hash = hashString;
2520+
ProdIdHeader->RawHash = hashRawContentString;
2521+
ProdIdHeader->Hash = hashContentString;
24702522
ProdIdHeader->NumberOfEntries = currentCount;
24712523
ProdIdHeader->ProdIdEntries = PhFinalArrayItems(&richHeaderEntryArray);
24722524

0 commit comments

Comments
 (0)