#pragma once #include "Domito.h" // Consumer helpers: see docs/consumer-helpers.md for ownership and trust limits. typedef struct _DOMITO_BYTE_VIEW { const UCHAR* Data; ULONG Size; } DOMITO_BYTE_VIEW; typedef struct _DOMITO_CERTIFICATE_SPKI { DOMITO_BYTE_VIEW Encoded; // Complete SPKI SEQUENCE, including tag and length. DOMITO_BYTE_VIEW Content; // Legacy consumer convention: excludes that header. } DOMITO_CERTIFICATE_SPKI; typedef enum _DOMITO_CERTIFICATE_HASH_KIND { DomitoCertificateHashDer = 0, DomitoCertificateHashSpkiDer = 1, DomitoCertificateHashSpkiContentLegacy = 2 } DOMITO_CERTIFICATE_HASH_KIND; // Bounded positional DER extraction, not X.509 validation. Views borrow CertData. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoGetCertificateSpki( _In_reads_bytes_(CertSize) const UCHAR* CertData, _In_ ULONG CertSize, _Out_ DOMITO_CERTIFICATE_SPKI* Spki ); // SHA-1/256/384/512. HashSize is capacity on entry, bytes on success, required // size on BUFFER_TOO_SMALL, zero on other failures. Hash may be NULL to size. // Input/output must not overlap. Hash contains zero bytes on operational failure. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoHashBuffer( _In_reads_bytes_opt_(Size) const UCHAR* Bytes, _In_ ULONG Size, _In_ ALG_ID Algorithm, _Out_writes_bytes_to_opt_(*HashSize, *HashSize) UCHAR* Hash, _Inout_ ULONG* HashSize ); _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoHashCertificate( _In_reads_bytes_(CertSize) const UCHAR* CertData, _In_ ULONG CertSize, _In_ DOMITO_CERTIFICATE_HASH_KIND Kind, _In_ ALG_ID Algorithm, _Out_writes_bytes_to_opt_(*HashSize, *HashSize) UCHAR* Hash, _Inout_ ULONG* HashSize ); // Strict length-delimited hex: no spaces, prefixes, separators or invalid digits. // Nonoverlapping buffers. Decode clears its output on malformed input. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoDecodeHex( _In_ const UNICODE_STRING* Hex, _Out_writes_bytes_(ByteCount) UCHAR* Bytes, _In_ ULONG ByteCount ); // Writes uppercase hex plus NUL; HexChars includes terminator capacity. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoEncodeHex( _In_reads_bytes_opt_(ByteCount) const UCHAR* Bytes, _In_ ULONG ByteCount, _Out_writes_(HexChars) WCHAR* Hex, _In_ ULONG HexChars ); // Resolve optional exports without creating a static import. Requires DomitoInit. // ModuleName is the full loaded-module path used by FindModuleBaseAddress. // Caller must keep that module mapped; this does not acquire a loader reference. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoFindModuleExportedFunctionAddress( _In_ PANSI_STRING ModuleName, _In_ PANSI_STRING FunctionName, _Outptr_result_maybenull_ PVOID* FunctionAddress ); // Results from either process-name API use one Domito allocation. The memory // callback pair must remain unchanged until all allocations are released. _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C void DomitoFreeProcessImageName( _In_opt_ PUNICODE_STRING ImageName ); // Caller holds a referenced PEPROCESS throughout the call. No PID re-lookup. // Returns a copy owned by Domito; use DomitoFreeProcessImageName once. // Name lookup does not establish the identity of a later reopened file. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoGetProcessImageNameEx( _In_ PEPROCESS Process, _Outptr_result_maybenull_ PUNICODE_STRING* ImageName ); #if (NTDDI_VERSION >= NTDDI_WIN10) // These wrappers do not require DomitoInit. Handle must be a trusted kernel // handle with FILE_READ_DATA; it is borrowed, referenced for the call, not closed. // Same initialized-result/cleanup rules and explicit flags as FileObjectEx. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoValidateFileHandleEx( _In_ HANDLE FileHandle, _In_ UINT32 ValidationFlags, _In_ UINT8 RequestedSigningLevel, _In_ DOMITO_CI_SIGNATURE_SELECTION Selection, _Inout_ DOMITO_CI_VALIDATION_RESULT* Result ); // Absolute native path (e.g. \??\C:\...). Opens read-only, shares only reads, // closes its own handle. The path can be reparsed; this validates the opened // file, not process memory or a previous path identity. No fallback is implicit. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoValidateFilePathEx( _In_ const UNICODE_STRING* Path, _In_ UINT32 ValidationFlags, _In_ UINT8 RequestedSigningLevel, _In_ DOMITO_CI_SIGNATURE_SELECTION Selection, _Inout_ DOMITO_CI_VALIDATION_RESULT* Result ); typedef enum _DOMITO_CI_CHAIN_LAYOUT { // Explicit caller assertion: observed x64 +0x28 array/+0x30 count, 120-byte // elements and a minimum 56-byte header. NOT selected by allocation Size. DomitoCiChainLayoutObservedX64 = 1 } DOMITO_CI_CHAIN_LAYOUT; typedef struct _DOMITO_CI_CHAIN_VIEW { const MINCRYPT_CHAIN_ELEMENT* Elements; ULONG Count; ULONG RootId; // Opaque CI identifier, not proof the last element is a root. } DOMITO_CI_CHAIN_VIEW; // Only accepts a readable, initialized CI-owned policy, never arbitrary pointers. // Checks every exposed name/certificate span against CI's owned allocation. // Leaf-first order is observed in sampled layouts. Last element is not promised // to be a self-signed/trusted root. No issuer/subject byte equality is imposed. // View borrows policy storage until CiFreePolicyInfo/result reuse. x64 only. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoGetCiChainView( _In_ const MINCRYPT_POLICY_INFO* Policy, _In_ DOMITO_CI_CHAIN_LAYOUT Layout, _Out_ DOMITO_CI_CHAIN_VIEW* View ); // Optional export, resolved at call time; requires DomitoInit. No static import // of CiGetCertPublisherName. Extracts a display name, not certificate trust. // Start with {0}; release even after failure using the dedicated free function. // Never pass an owning previous string: free it before making another call. _Must_inspect_result_ _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C NTSTATUS DomitoGetCertificatePublisherName( _In_ const MINCERT_BLOB* Certificate, _Out_ PUNICODE_STRING PublisherName ); _IRQL_requires_max_(PASSIVE_LEVEL) EXTERN_C void DomitoFreeCertificatePublisherName( _Inout_ PUNICODE_STRING PublisherName ); #endif