diff --git a/NOTES.md b/NOTES.md index 85aaae9..8d4e4e5 100644 --- a/NOTES.md +++ b/NOTES.md @@ -1,21 +1,69 @@ -# CI APIs +# CI API availability observations -These historical availability notes are unverified. The analyzed ci.dll -10.0.26100.8328 x64 still exports the digest-based APIs listed below. Exact -first-available builds and ABI changes need matching old binaries. See -[the current contracts and remaining work](docs/mincrypt-contracts.md). +See the [CI API compatibility matrix](docs/ci-api-compatibility.md) for the +per-API tables covering all ten VM, ISO and modern x64 samples, with exact +versions, file hashes and machine-readable results. The six-sample notes below +describe the original VM corpus and its subsequent ISO follow-up. -## Available starting with 1511 +These are export-table observations from six extracted x64 `ci.dll` files, not +claims about every servicing revision or a proof of the original introduction +build. The companion CodeIntegrity-RE `corpus-index.json` records identities, +extraction aliases, manifest checks, and metadata. VM directory names are labels; +versions below come from the PE version resources. No target was executed. -- CiCheckSignedFile -- CiFindPageHashesInCatalog -- CiFindPageHashesInSignedFile -- CiFreePolicyInfo -- CiGetPEInformation -- CiInitialize -- CiValidateFileObject -- CiVerifyHashInCatalog +## Named exports common to all six samples -## Added in 1709 +- `CiCheckSignedFile` +- `CiFindPageHashesInCatalog` +- `CiFindPageHashesInSignedFile` +- `CiFreePolicyInfo` +- `CiGetPEInformation` +- `CiInitialize` +- `CiValidateFileObject` +- `CiVerifyHashInCatalog` -- CiSetTrustedOriginClaimId +`CiValidateFileObject` is already present in sampled Windows 10 **1507** +`10.0.10240.16463`. The old “starting with 1511” list was therefore too narrow. +Export presence does not establish a complete compatible parameter/structure +contract; consult the per-build static analysis before using it. + +## Additional names and absent names + +`CiSetTrustedOriginClaimId` is present in sampled `10.0.15063.0` (**1703**) and +in the sampled 1709/1803 files. It is absent from the sampled 1507,1511,1607 +export tables. This corrects the old “added in 1709” note, without claiming the +first Windows build on which the API ever existed. + +`CiGetCertPublisherName` is absent from **all six** sampled 1507–1803 export +tables. The ISO follow-up also finds it absent in x64 `10.0.19041.1`, present +in x64 `10.0.19041.1865` and `10.0.22000.318`, and the original investigation +finds it present in `10.0.26100.8328`. This brackets Windows 10 servicing +observations without identifying the first update adding the export. The +CodeIntegrity-RE `iso-corpus-index.json` records the exact files and hashes. +A header declaration, +import-library symbol, or `NTDDI_VERSION >= NTDDI_WIN10` alone does not make an +unconditional static import loadable on the older samples. Callers supporting +those samples must avoid that import or use optional resolution with an +explicit unavailable/fallback path. `CiSetTrustedOriginClaimId` likewise cannot +be assumed available on every Windows 10 build; it is a CI-global setter. + +## Exact sampled files + +- Windows 10 1507: `10.0.10240.16463` x64, SHA-256 + `e83d900f4675c6e6ffc3fb7dcd3074610876a1398e495796769988df810fd3bc`. +- Windows 10 1511: `10.0.10586.0` x64, SHA-256 + `f949bfa614addea6174b28c3818c56b327c9290fd41bd91dfc545414b3df6783`. +- Windows 10 1607: `10.0.14393.2189` x64, SHA-256 + `ef0c02ecbd0818e84be9f61421f919825f96a3c59199460cab08548eee2881df`. +- Windows 10 1703: `10.0.15063.0` x64, SHA-256 + `3705aaf408f05326e028621380aa5c96a1f3583a2de8a139b188da4b82577863`. +- Windows 10 1709: `10.0.16299.125` x64, SHA-256 + `1db7ae5a08bd2361fc7fcdd373fb980e8d680035e67b02e5967095db0443effd`. +- Windows 10 1803: `10.0.17134.1130` x64, SHA-256 + `8ce3b8fe38c23b699f30b045383640019a429d3a9d513285c655bffe03a796d9`. + +Matching Microsoft public PDB GUIDs/ages were verified in +`historical/ci--symbols.json` in CodeIntegrity-RE. Public names help map +functions; they are not a full typed SDK. The default Domito declarations remain +conservative. See [current contracts and limits](docs/mincrypt-contracts.md) and +[implementation status](docs/implementation-status.md) for ABI and runtime work. diff --git a/README.md b/README.md index aa58660..b05e9df 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Built for and tested on **Windows 10 version 1507 (or newer) x64/ARM64**. 32-Bit - I do not want to force any consumer of the library to drag C++ paradigms into their project. I do expect the user to utilize a modern compiler though, so the library sources themselves may have some 'C++-ish touches' here and there, for my own convenience 😉 - Compatibility with every Windows 10 version. - APIs not available on older builds will give you a `STATUS_NOT_IMPLEMENTED` instead of hard-linking and therefore making your driver fail to load 🤞 - - CI entry points are currently static imports from `ci.lib`; consumers must avoid imports unavailable on their target Windows builds. Export lookup now uses the correct name-ordinal mapping and rejects forwarders, but this does not establish a complete CI availability or runtime ABI matrix. See the remaining-work ledger below. + - CI entry points are currently static imports from `ci.lib`; consumers must avoid imports unavailable on their target Windows builds. The [CI API compatibility matrix](docs/ci-api-compatibility.md) records all ten named exports across ten exact Windows 10/11 x64 CI files. Export lookup uses the correct name-ordinal mapping and rejects forwarders. Runtime ABI verification remains separate; see the remaining-work ledger below. - No conflicts with WDF or DMF - The consuming driver *may* (but doesn't have to) utilize Microsoft WDF or DMF in addition without having to fear any incompatibilities 💪 - Reliable SAL annotations. diff --git a/docs/ci-api-compatibility.json b/docs/ci-api-compatibility.json new file mode 100644 index 0000000..1a3ad24 --- /dev/null +++ b/docs/ci-api-compatibility.json @@ -0,0 +1,334 @@ +{ + "schema_version": 1, + "scope": "Observed named PE exports in exact x64 ci.dll samples; not runtime or ABI certification", + "generated_from": { + "corpus-index.json": "c324dddaa4b88e66eb119e2ce26023face3763fb68d496d6285b836a60d267f8", + "iso-corpus-index.json": "1b5f95e4ef2eb6aa6e7d0414cd5a899426ff7092e1ef8afb65f3b50f958bc6dc", + "manifest.json": "7712d6e88b81ac155bd1371ada61df2848e943a12abe709b7b2050ce4b91c6e5", + "ci-26100.8328-evidence.json": "ea0f939df9d8b7abde40e3402c01b2ac398253728f329e8c2b7134de8df6305f" + }, + "apis": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetCertPublisherName", + "CiGetPEInformation", + "CiInitialize", + "CiSetTrustedOriginClaimId", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "samples": [ + { + "label": "Windows 10 1507", + "ci_file_version": "10.0.10240.16463", + "architecture": "x64", + "sha256": "e83d900f4675c6e6ffc3fb7dcd3074610876a1398e495796769988df810fd3bc", + "source": "corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetPEInformation", + "CiInitialize", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": false, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": false, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 10 1511", + "ci_file_version": "10.0.10586.0", + "architecture": "x64", + "sha256": "f949bfa614addea6174b28c3818c56b327c9290fd41bd91dfc545414b3df6783", + "source": "corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetPEInformation", + "CiInitialize", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": false, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": false, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 10 1607", + "ci_file_version": "10.0.14393.2189", + "architecture": "x64", + "sha256": "ef0c02ecbd0818e84be9f61421f919825f96a3c59199460cab08548eee2881df", + "source": "corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetPEInformation", + "CiInitialize", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": false, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": false, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 10 1703", + "ci_file_version": "10.0.15063.0", + "architecture": "x64", + "sha256": "3705aaf408f05326e028621380aa5c96a1f3583a2de8a139b188da4b82577863", + "source": "corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetPEInformation", + "CiInitialize", + "CiSetTrustedOriginClaimId", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": false, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": true, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 10 1709", + "ci_file_version": "10.0.16299.125", + "architecture": "x64", + "sha256": "1db7ae5a08bd2361fc7fcdd373fb980e8d680035e67b02e5967095db0443effd", + "source": "corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetPEInformation", + "CiInitialize", + "CiSetTrustedOriginClaimId", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": false, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": true, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 10 1803", + "ci_file_version": "10.0.17134.1130", + "architecture": "x64", + "sha256": "8ce3b8fe38c23b699f30b045383640019a429d3a9d513285c655bffe03a796d9", + "source": "corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetPEInformation", + "CiInitialize", + "CiSetTrustedOriginClaimId", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": false, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": true, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 10 2004 ISO", + "ci_file_version": "10.0.19041.1", + "architecture": "x64", + "sha256": "2955710d34db26e352e62b20861ba338f0216cc36b378d128057be955e184282", + "source": "iso-corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetPEInformation", + "CiInitialize", + "CiSetTrustedOriginClaimId", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": false, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": true, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 10 22H2 consumer ISO", + "ci_file_version": "10.0.19041.1865", + "architecture": "x64", + "sha256": "d0408a9f64eafb72e8aa1cf127d07d919f0cab38a6bdf2b406255909c85e3a8d", + "source": "iso-corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetCertPublisherName", + "CiGetPEInformation", + "CiInitialize", + "CiSetTrustedOriginClaimId", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": true, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": true, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 11 English x64 v1 ISO", + "ci_file_version": "10.0.22000.318", + "architecture": "x64", + "sha256": "301ae49ac5b87cf1cbe07d9d3c6486a066d045b6bf55fc8eb392d52951ec69ff", + "source": "iso-corpus-index.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetCertPublisherName", + "CiGetPEInformation", + "CiInitialize", + "CiSetTrustedOriginClaimId", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": true, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": true, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + }, + { + "label": "Windows 11 24H2 sample", + "ci_file_version": "10.0.26100.8328", + "architecture": "x64", + "sha256": "c7d23814f3202c51fb23e3ca3d4328855787383cee5d14c4a986a13ec2aeda0b", + "source": "ci-26100.8328-evidence.json", + "named_exports": [ + "CiCheckSignedFile", + "CiFindPageHashesInCatalog", + "CiFindPageHashesInSignedFile", + "CiFreePolicyInfo", + "CiGetCertPublisherName", + "CiGetPEInformation", + "CiInitialize", + "CiSetTrustedOriginClaimId", + "CiValidateFileObject", + "CiVerifyHashInCatalog" + ], + "ordinal_only_export_count": 3, + "api_presence": { + "CiCheckSignedFile": true, + "CiFindPageHashesInCatalog": true, + "CiFindPageHashesInSignedFile": true, + "CiFreePolicyInfo": true, + "CiGetCertPublisherName": true, + "CiGetPEInformation": true, + "CiInitialize": true, + "CiSetTrustedOriginClaimId": true, + "CiValidateFileObject": true, + "CiVerifyHashInCatalog": true + } + } + ] +} diff --git a/docs/ci-api-compatibility.md b/docs/ci-api-compatibility.md new file mode 100644 index 0000000..b4593b7 --- /dev/null +++ b/docs/ci-api-compatibility.md @@ -0,0 +1,104 @@ +# CI API compatibility matrix + +This matrix records **named export presence in ten exact x64 `ci.dll` files**. +**Yes** means the complete PE export directory contains the name; **No** means +it does not. Neither result is inferred from a header, import library or PDB. +Export presence alone does not establish a compatible ABI or successful verification. + +Versions in the tables are **CI file versions**, not necessarily the kernel version. +In particular, the Windows 10 22H2 consumer ISO contains CI **19041.1865**. +Do not extrapolate a cell to every servicing revision of that Windows release. + +[Machine-readable matrix](ci-api-compatibility.json) includes exact SHA-256 identities, +all per-API results and hashes of the retained source inventories. + +## Windows 10 1507–1803 samples + +| API | 10240.16463 | 10586.0 | 14393.2189 | 15063.0 | 16299.125 | 17134.1130 | +| --- | --- | --- | --- | --- | --- | --- | +| `CiCheckSignedFile` | Yes | Yes | Yes | Yes | Yes | Yes | +| `CiFindPageHashesInCatalog` | Yes | Yes | Yes | Yes | Yes | Yes | +| `CiFindPageHashesInSignedFile` | Yes | Yes | Yes | Yes | Yes | Yes | +| `CiFreePolicyInfo` | Yes | Yes | Yes | Yes | Yes | Yes | +| `CiGetCertPublisherName` | No | No | No | No | No | No | +| `CiGetPEInformation` | Yes | Yes | Yes | Yes | Yes | Yes | +| `CiInitialize` | Yes | Yes | Yes | Yes | Yes | Yes | +| `CiSetTrustedOriginClaimId` | No | No | No | Yes | Yes | Yes | +| `CiValidateFileObject` | Yes | Yes | Yes | Yes | Yes | Yes | +| `CiVerifyHashInCatalog` | Yes | Yes | Yes | Yes | Yes | Yes | + +## Later Windows 10 and Windows 11 samples + +| API | 19041.1 | 19041.1865 | 22000.318 | 26100.8328 | +| --- | --- | --- | --- | --- | +| `CiCheckSignedFile` | Yes | Yes | Yes | Yes | +| `CiFindPageHashesInCatalog` | Yes | Yes | Yes | Yes | +| `CiFindPageHashesInSignedFile` | Yes | Yes | Yes | Yes | +| `CiFreePolicyInfo` | Yes | Yes | Yes | Yes | +| `CiGetCertPublisherName` | No | Yes | Yes | Yes | +| `CiGetPEInformation` | Yes | Yes | Yes | Yes | +| `CiInitialize` | Yes | Yes | Yes | Yes | +| `CiSetTrustedOriginClaimId` | Yes | Yes | Yes | Yes | +| `CiValidateFileObject` | Yes | Yes | Yes | Yes | +| `CiVerifyHashInCatalog` | Yes | Yes | Yes | Yes | + +## Exact sample identities + +- Windows 10 1507: **10.0.10240.16463 x64**, SHA-256 + `e83d900f4675c6e6ffc3fb7dcd3074610876a1398e495796769988df810fd3bc`. +- Windows 10 1511: **10.0.10586.0 x64**, SHA-256 + `f949bfa614addea6174b28c3818c56b327c9290fd41bd91dfc545414b3df6783`. +- Windows 10 1607: **10.0.14393.2189 x64**, SHA-256 + `ef0c02ecbd0818e84be9f61421f919825f96a3c59199460cab08548eee2881df`. +- Windows 10 1703: **10.0.15063.0 x64**, SHA-256 + `3705aaf408f05326e028621380aa5c96a1f3583a2de8a139b188da4b82577863`. +- Windows 10 1709: **10.0.16299.125 x64**, SHA-256 + `1db7ae5a08bd2361fc7fcdd373fb980e8d680035e67b02e5967095db0443effd`. +- Windows 10 1803: **10.0.17134.1130 x64**, SHA-256 + `8ce3b8fe38c23b699f30b045383640019a429d3a9d513285c655bffe03a796d9`. +- Windows 10 2004 ISO: **10.0.19041.1 x64**, SHA-256 + `2955710d34db26e352e62b20861ba338f0216cc36b378d128057be955e184282`. +- Windows 10 22H2 consumer ISO: **10.0.19041.1865 x64**, SHA-256 + `d0408a9f64eafb72e8aa1cf127d07d919f0cab38a6bdf2b406255909c85e3a8d`. +- Windows 11 English x64 v1 ISO: **10.0.22000.318 x64**, SHA-256 + `301ae49ac5b87cf1cbe07d9d3c6486a066d045b6bf55fc8eb392d52951ec69ff`. +- Windows 11 24H2 sample: **10.0.26100.8328 x64**, SHA-256 + `c7d23814f3202c51fb23e3ca3d4328855787383cee5d14c4a986a13ec2aeda0b`. + +## What callers can rely on + +- `CiValidateFileObject` is already exported in the sampled Windows 10 1507 file. +- `CiSetTrustedOriginClaimId` is present in the sampled 1703 file and absent in + the three earlier samples. This does not prove its first introduction build. +- `CiGetCertPublisherName` is absent in 19041.1 and present in 19041.1865. + Its first Windows 10 servicing update remains unknown. It is also present + in the sampled 22000.318 and 26100.8328 files. +- CI entry points currently use static imports from `ci.lib`. An unavailable + import can prevent driver loading; this matrix does not add an automatic + `STATUS_NOT_IMPLEMENTED` fallback. Supporting these older samples requires + avoiding unavailable imports or implementing optional resolution. +- Choose structures using a verified runtime profile. The sampled x64 chain + headers differ: 1507 uses 56 bytes, 1511 uses 72, and 1607–1803 use 104. + Export presence, compile-target `NTDDI_VERSION` and total allocation `Size` + do not select a compatible layout. See [mincrypt contracts](mincrypt-contracts.md). + +## Coverage gaps and evidence + +**Unknown / not sampled:** x86 and ARM64 export availability; pre-Windows-10; +Windows 10 1809/1903/1909; other 19041 servicing revisions; and Windows 11 +22621/22631. These are gaps, not negative export results. No interval between +two samples is certified. Runtime verification and cross-version ABI checks +remain in the [implementation ledger](implementation-status.md). + +The tables cover every named export found in these samples, including +`CiInitialize`; inclusion is not a recommendation to call initialization or +global-policy routines. Each sample also has three ordinal-only exports, +which are outside this named-API matrix. Private `Mincrypt*` PDB symbols are +not automatically callable exports. + +Source inventories are retained in the companion +[CodeIntegrity-RE repository](https://git.nefarius.at/nefarius/CodeIntegrity-RE): +`corpus-index.json` (VM samples), `iso-corpus-index.json` (ISO samples), and +`ci-26100.8328-evidence.json` with `manifest.json` (original 26100 sample). +Regenerate with its `generate_compatibility_matrix.py --output `. +No Windows binary or PDB is distributed with the matrix. diff --git a/docs/ci-validate-file-object.md b/docs/ci-validate-file-object.md index 3a982d7..ddbf516 100644 --- a/docs/ci-validate-file-object.md +++ b/docs/ci-validate-file-object.md @@ -49,6 +49,52 @@ fixed SHA-1/SHA-256 selector. Also distinguish this **input flag** from the unrelated `MINCRYPT_POLICY_INFO.PolicyBits` output bit `0x20`, associated with the built-in DMD root category in this build. +## Historical generation differences + +The same numeric flag does not imply the same internal root mask across Windows +versions. Static analysis of the extracted x64 corpus adds these bounded facts: + +- On sampled `10.0.10240.16463` (1507), `10.0.10586.0` (1511), + `10.0.14393.2189` (1607) and `10.0.15063.0` (1703), the recovered + `CipGetAcceptedRootKeys` bodies have no direct `flag & 0x20` broadening branch. + They still test larger masks containing that bit, so this is not evidence that + the flag has no effect anywhere in those verifiers. +- On sampled `10.0.16299.125` (1709) and `10.0.17134.1130` (1803), when the + helper's main global mode is zero, + `flag & 0x20` selects mask `0x224FF` (assignment), rather than the modern + `mask |= 0xA4FF` operation. A signing-level predicate can select the same mask. + Other global additions occur afterward. The other global mode returns + `0x204FF` directly. + +The observed helper masks include branch-specific diagnostics/categories and +must not be interpreted as an official stable root enum. The descriptive Domito +constant names the intended broadening use without promising a single mask or +identical behavior on every build. + +The ISO-derived **10.0.19041.1 x64** helper provides direct static evidence for +the reported build family: in its main global mode it uses `mask |= 0x24FF` +when flag `0x20` or the signing-level predicate applies; the alternate mode +returns `0x24FF`. With requested level zero and optional global additions +disabled, `0xAA` becomes `0x24FF` (added bits `0x2455`). This is an arithmetic +witness, not a measurement of initialized OS policy. The exact CI SHA-256 is +`2955710d34db26e352e62b20861ba338f0216cc36b378d128057be955e184282`. +CodeIntegrity-RE retains matched-PDB pseudocode and assembly in +`historical/ci-19041.1-contracts.json` and `historical/ci-19041.1-assembly.json`, +with batch evidence ID +`ev_13f89502777ee38ea98410f7a07f078bb934e78d792b662ab242f7b11d27e747`. +Other 19041/19045 servicing revisions and the TESTSIGNING-off runtime workaround +still require their own evidence. + +Historical records in CodeIntegrity-RE: +`historical/ci-14393-contracts.json` +`ev_e63a4c4b7613e231795051b784b9571605b9bf81258b5dcd04d32ddc681abb41`, +`historical/ci-15063-contracts.json` +`ev_338658fb82559fa6daa8ae5487b90fe84b8e408ea7578feed6d8dff5d590e114`, +`historical/ci-16299-contracts.json` +`ev_fe5731175f0726f0d46af2f78ca615d284f8598939296815e26b5589db3001cf`, +and `historical/ci-17134-contracts.json` +`ev_0c3e3359b8b7486318006afa6b95eb2257a18abeec9041a86a32db487bcbe996`. + ## Evidence and compatibility limits The [upstream report](https://github.com/Ido-Moshe-Github/CiDllDemo/issues/5#issuecomment-2725851295) diff --git a/docs/implementation-status.md b/docs/implementation-status.md index b53c372..cd8bf86 100644 --- a/docs/implementation-status.md +++ b/docs/implementation-status.md @@ -43,19 +43,30 @@ it should not be read as describing the corrected source unchanged. - **S13/S15/S16:** recovered fields, parameter meanings, policy categories, sizes, name encoding, borrowed lifetimes, and allocator ownership are documented. The opt-in x64 26100 header provides distinct observed layouts and assertions. - Default layouts remain compatible; runtime layout identity cannot be inferred - from `NTDDI_VERSION` or `ChainInfo->Size` alone. + Default declarations retain source compatibility; later chain fields require + a confirmed runtime layout. The sampled 1507 chain header is 56 bytes and has + no attributes descriptor at +0x38; 1511 uses 72 bytes; 1607–1803 samples use 104. + Distinct views are available in `Domito.MinCrypt.Historical.h`. Neither + `NTDDI_VERSION` nor total allocation Size identifies the layout. ## Requires the test VM or additional matching binaries -The VM is not available yet. Host mocks and compilation do not close these: +Live kernel testing is not available yet. Extracted VM artifacts, host mocks, +and compilation do not close these: 1. Run the paired `CiValidateFileObject` flag `0`/`0x20` probe on 19041/19045 with TESTSIGNING off and a loadable signed test driver. Preserve complete statuses, policies and fixture/environment identities (issue #3). -2. Verify historical and ARM64 ABI, structure evolution and first-available - export versions using matching binaries/symbols and runtime tests. Preserve - default layouts until that evidence supports changing them. +2. Complete historical and ARM64 ABI/structure verification and runtime tests. + The [published export matrix](ci-api-compatibility.md) now covers all ten + named APIs across ten exact Windows 10/11 x64 CI files, including 19041.1, + 19041.1865 and 22000.318 ISO samples. This closes the initial export-presence + matrix; additional releases, servicing revisions and architectures remain + unsampled. It does not certify ABI or runtime behavior. The six 1507–1803 + sampled bodies establish the + 48-byte policy storage and 64-byte hash-capacity gate. Chain constructors + establish 56/72/104-byte headers; opt-in views prevent treating 1507 payload + as the later attributes descriptor. Unsampled layouts/runtime remain open. 3. Test real CI policy ownership on every failure/retry path under Driver Verifier, including allocation failures and initialized outputs. 4. Compare real embedded/catalog-only SHA-1/SHA-256 results, catalog cache/reload @@ -75,5 +86,5 @@ The VM is not available yet. Host mocks and compilation do not close these: Run the three host runners in `tests/README.md`. Kernel compilation also covers the default modern x64/ARM64 structures, the pre-Windows-10 x64 compile variant, -and 14 assertions in the opt-in observed-build header. Those are build checks, +and 14 assertions in the 26100 opt-in header plus 12 historical-view assertions. Those are build checks, not a claim that historical or ARM64 CI runtime ABI has been verified. diff --git a/docs/mincrypt-contracts.md b/docs/mincrypt-contracts.md index c2879c5..2eeb94f 100644 --- a/docs/mincrypt-contracts.md +++ b/docs/mincrypt-contracts.md @@ -11,9 +11,80 @@ The evidence is static REA/Ghidra analysis of SHA-256 `c7d23814f3202c51fb23e3ca3d4328855787383cee5d14c4a986a13ec2aeda0b`, with Microsoft ci.pdb GUID `1CAE574B-CF1F-3564-5F74-49567A128629`, age 1 supplying the address/name map. The companion CodeIntegrity-RE repository retains the full -records and readable `evidence/` files. These observations do not establish -older-Windows or ARM64 ABI compatibility. Compile-target `NTDDI_VERSION` is not -runtime layout negotiation. +records and readable `evidence/` files. The historical corpus below adds +sampled x64 Windows 10 observations; ARM64 and unsampled-build compatibility +remain open. Compile-target `NTDDI_VERSION` is not runtime layout negotiation. + +## Historical x64 corpus: availability and structure evolution + +The [CI API compatibility matrix](ci-api-compatibility.md) lists observed named +exports for ten exact x64 CI files, including the later ISO samples. Consult it +for import availability, and the contracts below for layout and ownership limits. + +[NOTES.md](../NOTES.md) lists the exact identities of six sampled Windows 10 +files: `10.0.10240.16463`, `10.0.10586.0`, `10.0.14393.2189`, `10.0.15063.0`, +`10.0.16299.125`, and `10.0.17134.1130`. All export `CiValidateFileObject` and +the digest/catalog functions. The global setter is already present in sampled +1703, correcting the old 1709 note. The publisher-name export is absent from +all six. ISO samples additionally show absence in 19041.1 and presence in +19041.1865 and 22000.318 x64; the original 26100 file also exports it. The first +Windows 10 servicing update adding it remains unresolved. See CodeIntegrity-RE +`iso-corpus-index.json`. Header guards do not negotiate runtime import availability. + +All six sampled x64 file-object exports transfer 48 bytes into each caller +policy, with the owned chain pointer at `+0x10`; cleanup zeros `0x30` bytes. Their +file-object helpers require hash capacity >=64, return `STATUS_BUFFER_TOO_SMALL` +and required length 64 for a smaller buffer, and consume the third input as a +byte. This supports the stable policy storage prefix on these exact artifacts; +it does not establish all field semantics or every servicing build's behavior. + +**The chain header evolves within Windows 10. The default header's +`NTDDI_VERSION >= NTDDI_WIN10` condition cannot safely expose every later field +on Windows 10 1507.** Constructor evidence establishes: + +- `10.0.10240.16463` (1507): fixed header 56 bytes (`0x38`), root ID at `+0x34`, + variable payload beginning at `+0x38`. There is **no AuthenticodeAttributes + header field at `+0x38`**. Accessing the default structure's member on this + layout would interpret variable payload bytes as a blob descriptor. +- `10.0.10586.0` (1511): fixed header 72 bytes (`0x48`), attributes descriptor at + `+0x38`, payload beginning at `+0x48`. +- Sampled 1607/1703/1709/1803: fixed header 104 bytes (`0x68`), root ID still at + `+0x34`, attributes at `+0x38`, payload beginning at `+0x68`. Constructor evidence + establishes space for the 32-byte extension at `+0x48`, not its semantic + contents on every build. The historical view leaves this region reserved. + +`Domito.MinCrypt.Historical.h` supplies distinct opt-in x64 views for those +observed profiles with 12 compile-time assertions. The common prefix ends after +root ID at `+0x34`; chain elements use 120-byte strides in these constructors, +but the prefix views expose their storage as opaque. Do not assume every element +field is populated on every version. The 26100-specific header separately names +its recovered binary-ID field. + +Choose a view only after establishing the runtime artifact/layout. `Size` is +**total allocation bytes including payload**: a 1507 allocation can be larger +than 72 or 104 bytes, so `Size >= sizeof(later_header)` is not version detection. +Once layout identity is established, a size check is an additional field-read +bound, not a substitute for identity. The default declarations remain unchanged +for source compatibility; their later fields require this explicit runtime scope. + +Successful exported/helper records in CodeIntegrity-RE retain the evidence: + +- `historical/1507-export-contracts.json`: + `ev_489c3b57057b0bc5c86950d7bb4ea25108bbc7762abc363e1be7eb5cca034796`. +- `historical/ci-10240-helpers.json`: + `ev_6d602c57de9614e7c5c28b9532c139f750f0e014b151000ecb41ad36f54bf764`. +- `historical/ci-10586-exports.json`: + `ev_a09e04976cfd90e9ba69cc6618892f15c3da166c64fa9241efae0db85234fd6e`. +- `historical/ci-10586-helpers.json`: + `ev_3403d5b8bf7c322fd924880d4cd9b296b98e94238cac2e1c1e9605c4b4d27255`. +- `historical/ci-14393-contracts.json`: + `ev_e63a4c4b7613e231795051b784b9571605b9bf81258b5dcd04d32ddc681abb41`. +- `historical/ci-15063-contracts.json`: + `ev_338658fb82559fa6daa8ae5487b90fe84b8e408ea7578feed6d8dff5d590e114`. +- `historical/ci-16299-contracts.json`: + `ev_fe5731175f0726f0d46af2f78ca615d284f8598939296815e26b5589db3001cf`. +- `historical/ci-17134-contracts.json`: + `ev_0c3e3359b8b7486318006afa6b95eb2257a18abeec9041a86a32db487bcbe996`. ## Results and trust policy @@ -33,7 +104,7 @@ bytes the application will subsequently use. The [file-object flag document](ci-validate-file-object.md) covers `0x20`, hash capacity, signing level, and its pending VM experiment. Other observed flag -effects on this build are: +effects on 26100.8328 x64 are: - `0x1` selects hash scenario 5. - Otherwise `0x2` selects scenario 4 for signing levels <=4; higher levels use @@ -96,11 +167,11 @@ The wrapper selects the first certificate-table entry. Multiple table entries and nested signatures are separate concepts; this is not a complete signature enumeration interface. -These exports remain implemented on the analyzed Windows 11 build. The older -header's “Win7–8.1 only” comments described a workflow, not verified export -availability. Exact first-available builds and pre/post-KB3033929 ABI changes -still require matching historical binaries. Import-library symbol names and -stdcall stack-byte counts alone do not settle parameter semantics. +These exports are present in all six sampled Windows 10 x64 files and the +analyzed Windows 11 file. The older header's “Win7–8.1 only” comments described +a workflow, not verified export availability. Earlier first-available builds +and pre/post-KB3033929 ABI changes still require matching Windows 7/8 artifacts. +Import-library names and stdcall stack-byte counts alone do not settle semantics. ## Catalog controls @@ -201,7 +272,7 @@ be tested. CI global; it is not an ordinary per-file trust selector. Ordinal-only exports and other initialization interfaces require their own evidence and callers. -Still required: historical/ARM64 layout and parameter verification, real CI +Still required: complete sampled-build/ARM64 layout and parameter verification, real CI output lifetimes and retry behavior under failures, timestamp propagation, revocation freshness/network policy, weak-crypto selection, multiple/nested signatures, catalog-only algorithms, and extension of the bounded digest subset to additional PE layouts. diff --git a/include/Domito.MinCrypt.Historical.h b/include/Domito.MinCrypt.Historical.h new file mode 100644 index 0000000..0d0aa42 --- /dev/null +++ b/include/Domito.MinCrypt.Historical.h @@ -0,0 +1,73 @@ +/* Opt-in x64 chain views for exact observed Windows 10 CI artifacts. + * Include after ntddk.h. This does not alter Domito's default declarations. + * Select a view only after establishing the matching runtime layout from + * build/artifact evidence. ChainInfo->Size is TOTAL allocation size; it cannot + * identify the header version, because variable payload follows the header. + * See docs/mincrypt-contracts.md and NOTES.md for exact sampled versions/hashes. + */ +#pragma once +#include "Domito.MinCrypt.h" + +#if !defined(_M_AMD64) && !defined(__x86_64__) +#error Historical CI views are validated only for the documented x64 artifacts. +#endif + +#pragma pack(push, 8) +// Observed ci.dll 10.0.10240.16463. The variable payload begins at +0x38; +// AuthenticodeAttributes does not exist at that offset in this header. +typedef struct _DOMITO_CI10240_CHAIN_INFO +{ + UINT32 Size; + MINCERT_BLOB* PublicKeys; + UINT32 NumberOfPublicKeys; + MINCERT_BLOB* EKUs; + UINT32 NumberOfEKUs; + PVOID ChainElements; // Constructor copies 120-byte elements; borrowed storage. + UINT32 NumberOfChainElements; + UINT32 RootId; // Opaque identifier, not PolicyBits. +} DOMITO_CI10240_CHAIN_INFO, *PDOMITO_CI10240_CHAIN_INFO; + +// Observed ci.dll 10.0.10586.0. The variable payload begins at +0x48. +typedef struct _DOMITO_CI10586_CHAIN_INFO +{ + UINT32 Size; + MINCERT_BLOB* PublicKeys; + UINT32 NumberOfPublicKeys; + MINCERT_BLOB* EKUs; + UINT32 NumberOfEKUs; + PVOID ChainElements; + UINT32 NumberOfChainElements; + UINT32 RootId; + MINCRYPT_ATTR_BLOB AuthenticodeAttributes; +} DOMITO_CI10586_CHAIN_INFO, *PDOMITO_CI10586_CHAIN_INFO; + +// Observed 10.0.14393.2189, 15063.0, 16299.125 and 17134.1130 x64. +// The variable payload begins at +0x68. Constructor evidence establishes the +// 32-byte extension's space, not its semantic contents on every sampled build. +typedef struct _DOMITO_CI14393_CHAIN_INFO +{ + UINT32 Size; + MINCERT_BLOB* PublicKeys; + UINT32 NumberOfPublicKeys; + MINCERT_BLOB* EKUs; + UINT32 NumberOfEKUs; + PVOID ChainElements; + UINT32 NumberOfChainElements; + UINT32 RootId; + MINCRYPT_ATTR_BLOB AuthenticodeAttributes; + UINT8 ReservedExtension[32]; +} DOMITO_CI14393_CHAIN_INFO, *PDOMITO_CI14393_CHAIN_INFO; +#pragma pack(pop) + +C_ASSERT(sizeof(DOMITO_CI10240_CHAIN_INFO) == 56); +C_ASSERT(FIELD_OFFSET(DOMITO_CI10240_CHAIN_INFO, PublicKeys) == 8); +C_ASSERT(FIELD_OFFSET(DOMITO_CI10240_CHAIN_INFO, EKUs) == 24); +C_ASSERT(FIELD_OFFSET(DOMITO_CI10240_CHAIN_INFO, ChainElements) == 40); +C_ASSERT(FIELD_OFFSET(DOMITO_CI10240_CHAIN_INFO, RootId) == 52); +C_ASSERT(sizeof(DOMITO_CI10586_CHAIN_INFO) == 72); +C_ASSERT(FIELD_OFFSET(DOMITO_CI10586_CHAIN_INFO, RootId) == 52); +C_ASSERT(FIELD_OFFSET(DOMITO_CI10586_CHAIN_INFO, AuthenticodeAttributes) == 56); +C_ASSERT(sizeof(DOMITO_CI14393_CHAIN_INFO) == 104); +C_ASSERT(FIELD_OFFSET(DOMITO_CI14393_CHAIN_INFO, RootId) == 52); +C_ASSERT(FIELD_OFFSET(DOMITO_CI14393_CHAIN_INFO, AuthenticodeAttributes) == 56); +C_ASSERT(FIELD_OFFSET(DOMITO_CI14393_CHAIN_INFO, ReservedExtension) == 72); diff --git a/include/Domito.MinCrypt.h b/include/Domito.MinCrypt.h index 78d54d4..7a879ff 100644 --- a/include/Domito.MinCrypt.h +++ b/include/Domito.MinCrypt.h @@ -322,12 +322,17 @@ typedef struct _MINCRYPT_CHAIN_INFO PMINCRYPT_CHAIN_ELEMENT ChainElements; UINT32 NumberOfChainElement; - // ASN.1 blob of authenticated attributes - spcSpOpusInfo, contentType, etc. + // REQUIRES a confirmed runtime layout (10586 and later sampled profiles). + // Sampled 10240 has only 56 header bytes: +0x38 begins variable payload. + // NTDDI_VERSION and allocation Size cannot establish field availability. + // See Domito.MinCrypt.Historical.h for distinct observed x64 prefix views. MINCRYPT_ATTR_BLOB AuthenticodeAttributes; - // Observed 26100 x64 adds RootId at +0x34 and a 32-byte platform-manifest - // binary ID at +0x48. These are exposed only by Domito.MinCrypt.26100.h. - // Do not infer their availability solely from NTDDI_VERSION or Size. + // RootId occupies padding at +0x34 in all six historical x64 samples and + // 26100. The historical views name it without extending this default layout. + // 26100's 32-byte platform-manifest binary ID at +0x48 is named only in its + // explicit version header. Earlier 104-byte views reserve that extension. + // Do not infer field availability solely from NTDDI_VERSION or Size. #endif // NTDDI_VERSION >= NTDDI_WIN10 @@ -518,7 +523,10 @@ MINCRYPT_ALLOCATE_ROUTINE( typedef MINCRYPT_ALLOCATE_ROUTINE* PMINCRYPT_ALLOCATE_ROUTINE; /** -* Parse the publisher name from the certificate +* Parse the publisher name from the certificate. +* Export absent from sampled Windows 10 x64 builds 10240–17134; observed present +* on 19041.1865, 22000.318 and 26100 x64; absent on sampled 19041.1 x64. +* The NTDDI guard does not establish runtime availability. See NOTES.md. * * @param Certificate - &PolicyInfo.ChainInfo->ChainElements[x].Certificate * @@ -541,6 +549,8 @@ CiGetCertPublisherName( ); +// Export observed already in 15063.0 x64 (1703); absent from sampled +// 10240/10586/14393 files. This writes CI-global state, not per-file policy. MINCRYPTAPI VOID NTAPI @@ -550,7 +560,8 @@ CiSetTrustedOriginClaimId( // Domito descriptive name, not an official Microsoft flag name. // Observed on CI 10.0.26100.8328 x64: broadens the accepted-root mask in -// CipGetAcceptedRootKeys. This is not a WinVerifyTrust-equivalent trust policy. +// CipGetAcceptedRootKeys. Sampled 1709/1803 instead select 0x224FF; earlier helper +// generations differ. This is not a WinVerifyTrust-equivalent trust policy. // See docs/ci-validate-file-object.md for evidence and version limitations. #define DOMITO_CI_VALIDATE_FLAG_BROADEN_ROOT_ACCEPTANCE 0x00000020UL diff --git a/src/Domito.vcxproj b/src/Domito.vcxproj index 83e45d4..b46a46c 100644 --- a/src/Domito.vcxproj +++ b/src/Domito.vcxproj @@ -128,6 +128,7 @@ + diff --git a/src/Domito.vcxproj.filters b/src/Domito.vcxproj.filters index 08dd0ce..3483c2f 100644 --- a/src/Domito.vcxproj.filters +++ b/src/Domito.vcxproj.filters @@ -42,6 +42,9 @@ Header Files\Public + + Header Files\Public + Header Files\Public diff --git a/tests/mincrypt-layout-tests.cpp b/tests/mincrypt-layout-tests.cpp index d01539b..39c6903 100644 --- a/tests/mincrypt-layout-tests.cpp +++ b/tests/mincrypt-layout-tests.cpp @@ -21,4 +21,5 @@ C_ASSERT(FIELD_OFFSET(MINCRYPT_CHAIN_ELEMENT, Certificate) == 104); #if defined(_M_AMD64) // These opt-in declarations establish observations only for the named x64 build. #include "Domito.MinCrypt.26100.h" +#include "Domito.MinCrypt.Historical.h" #endif