Out of bounds read fix
This commit is contained in:
@@ -178,6 +178,7 @@ EXTERN_C
|
|||||||
UINT32
|
UINT32
|
||||||
DomitoGetPortableExecutableDigestKind(
|
DomitoGetPortableExecutableDigestKind(
|
||||||
_In_ PUCHAR pPeBytes,
|
_In_ PUCHAR pPeBytes,
|
||||||
|
_In_ ULONG PeSize,
|
||||||
_In_ PIMAGE_DATA_DIRECTORY pImgDataDirectory
|
_In_ PIMAGE_DATA_DIRECTORY pImgDataDirectory
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -20,16 +20,25 @@ _IRQL_requires_max_(DISPATCH_LEVEL)
|
|||||||
UINT32
|
UINT32
|
||||||
DomitoGetPortableExecutableDigestKind(
|
DomitoGetPortableExecutableDigestKind(
|
||||||
_In_ PUCHAR pPeBytes,
|
_In_ PUCHAR pPeBytes,
|
||||||
|
_In_ ULONG PeSize,
|
||||||
_In_ PIMAGE_DATA_DIRECTORY pImgDataDirectory
|
_In_ PIMAGE_DATA_DIRECTORY pImgDataDirectory
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!pImgDataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress)
|
const ULONG securityRva = pImgDataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
|
||||||
|
|
||||||
|
if (!securityRva)
|
||||||
{
|
{
|
||||||
return CALG_SHA1;
|
return CALG_SHA1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PVOID pBase = pPeBytes + pImgDataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
|
if (securityRva > PeSize || (PeSize - securityRva) < sizeof(WIN_CERTIFICATE))
|
||||||
|
{
|
||||||
|
return CALG_SHA1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PVOID pBase = pPeBytes + securityRva;
|
||||||
const LPWIN_CERTIFICATE pCert = (WIN_CERTIFICATE*)pBase;
|
const LPWIN_CERTIFICATE pCert = (WIN_CERTIFICATE*)pBase;
|
||||||
|
const ULONG searchLen = min(pCert->dwLength, PeSize - securityRva);
|
||||||
PUCHAR pMatch = NULL;
|
PUCHAR pMatch = NULL;
|
||||||
|
|
||||||
if (NT_SUCCESS(DomitoMemorySearchPattern(
|
if (NT_SUCCESS(DomitoMemorySearchPattern(
|
||||||
@@ -37,7 +46,7 @@ DomitoGetPortableExecutableDigestKind(
|
|||||||
0x00,
|
0x00,
|
||||||
15,
|
15,
|
||||||
pBase,
|
pBase,
|
||||||
pCert->dwLength,
|
searchLen,
|
||||||
(PVOID*)&pMatch
|
(PVOID*)&pMatch
|
||||||
)))
|
)))
|
||||||
{
|
{
|
||||||
@@ -49,7 +58,7 @@ DomitoGetPortableExecutableDigestKind(
|
|||||||
0xcc,
|
0xcc,
|
||||||
19,
|
19,
|
||||||
pBase,
|
pBase,
|
||||||
pCert->dwLength,
|
searchLen,
|
||||||
(PVOID*)&pMatch
|
(PVOID*)&pMatch
|
||||||
)))
|
)))
|
||||||
{
|
{
|
||||||
@@ -99,6 +108,11 @@ DomitoCalculatePortableExecutableDigest(
|
|||||||
ULONG resultLength;
|
ULONG resultLength;
|
||||||
ULONG fileOffset = 0;
|
ULONG fileOffset = 0;
|
||||||
|
|
||||||
|
if (PeSize < sizeof(IMAGE_DOS_HEADER))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_IMAGE_NOT_MZ;
|
||||||
|
}
|
||||||
|
|
||||||
const PIMAGE_DOS_HEADER phDos = (IMAGE_DOS_HEADER*)pPeBytes;
|
const PIMAGE_DOS_HEADER phDos = (IMAGE_DOS_HEADER*)pPeBytes;
|
||||||
if (phDos->e_magic != IMAGE_DOS_SIGNATURE)
|
if (phDos->e_magic != IMAGE_DOS_SIGNATURE)
|
||||||
{
|
{
|
||||||
@@ -106,6 +120,11 @@ DomitoCalculatePortableExecutableDigest(
|
|||||||
return STATUS_INVALID_IMAGE_NOT_MZ;
|
return STATUS_INVALID_IMAGE_NOT_MZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (phDos->e_lfanew > PeSize - sizeof(IMAGE_NT_HEADERS))
|
||||||
|
{
|
||||||
|
return STATUS_INVALID_IMAGE_FORMAT;
|
||||||
|
}
|
||||||
|
|
||||||
const PIMAGE_NT_HEADERS phNt = (PIMAGE_NT_HEADERS)(pPeBytes + phDos->e_lfanew);
|
const PIMAGE_NT_HEADERS phNt = (PIMAGE_NT_HEADERS)(pPeBytes + phDos->e_lfanew);
|
||||||
if (phNt->Signature != IMAGE_NT_SIGNATURE)
|
if (phNt->Signature != IMAGE_NT_SIGNATURE)
|
||||||
{
|
{
|
||||||
@@ -167,7 +186,7 @@ DomitoCalculatePortableExecutableDigest(
|
|||||||
//
|
//
|
||||||
// Boring bcrypt boilerplate code
|
// Boring bcrypt boilerplate code
|
||||||
//
|
//
|
||||||
const UINT32 peDigestKind = DomitoGetPortableExecutableDigestKind(pPeBytes, pImgDataDirectory);
|
const UINT32 peDigestKind = DomitoGetPortableExecutableDigestKind(pPeBytes, PeSize, pImgDataDirectory);
|
||||||
|
|
||||||
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(
|
if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(
|
||||||
&hbAlg,
|
&hbAlg,
|
||||||
@@ -275,9 +294,21 @@ DomitoCalculatePortableExecutableDigest(
|
|||||||
//
|
//
|
||||||
// Now hash everything else in the file up to the certificate data.
|
// Now hash everything else in the file up to the certificate data.
|
||||||
//
|
//
|
||||||
ULONG remaining = hasEmbeddedSig
|
ULONG remaining;
|
||||||
? pImgDataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress - fileOffset
|
if (hasEmbeddedSig)
|
||||||
: PeSize - fileOffset;
|
{
|
||||||
|
const ULONG secRva = pImgDataDirectory[IMAGE_DIRECTORY_ENTRY_SECURITY].VirtualAddress;
|
||||||
|
if (secRva < fileOffset)
|
||||||
|
{
|
||||||
|
status = STATUS_INVALID_IMAGE_FORMAT;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
remaining = secRva - fileOffset;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
remaining = (fileOffset <= PeSize) ? (PeSize - fileOffset) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (remaining > 0)
|
while (remaining > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
+6
-1
@@ -213,7 +213,12 @@ DomitoMemorySearchPattern(
|
|||||||
|
|
||||||
*ppMatch = NULL;
|
*ppMatch = NULL;
|
||||||
|
|
||||||
for (SIZE_T i = 0; i < puSize - puLen; i++)
|
if (puLen == 0 || puSize < puLen)
|
||||||
|
{
|
||||||
|
return STATUS_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (SIZE_T i = 0; i + puLen <= puSize; i++)
|
||||||
{
|
{
|
||||||
BOOLEAN found = TRUE;
|
BOOLEAN found = TRUE;
|
||||||
for (SIZE_T j = 0; j < puLen; j++)
|
for (SIZE_T j = 0; j < puLen; j++)
|
||||||
|
|||||||
Reference in New Issue
Block a user