Add reusable certificate and file validation helpers

Fix process-name ownership and module lookup outputs, add explicit SPKI hashing and bounded chain access, and improve WDM integration. Deprecate superseded entry points with migration guidance and align branch code and tests with the library style.
This commit is contained in:
nefarius committed 2026-10-27 00:16:42 +01:00
1 parent 1f4d62ae95
commit a491bbd3f8
32 files changed
+5404 -1136

No files matched your search

+56 -51
View File
@@ -2,7 +2,6 @@
#include <Domito.MinCrypt.h>
/* ___
* / __|___ _ __ _ __ ___ _ _
* | (__/ _ \ ' \| ' \/ _ \ ' \
@@ -12,7 +11,7 @@
//
// Library initialization tasks. Call once in your DriverEntry
//
//
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
@@ -25,7 +24,6 @@ EXTERN_C
void
DomitoShutdown();
/* __ __ __ __ _
* | \/ |___ _ __ ___ _ _ _ _ | \/ |__ _ _ _ __ _ __ _ ___ _ __ ___ _ _| |_
* | |\/| / -_) ' \/ _ \ '_| || | | |\/| / _` | ' \/ _` / _` / -_) ' \/ -_) ' \ _|
@@ -35,34 +33,26 @@ DomitoShutdown();
//
// Allocator function the library uses.
//
typedef
_IRQL_requires_same_
_Function_class_(EVT_DOMITO_ALLOCATE_ROUTINE)
__drv_allocatesMem(mem)
//
typedef _IRQL_requires_same_ _Function_class_(EVT_DOMITO_ALLOCATE_ROUTINE)
__drv_allocatesMem(
mem
)
PVOID
NTAPI
EVT_DOMITO_ALLOCATE_ROUTINE(
_In_ SIZE_T ByteSize
);
EVT_DOMITO_ALLOCATE_ROUTINE(_In_ SIZE_T ByteSize);
typedef EVT_DOMITO_ALLOCATE_ROUTINE* PFN_DOMITO_ALLOCATE_ROUTINE;
//
// Freeing function the library uses.
//
typedef
_IRQL_requires_same_
_Function_class_(EVT_DOMITO_FREE_ROUTINE)
void
NTAPI
EVT_DOMITO_FREE_ROUTINE(
_In_ __drv_freesMem(mem) PVOID Memory
);
//
typedef _IRQL_requires_same_ _Function_class_(EVT_DOMITO_FREE_ROUTINE) void NTAPI
EVT_DOMITO_FREE_ROUTINE(_In_ __drv_freesMem(mem) PVOID Memory);
typedef EVT_DOMITO_FREE_ROUTINE* PFN_DOMITO_FREE_ROUTINE;
//
// Get the original set of Domito memory functions.
//
//
EXTERN_C
void
DomitoGetOriginalMemoryFunctions(
@@ -72,7 +62,7 @@ DomitoGetOriginalMemoryFunctions(
//
// Get the current set of Domito memory functions.
//
//
EXTERN_C
void
DomitoGetMemoryFunctions(
@@ -81,7 +71,9 @@ DomitoGetMemoryFunctions(
);
//
// Replace Domito's memory allocation functions with a custom set
// Replace Domito's memory allocation functions with a compatible pair during
// quiescent initialization. No in-flight calls or outstanding callback-backed
// allocations may span a pair change. Replacement is not synchronized.
EXTERN_C
void
DomitoSetMemoryFunctions(
@@ -89,7 +81,6 @@ DomitoSetMemoryFunctions(
_In_opt_ PFN_DOMITO_FREE_ROUTINE Free
);
/* ___ _ _
* / __|_ _ _ _ _ __| |_ ___ __ _ _ _ __ _ _ __| |_ _ _
* | (__| '_| || | '_ \ _/ _ \/ _` | '_/ _` | '_ \ ' \ || |
@@ -97,9 +88,9 @@ DomitoSetMemoryFunctions(
* |__/|_| |___/ |_| |__/
*/
//
// This structure encapsulates a signature used in verifying executable files.
//
//
// This structure encapsulates a signature used in verifying executable files.
//
#if !defined(WIN_CERTIFICATE)
typedef struct _WIN_CERTIFICATE
{
@@ -112,16 +103,16 @@ typedef struct _WIN_CERTIFICATE
//
// UM definitions of WinCrypt.h
//
//
#if !defined(WIN_CERT_TYPE_X509)
#define WIN_CERT_TYPE_X509 (0x0001) // The bCertificate member contains an X.509 certificate.
#define WIN_CERT_TYPE_X509 (0x0001) // The bCertificate member contains an X.509 certificate.
#endif
#if !defined(WIN_CERT_TYPE_PKCS_SIGNED_DATA)
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA (0x0002) // The bCertificate member contains a PKCS SignedData structure.
#define WIN_CERT_TYPE_PKCS_SIGNED_DATA (0x0002) // The bCertificate member contains a PKCS SignedData structure.
#endif
#if !defined(WIN_CERT_TYPE_PKCS1_SIGN)
#define WIN_CERT_TYPE_PKCS1_SIGN (0x0009) // The bCertificate member contains PKCS1_MODULE_SIGN fields.
#define WIN_CERT_TYPE_PKCS1_SIGN (0x0009) // The bCertificate member contains PKCS1_MODULE_SIGN fields.
#endif
#if !defined(CALG_SHA1)
@@ -141,6 +132,7 @@ typedef struct _WIN_CERTIFICATE
// Converts a WinCrypt CALG_ID to a BCRYPT_ALGORITHM identifier.
//
PCWSTR
FORCEINLINE
DOMITO_CALG_TO_BCRYPT_ALGORITHM(
_In_ UINT32 Calg
@@ -161,7 +153,6 @@ DOMITO_CALG_TO_BCRYPT_ALGORITHM(
}
}
/* ___ _ ___ _ _ _
* / __|___ __| |___ |_ _|_ _| |_ ___ __ _ _ _(_) |_ _ _
* | (__/ _ \/ _` / -_) | || ' \ _/ -_) _` | '_| | _| || |
@@ -177,7 +168,9 @@ DOMITO_CALG_TO_BCRYPT_ALGORITHM(
//
_IRQL_requires_max_(DISPATCH_LEVEL)
EXTERN_C
UINT32
__declspec(deprecated(
"Use DomitoGetPortableExecutableDigestKindEx; heuristic detection silently falls back to SHA-1. Check the returned NTSTATUS."
)) UINT32
DomitoGetPortableExecutableDigestKind(
_In_ PUCHAR pPeBytes,
_In_ ULONG PeSize,
@@ -228,12 +221,14 @@ DomitoCalculatePortableExecutableDigestEx(
// The returned certificate pointer borrows the input buffer; free only the digest
// with DomitoFreePortableExecutableDigest. Algorithm detection is heuristic;
// general section-ordered Authenticode hashing is not implemented here.
//
//
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
EXTERN_C
NTSTATUS
__declspec(deprecated(
"Use DomitoCalculatePortableExecutableDigestEx with an explicit algorithm; review its supported PE layout and failure statuses."
)) NTSTATUS
DomitoCalculatePortableExecutableDigest(
_In_ PUCHAR pPeBytes,
_In_ ULONG PeSize,
@@ -246,7 +241,7 @@ DomitoCalculatePortableExecutableDigest(
//
// Frees the memory allocated by DomitoCalculatePortableExecutableDigest.
//
//
_IRQL_requires_max_(DISPATCH_LEVEL)
EXTERN_C
void
@@ -278,7 +273,7 @@ typedef struct _DOMITO_CI_VALIDATION_RESULT
UINT32 HashSize;
ALG_ID HashAlgId;
UINT32 FileObjectValidationFlags; // Flags passed to CI export; zero for embedded helper.
UINT8 RequestedSigningLevel; // File-object helper only.
UINT8 RequestedSigningLevel; // File-object helper only.
} DOMITO_CI_VALIDATION_RESULT, *PDOMITO_CI_VALIDATION_RESULT;
// Safe for NULL or an empty/initialized result; resets all fields after cleanup.
@@ -328,7 +323,7 @@ DomitoValidatePortableExecutableEmbeddedSignature(
#endif // NTDDI_VERSION >= NTDDI_WIN10
#define DOMITO_CI_SOURCE_EMBEDDED 1UL
#define DOMITO_CI_SOURCE_CATALOG 2UL
#define DOMITO_CI_SOURCE_CATALOG 2UL
// Policy-explicit legacy helper. SHA-1/256 only; hash size must match algorithm.
// Policy objects must be zero-initialized or own valid CI results; both are freed
@@ -361,12 +356,14 @@ DomitoValidateFileLegacyModeEx(
// Compatibility wrapper around DomitoValidateFileLegacyModeEx, with catalog
// mask DOMITO_CI_LEGACY_CATALOG_POLICY_BITS and RequireTrustedCatalog = FALSE.
// The same initialization, ownership, hash, handle, and stable-file rules apply.
//
//
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
EXTERN_C
NTSTATUS
__declspec(deprecated(
"Use DomitoValidateFileLegacyModeEx with explicit catalog policy and validation-source output; do not change trust policy implicitly."
)) NTSTATUS
DomitoValidateFileLegacyMode(
_In_ HANDLE FileHandle,
_In_ PVOID Hash,
@@ -378,7 +375,6 @@ DomitoValidateFileLegacyMode(
_Inout_ MINCRYPT_POLICY_INFO* TimeStampPolicyInfo
);
/* __ __ _
* | \/ (_)___ __
* | |\/| | (_-</ _|_
@@ -386,9 +382,9 @@ DomitoValidateFileLegacyMode(
*
*/
//
// Finds the base address of a driver module.
//
//
// Finds the base address of a driver module. Clears the optional output first.
//
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
@@ -404,7 +400,7 @@ DomitoFindModuleBaseAddress(
// ModuleBase must remain mapped; arbitrary file buffers are not supported.
// Export table spans are checked against SizeOfImage. Forwarded exports return
// STATUS_NOT_SUPPORTED; the optional output is cleared before lookup.
//
//
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
@@ -418,7 +414,7 @@ DomitoFindExportedFunctionAddress(
//
// Scans a provided buffer for a memory pattern.
//
//
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(DISPATCH_LEVEL)
@@ -456,7 +452,7 @@ DomitoReadFileAt(
// with special kernel APCs enabled, a readable handle valid in the current process
// (or a kernel handle), and a buffer that remains valid for the entire call.
// For synchronous handles, the explicit read also updates the file position.
//
//
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
@@ -469,14 +465,23 @@ DomitoReadFile(
);
//
// Gets the name of the main image of the process identified by PID.
//
// Gets the main image name after resolving the ULONG PID once to a process handle.
// Requires DomitoInit. Output is NULL on failure; successful result is one Domito
// allocation containing UNICODE_STRING and its buffer. Use DomitoFreeProcessImageName.
// Do not change memory callbacks with outstanding allocations. PID reuse can race
// the initial open; a later path reopen is not proof of original image identity.
//
_Success_(return == STATUS_SUCCESS)
_Must_inspect_result_
_IRQL_requires_max_(PASSIVE_LEVEL)
EXTERN_C
NTSTATUS
__declspec(deprecated(
"Use DomitoGetProcessImageNameEx with a caller-referenced PEPROCESS to avoid a fresh PID lookup; free the result with DomitoFreeProcessImageName."
)) NTSTATUS
DomitoGetProcessImageName(
_In_ ULONG ProcessId,
_Inout_ PUNICODE_STRING* ProcessImageName
_Outptr_result_maybenull_ PUNICODE_STRING* ProcessImageName
);
// Additive consumer helpers, included here for existing Domito.h clients.
#include "Domito.Consumer.h"