-
Notifications
You must be signed in to change notification settings - Fork 17
Extending the Tool
Kriyos Arcane edited this page Jul 4, 2026
·
1 revision
For contributors and researchers.
Every file type that Windows verifies through WinVerifyTrust has a SIP GUID. The GUID maps to a DLL and a set of functions (verify, sign, hash, etc.) registered in:
HKLM\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDll*\{GUID}
The CryptSIPDllVerifyIndirectData subkey holds the verification function. This is what TrustMeBro redirects.
- Open
wintrust.dllin Ghidra or IDA - Search for the builtin GUID table in
.rdata. On Win11 24H2, it starts at offset0x62410 - Each entry has a 16-byte GUID followed by function pointers
- Cross-reference the function pointers to find the handler DLL and function name
- Check
CryptSIPDllIsMyFileType2registrations in the registry for non-builtin SIPs (AppxSip, EsdSip, pwrshsip, wshext, MSISIP)
The full 19-GUID map is at docs/SIP_COMPLETE_MAP.md.
- Add the entry to
ALL_STANDARD_SIPS[]insteal.h - Add the alias to
GUID_ALIASES[]inmain.cpp - Increment
NUM_STANDARD_SIPSif adding to the standard set
- Add the entry to the
SIPSdict - Add the alias to the
GUID_ALIASESdict
- Add the entry to the
GUID_ALIASES[]array intmb_bof.h
tmb_bof.h provides:
-
NT API resolution: resolves NtOpenKey, NtCreateKey, NtSetValueKey, NtDeleteKey, NtClose, NtQuerySystemInformation from ntdll exports via GetProcAddress. The
tmb_init()function populates a globalTMB_NTAPIstruct. -
FNV-1a hashing:
fnv1a()function for string-free API resolution. Pre-computed hashes for NT functions are defined as constants. -
Stack string macros:
WSTR_INIT()builds wide strings on the stack character by character. Named macros likeSTR_WINTRUST(),STR_DBGUICONTINUE()provide common strings without .rdata literals. -
GUID alias table:
GUID_ALIASES[]array withtmb_resolve_alias()for case-insensitive lookup. -
Registry helpers:
tmb_reg_open(),tmb_reg_set_sz(),tmb_reg_delete(),tmb_reg_write_sip()wrap NT API calls with UNICODE_STRING handling. -
Path builders:
tmb_build_sip_path(),tmb_build_finalpolicy_path(),tmb_build_ismyfiletype_path(),tmb_build_formatobject_path()construct registry paths on the stack. -
Output helpers:
TMB_OK(),TMB_ERR(),TMB_WARN(),TMB_INFO(),TMB_NTERR()wrapBeaconPrintfwith consistent formatting.
- Create
bofs/src/tmb_yourname.c - Include
tmb_bof.h - Implement
void go(char *args, int alen)as the entry point - Use
BeaconDataParsefor argument parsing - Call
tmb_init()before any NT API call - Use
TMB_OK/TMB_ERRfor output - Compile:
x86_64-w64-mingw32-gcc -o bofs/bin/tmb_yourname.o -c bofs/src/tmb_yourname.c -I bofs/include -Wall -Wno-unused-function - Add the command to
cna/tmb.cnaandaxscript/tmb.axscript
Generates a self-signed cert with a chosen Common Name. Combined with FinalPolicy hijack, the UAC dialog shows the chosen publisher name.
What it needs to become production-ready:
- Auto-enrollment of the cert in TrustedPublisher store (currently prints manual steps)
- Auto-signing of the target PE with osslsigncode
- Integration with the
stealsubcommand
Documentation only. Describes the parser divergence: kernel ci.dll reads SignerInfo[0], user-mode wintrust iterates all SignerInfo entries.
What it needs to become production-ready:
- ASN.1 surgery code to inject a second SignerInfo into a PKCS#7 structure
- Lab testing on Win11 24H2 to verify the kernel stride is still 0xF0
- Verification that user-mode tools report the second (benign) signer as the primary