Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1508 lines
33 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. RegistryChecks.cpp
  5. Abstract:
  6. Warn the app when it's trying to read from or write to inappropriate
  7. places in the registry.
  8. Notes:
  9. This is a general purpose shim.
  10. History:
  11. 03/09/2001 maonis Created
  12. 09/04/2001 maonis Since none of the paths we compare with exceed MAX_PATH - 1
  13. characters, we only examine at most that many characters of
  14. the key paths to make sure there's no buffer overflow in
  15. the paths of open keys.
  16. --*/
  17. #include "precomp.h"
  18. IMPLEMENT_SHIM_BEGIN(RegistryChecks)
  19. #include "ShimHookMacro.h"
  20. #include "RegistryChecks.h"
  21. //
  22. // verifier log entries
  23. //
  24. BEGIN_DEFINE_VERIFIER_LOG(RegistryChecks)
  25. VERIFIER_LOG_ENTRY(VLOG_HKCU_Console_READ)
  26. VERIFIER_LOG_ENTRY(VLOG_HKCU_ControlPanel_READ)
  27. VERIFIER_LOG_ENTRY(VLOG_HKCU_Environment_READ)
  28. VERIFIER_LOG_ENTRY(VLOG_HKCU_Identities_READ)
  29. VERIFIER_LOG_ENTRY(VLOG_HKCU_KeyboardLayout_READ)
  30. VERIFIER_LOG_ENTRY(VLOG_HKCU_Printers_READ)
  31. VERIFIER_LOG_ENTRY(VLOG_HKCU_RemoteAccess_READ)
  32. VERIFIER_LOG_ENTRY(VLOG_HKCU_SessionInformation_READ)
  33. VERIFIER_LOG_ENTRY(VLOG_HKCU_UNICODEProgramGroups_READ)
  34. VERIFIER_LOG_ENTRY(VLOG_HKCU_VolatileEnvironment_READ)
  35. VERIFIER_LOG_ENTRY(VLOG_HKCU_Windows31MigrationStatus_READ)
  36. VERIFIER_LOG_ENTRY(VLOG_HKLM_HARDWARE_READ)
  37. VERIFIER_LOG_ENTRY(VLOG_HKLM_SAM_READ)
  38. VERIFIER_LOG_ENTRY(VLOG_HKLM_SECURITY_READ)
  39. VERIFIER_LOG_ENTRY(VLOG_HKLM_SYSTEM_READ)
  40. VERIFIER_LOG_ENTRY(VLOG_HKCC_READ)
  41. VERIFIER_LOG_ENTRY(VLOG_HKUS_READ)
  42. VERIFIER_LOG_ENTRY(VLOG_NON_HKCU_WRITE)
  43. END_DEFINE_VERIFIER_LOG(RegistryChecks)
  44. INIT_VERIFIER_LOG(RegistryChecks);
  45. const RCWARNING g_warnNoDirectRead[] =
  46. {
  47. {HKCU_Console_STR, VLOG_HKCU_Console_READ, NUM_OF_CHAR(HKCU_Console_STR)},
  48. {HKCU_ControlPanel_STR, VLOG_HKCU_ControlPanel_READ, NUM_OF_CHAR(HKCU_ControlPanel_STR)},
  49. {HKCU_Environment_STR, VLOG_HKCU_Environment_READ, NUM_OF_CHAR(HKCU_Environment_STR)},
  50. {HKCU_Identities_STR, VLOG_HKCU_Identities_READ, NUM_OF_CHAR(HKCU_Identities_STR)},
  51. {HKCU_KeyboardLayout_STR, VLOG_HKCU_KeyboardLayout_READ, NUM_OF_CHAR(HKCU_KeyboardLayout_STR)},
  52. {HKCU_Printers_STR, VLOG_HKCU_Printers_READ, NUM_OF_CHAR(HKCU_Printers_STR)},
  53. {HKCU_RemoteAccess_STR, VLOG_HKCU_RemoteAccess_READ, NUM_OF_CHAR(HKCU_RemoteAccess_STR)},
  54. {HKCU_SessionInformation_STR, VLOG_HKCU_SessionInformation_READ, NUM_OF_CHAR(HKCU_SessionInformation_STR)},
  55. {HKCU_UNICODEProgramGroups_STR, VLOG_HKCU_UNICODEProgramGroups_READ, NUM_OF_CHAR(HKCU_UNICODEProgramGroups_STR)},
  56. {HKCU_VolatileEnvironment_STR, VLOG_HKCU_VolatileEnvironment_READ, NUM_OF_CHAR(HKCU_VolatileEnvironment_STR)},
  57. {HKCU_Windows31MigrationStatus_STR, VLOG_HKCU_Windows31MigrationStatus_READ,NUM_OF_CHAR(HKCU_Windows31MigrationStatus_STR)},
  58. {HKLM_HARDWARE_STR, VLOG_HKLM_HARDWARE_READ, NUM_OF_CHAR(HKLM_HARDWARE_STR)},
  59. {HKLM_SAM_STR, VLOG_HKLM_SAM_READ, NUM_OF_CHAR(HKLM_SAM_STR)},
  60. {HKLM_SECURITY_STR, VLOG_HKLM_SECURITY_READ, NUM_OF_CHAR(HKLM_SECURITY_STR)},
  61. {HKLM_SYSTEM_STR, VLOG_HKLM_SYSTEM_READ, NUM_OF_CHAR(HKLM_SYSTEM_STR)},
  62. {HKCC_STR, VLOG_HKCC_READ, NUM_OF_CHAR(HKCC_STR)},
  63. {HKUS_STR, VLOG_HKUS_READ, NUM_OF_CHAR(HKUS_STR)},
  64. };
  65. const UINT g_cWarnNDirectRead = sizeof(g_warnNoDirectRead) / sizeof(RCWARNING);
  66. VOID
  67. MakePathW(
  68. IN RCOPENKEY* key,
  69. IN HKEY hKey,
  70. IN LPCWSTR lpSubKey,
  71. IN OUT LPWSTR lpPath
  72. )
  73. {
  74. if (key) {
  75. if (key->wszPath[0]) {
  76. //
  77. // We only care about at most MAX_PATH - 1 characters.
  78. //
  79. wcsncpy(lpPath, key->wszPath, MAX_PATH - 1);
  80. }
  81. } else {
  82. if (hKey == HKEY_CLASSES_ROOT) {
  83. wcscpy(lpPath, L"HKCR");
  84. } else if (hKey == HKEY_CURRENT_CONFIG) {
  85. wcscpy(lpPath, L"HKCC");
  86. } else if (hKey == HKEY_CURRENT_USER) {
  87. wcscpy(lpPath, L"HKCU");
  88. } else if (hKey == HKEY_LOCAL_MACHINE) {
  89. wcscpy(lpPath, L"HKLM");
  90. } else if (hKey == HKEY_USERS) {
  91. wcscpy(lpPath, L"HKUS");
  92. } else {
  93. wcscpy(lpPath, L"Not recognized");
  94. }
  95. }
  96. if (lpSubKey && *lpSubKey) {
  97. DWORD cLen = wcslen(lpPath);
  98. //
  99. // We only care about at most MAX_PATH - 1 characters.
  100. //
  101. if (cLen < MAX_PATH - 1) {
  102. lpPath[cLen] = L'\\';
  103. wcsncpy(lpPath + cLen + 1, lpSubKey, MAX_PATH - cLen - 2);
  104. }
  105. }
  106. lpPath[MAX_PATH - 1] = L'\0';
  107. }
  108. VOID CheckReading(
  109. IN LPCWSTR pwszPath
  110. )
  111. {
  112. RCWARNING warn;
  113. for (UINT ui = 0; ui < g_cWarnNDirectRead; ++ui) {
  114. warn = g_warnNoDirectRead[ui];
  115. if (!_wcsnicmp(pwszPath, warn.wszPath, warn.cLen)) {
  116. VLOG(VLOG_LEVEL_ERROR, warn.dwAVStatus, "Read from dangerous registry entry '%ls'.", pwszPath);
  117. }
  118. }
  119. }
  120. // We warn for every tempt of writing to anything besides keys under HKCU.
  121. // Note this applies to both Users and Admins/Power Users because when an
  122. // app is running it shouldn't write anything to non HKCU keys, which should
  123. // be done during the installation time.
  124. VOID CheckWriting(
  125. IN REGSAM samDesired,
  126. IN LPCWSTR pwszPath
  127. )
  128. {
  129. if ((samDesired &~ STANDARD_RIGHTS_WRITE) & KEY_WRITE) {
  130. if (_wcsnicmp(pwszPath, L"HKCU", 4)) {
  131. VLOG(VLOG_LEVEL_ERROR, VLOG_NON_HKCU_WRITE, "Write to non-HKCU registry entry '%ls'.", pwszPath);
  132. }
  133. }
  134. }
  135. //
  136. // simple locking.
  137. //
  138. static BOOL g_bInitialized = FALSE;
  139. CRITICAL_SECTION g_csRegRedirect;
  140. class CRRegLock
  141. {
  142. public:
  143. CRRegLock()
  144. {
  145. if (!g_bInitialized) {
  146. InitializeCriticalSection(&g_csRegRedirect);
  147. g_bInitialized = TRUE;
  148. }
  149. EnterCriticalSection(&g_csRegRedirect);
  150. }
  151. ~CRRegLock()
  152. {
  153. LeaveCriticalSection(&g_csRegRedirect);
  154. }
  155. };
  156. //
  157. // Implementation of the CRegistryChecks class.
  158. //
  159. RCOPENKEY*
  160. CRegistryChecks::FindKey(
  161. HKEY hKey
  162. )
  163. {
  164. RCOPENKEY* key = keys;
  165. while (key) {
  166. if (key->hkBase == hKey) {
  167. return key;
  168. }
  169. key = key->next;
  170. }
  171. return NULL;
  172. }
  173. // We add the key to the front of the list because the most
  174. // recently added keys are usually used/deleted first.
  175. BOOL
  176. CRegistryChecks::AddKey(
  177. HKEY hKey,
  178. LPCWSTR pwszPath
  179. )
  180. {
  181. RCOPENKEY* key = new RCOPENKEY;
  182. if (!key) {
  183. return FALSE;
  184. }
  185. key->hkBase = hKey;
  186. //
  187. // None of the key paths we need to check exceed MAX_PATH - 1 characters so
  188. // we only need to copy at most that many characters.
  189. //
  190. wcsncpy(key->wszPath, pwszPath, MAX_PATH - 1);
  191. key->wszPath[MAX_PATH - 1] = L'\0';
  192. key->next = keys;
  193. keys = key;
  194. return TRUE;
  195. }
  196. VOID
  197. CRegistryChecks::Check(
  198. HKEY hKey,
  199. LPCSTR lpSubKey,
  200. BOOL fCheckRead,
  201. BOOL fCheckWrite,
  202. REGSAM samDesired
  203. )
  204. {
  205. LPWSTR pwszSubKey = NULL;
  206. if (pwszSubKey = ToUnicode(lpSubKey)) {
  207. Check(hKey, pwszSubKey, fCheckRead, fCheckWrite);
  208. free(pwszSubKey);
  209. } else {
  210. DPFN(eDbgLevelError, "Failed to convert %s to unicode", lpSubKey);
  211. }
  212. }
  213. VOID
  214. CRegistryChecks::Check(
  215. HKEY hKey,
  216. LPCWSTR lpSubKey,
  217. BOOL fCheckRead,
  218. BOOL fCheckWrite,
  219. REGSAM samDesired
  220. )
  221. {
  222. RCOPENKEY* key = FindKey(hKey);
  223. WCHAR wszPath[MAX_PATH] = L"";
  224. MakePathW(key, hKey, lpSubKey, wszPath);
  225. if (fCheckRead) {
  226. CheckReading(wszPath);
  227. }
  228. if (fCheckWrite) {
  229. CheckWriting(samDesired, wszPath);
  230. }
  231. }
  232. LONG
  233. CRegistryChecks::OpenKeyExOriginalW(
  234. HKEY hKey,
  235. LPCWSTR lpSubKey,
  236. LPWSTR lpClass,
  237. DWORD dwOptions,
  238. REGSAM samDesired,
  239. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  240. PHKEY phkResult,
  241. LPDWORD lpdwDisposition,
  242. BOOL bCreate
  243. )
  244. {
  245. if (bCreate) {
  246. return ORIGINAL_API(RegCreateKeyExW)(
  247. hKey,
  248. lpSubKey,
  249. 0,
  250. lpClass,
  251. dwOptions,
  252. samDesired,
  253. lpSecurityAttributes,
  254. phkResult,
  255. lpdwDisposition);
  256. } else {
  257. return ORIGINAL_API(RegOpenKeyExW)(
  258. hKey,
  259. lpSubKey,
  260. 0,
  261. samDesired,
  262. phkResult);
  263. }
  264. }
  265. LONG
  266. CRegistryChecks::OpenKeyExA(
  267. HKEY hKey,
  268. LPCSTR lpSubKey,
  269. LPSTR lpClass,
  270. DWORD dwOptions,
  271. REGSAM samDesired,
  272. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  273. PHKEY phkResult,
  274. LPDWORD lpdwDisposition,
  275. BOOL bCreate
  276. )
  277. {
  278. LONG lRet;
  279. LPWSTR pwszSubKey = NULL;
  280. LPWSTR pwszClass = NULL;
  281. if (lpSubKey) {
  282. if (!(pwszSubKey = ToUnicode(lpSubKey))) {
  283. DPFN(eDbgLevelError, "Failed to convert %s to unicode", lpSubKey);
  284. return ERROR_NOT_ENOUGH_MEMORY;
  285. }
  286. }
  287. if (lpClass) {
  288. if (!(pwszClass = ToUnicode(lpClass)))
  289. {
  290. free(pwszSubKey);
  291. DPFN(eDbgLevelError, "Failed to convert %s to unicode", lpClass);
  292. return ERROR_NOT_ENOUGH_MEMORY;
  293. }
  294. }
  295. lRet = OpenKeyExW(
  296. hKey,
  297. pwszSubKey,
  298. pwszClass,
  299. dwOptions,
  300. samDesired,
  301. lpSecurityAttributes,
  302. phkResult,
  303. lpdwDisposition,
  304. bCreate);
  305. free(pwszSubKey);
  306. free(pwszClass);
  307. return lRet;
  308. }
  309. LONG
  310. CRegistryChecks::OpenKeyExW(
  311. HKEY hKey,
  312. LPCWSTR lpSubKey,
  313. LPWSTR lpClass,
  314. DWORD dwOptions,
  315. REGSAM samDesired,
  316. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  317. PHKEY phkResult,
  318. LPDWORD lpdwDisposition,
  319. BOOL bCreate
  320. )
  321. {
  322. RCOPENKEY* key = FindKey(hKey);
  323. WCHAR wszPath[MAX_PATH] = L"";
  324. MakePathW(key, hKey, lpSubKey, wszPath);
  325. CheckReading(wszPath);
  326. CheckWriting(samDesired, wszPath);
  327. LONG lRes = OpenKeyExOriginalW(
  328. hKey,
  329. lpSubKey,
  330. lpClass,
  331. dwOptions,
  332. samDesired,
  333. lpSecurityAttributes,
  334. phkResult,
  335. lpdwDisposition,
  336. bCreate);
  337. if (lRes == ERROR_SUCCESS) {
  338. if (AddKey(*phkResult, wszPath)) {
  339. DPFN(eDbgLevelInfo, "[OpenKeyExW] success - adding key 0x%08x", *phkResult);
  340. } else {
  341. lRes = ERROR_INVALID_HANDLE;
  342. }
  343. }
  344. return lRes;
  345. }
  346. LONG
  347. CRegistryChecks::QueryValueA(
  348. HKEY hKey,
  349. LPCSTR lpSubKey,
  350. LPSTR lpValue,
  351. PLONG lpcbValue
  352. )
  353. {
  354. Check(hKey, lpSubKey, TRUE, FALSE);
  355. return ORIGINAL_API(RegQueryValueA)(
  356. hKey,
  357. lpSubKey,
  358. lpValue,
  359. lpcbValue);
  360. }
  361. LONG
  362. CRegistryChecks::QueryValueW(
  363. HKEY hKey,
  364. LPCWSTR lpSubKey,
  365. LPWSTR lpValue,
  366. PLONG lpcbValue
  367. )
  368. {
  369. Check(hKey, lpSubKey, TRUE, FALSE);
  370. return ORIGINAL_API(RegQueryValueW)(
  371. hKey,
  372. lpSubKey,
  373. lpValue,
  374. lpcbValue);
  375. }
  376. LONG
  377. CRegistryChecks::QueryValueExA(
  378. HKEY hKey,
  379. LPCSTR lpValueName,
  380. LPDWORD lpReserved,
  381. LPDWORD lpType,
  382. LPBYTE lpData,
  383. LPDWORD lpcbData
  384. )
  385. {
  386. Check(hKey, L"", TRUE, FALSE);
  387. return ORIGINAL_API(RegQueryValueExA)(
  388. hKey,
  389. lpValueName,
  390. lpReserved,
  391. lpType,
  392. lpData,
  393. lpcbData);
  394. }
  395. LONG
  396. CRegistryChecks::QueryValueExW(
  397. HKEY hKey,
  398. LPCWSTR lpValueName,
  399. LPDWORD lpReserved,
  400. LPDWORD lpType,
  401. LPBYTE lpData,
  402. LPDWORD lpcbData
  403. )
  404. {
  405. Check(hKey, L"", TRUE, FALSE);
  406. return ORIGINAL_API(RegQueryValueExW)(
  407. hKey,
  408. lpValueName,
  409. lpReserved,
  410. lpType,
  411. lpData,
  412. lpcbData);
  413. }
  414. LONG
  415. CRegistryChecks::QueryInfoKeyA(
  416. HKEY hKey,
  417. LPSTR lpClass,
  418. LPDWORD lpcbClass,
  419. LPDWORD lpReserved,
  420. LPDWORD lpcSubKeys,
  421. LPDWORD lpcbMaxSubKeyLen,
  422. LPDWORD lpcbMaxClassLen,
  423. LPDWORD lpcValues,
  424. LPDWORD lpcbMaxValueNameLen,
  425. LPDWORD lpcbMaxValueLen,
  426. LPDWORD lpcbSecurityDescriptor,
  427. PFILETIME lpftLastWriteTime
  428. )
  429. {
  430. Check(hKey, L"", TRUE, FALSE);
  431. return ORIGINAL_API(RegQueryInfoKeyA)(
  432. hKey,
  433. lpClass,
  434. lpcbClass,
  435. lpReserved,
  436. lpcSubKeys,
  437. lpcbMaxSubKeyLen,
  438. lpcbMaxClassLen,
  439. lpcValues,
  440. lpcbMaxValueNameLen,
  441. lpcbMaxValueLen,
  442. lpcbSecurityDescriptor,
  443. lpftLastWriteTime);
  444. }
  445. LONG
  446. CRegistryChecks::QueryInfoKeyW(
  447. HKEY hKey,
  448. LPWSTR lpClass,
  449. LPDWORD lpcbClass,
  450. LPDWORD lpReserved,
  451. LPDWORD lpcSubKeys,
  452. LPDWORD lpcbMaxSubKeyLen,
  453. LPDWORD lpcbMaxClassLen,
  454. LPDWORD lpcValues,
  455. LPDWORD lpcbMaxValueNameLen,
  456. LPDWORD lpcbMaxValueLen,
  457. LPDWORD lpcbSecurityDescriptor,
  458. PFILETIME lpftLastWriteTime
  459. )
  460. {
  461. Check(hKey, L"", TRUE, FALSE);
  462. return ORIGINAL_API(RegQueryInfoKeyW)(
  463. hKey,
  464. lpClass,
  465. lpcbClass,
  466. lpReserved,
  467. lpcSubKeys,
  468. lpcbMaxSubKeyLen,
  469. lpcbMaxClassLen,
  470. lpcValues,
  471. lpcbMaxValueNameLen,
  472. lpcbMaxValueLen,
  473. lpcbSecurityDescriptor,
  474. lpftLastWriteTime);
  475. }
  476. LONG
  477. CRegistryChecks::SetValueA(
  478. HKEY hKey,
  479. LPCSTR lpSubKey,
  480. DWORD dwType,
  481. LPCSTR lpData,
  482. DWORD cbData
  483. )
  484. {
  485. Check(hKey, lpSubKey, FALSE, TRUE, KEY_WRITE);
  486. return ORIGINAL_API(RegSetValueA)(
  487. hKey,
  488. lpSubKey,
  489. dwType,
  490. lpData,
  491. cbData);
  492. }
  493. LONG
  494. CRegistryChecks::SetValueW(
  495. HKEY hKey,
  496. LPCWSTR lpSubKey,
  497. DWORD dwType,
  498. LPCWSTR lpData,
  499. DWORD cbData
  500. )
  501. {
  502. Check(hKey, lpSubKey, FALSE, TRUE, KEY_WRITE);
  503. return ORIGINAL_API(RegSetValueW)(
  504. hKey,
  505. lpSubKey,
  506. dwType,
  507. lpData,
  508. cbData);
  509. }
  510. LONG
  511. CRegistryChecks::SetValueExA(
  512. HKEY hKey,
  513. LPCSTR lpValueName,
  514. DWORD Reserved,
  515. DWORD dwType,
  516. CONST BYTE * lpData,
  517. DWORD cbData
  518. )
  519. {
  520. Check(hKey, L"", FALSE, TRUE, KEY_WRITE);
  521. return ORIGINAL_API(RegSetValueExA)(
  522. hKey,
  523. lpValueName,
  524. Reserved,
  525. dwType,
  526. lpData,
  527. cbData);
  528. }
  529. LONG
  530. CRegistryChecks::SetValueExW(
  531. HKEY hKey,
  532. LPCWSTR lpValueName,
  533. DWORD Reserved,
  534. DWORD dwType,
  535. CONST BYTE * lpData,
  536. DWORD cbData
  537. )
  538. {
  539. Check(hKey, L"", FALSE, TRUE, KEY_WRITE);
  540. return ORIGINAL_API(RegSetValueExW)(
  541. hKey,
  542. lpValueName,
  543. Reserved,
  544. dwType,
  545. lpData,
  546. cbData);
  547. }
  548. LONG
  549. CRegistryChecks::EnumValueA(
  550. HKEY hKey,
  551. DWORD dwIndex,
  552. LPSTR lpValueName,
  553. LPDWORD lpcbValueName,
  554. LPDWORD lpReserved,
  555. LPDWORD lpType,
  556. LPBYTE lpData,
  557. LPDWORD lpcbData
  558. )
  559. {
  560. Check(hKey, L"", TRUE, FALSE);
  561. return ORIGINAL_API(RegEnumValueA)(
  562. hKey,
  563. dwIndex,
  564. lpValueName,
  565. lpcbValueName,
  566. lpReserved,
  567. lpType,
  568. lpData,
  569. lpcbData);
  570. }
  571. // If the key was not originated from HKCU,
  572. // we enum at the original location.
  573. LONG
  574. CRegistryChecks::EnumValueW(
  575. HKEY hKey,
  576. DWORD dwIndex,
  577. LPWSTR lpValueName,
  578. LPDWORD lpcbValueName,
  579. LPDWORD lpReserved,
  580. LPDWORD lpType,
  581. LPBYTE lpData,
  582. LPDWORD lpcbData
  583. )
  584. {
  585. Check(hKey, L"", TRUE, FALSE);
  586. return ORIGINAL_API(RegEnumValueW)(
  587. hKey,
  588. dwIndex,
  589. lpValueName,
  590. lpcbValueName,
  591. lpReserved,
  592. lpType,
  593. lpData,
  594. lpcbData);
  595. }
  596. LONG
  597. CRegistryChecks::EnumKeyExA(
  598. HKEY hKey,
  599. DWORD dwIndex,
  600. LPSTR lpName,
  601. LPDWORD lpcbName,
  602. LPDWORD lpReserved,
  603. LPSTR lpClass,
  604. LPDWORD lpcbClass,
  605. PFILETIME lpftLastWriteTime
  606. )
  607. {
  608. Check(hKey, L"", TRUE, FALSE);
  609. return ORIGINAL_API(RegEnumKeyExA)(
  610. hKey,
  611. dwIndex,
  612. lpName,
  613. lpcbName,
  614. lpReserved,
  615. lpClass,
  616. lpcbClass,
  617. lpftLastWriteTime);
  618. }
  619. // If the key was not originated from HKCU,
  620. // we enum at the original location.
  621. LONG
  622. CRegistryChecks::EnumKeyExW(
  623. HKEY hKey,
  624. DWORD dwIndex,
  625. LPWSTR lpName,
  626. LPDWORD lpcbName,
  627. LPDWORD lpReserved,
  628. LPWSTR lpClass,
  629. LPDWORD lpcbClass,
  630. PFILETIME lpftLastWriteTime
  631. )
  632. {
  633. Check(hKey, L"", TRUE, FALSE);
  634. return ORIGINAL_API(RegEnumKeyExW)(
  635. hKey,
  636. dwIndex,
  637. lpName,
  638. lpcbName,
  639. lpReserved,
  640. lpClass,
  641. lpcbClass,
  642. lpftLastWriteTime);
  643. }
  644. // Remove the key from the list.
  645. LONG
  646. CRegistryChecks::CloseKey(
  647. HKEY hKey
  648. )
  649. {
  650. RCOPENKEY* key = keys;
  651. RCOPENKEY* last = NULL;
  652. while (key) {
  653. if (key->hkBase == hKey) {
  654. if (last) {
  655. last->next = key->next;
  656. } else {
  657. keys = key->next;
  658. }
  659. delete key;
  660. break;
  661. }
  662. last = key;
  663. key = key->next;
  664. }
  665. DPFN(eDbgLevelInfo, "[CloseKey] closing key 0x%08x", hKey);
  666. return ORIGINAL_API(RegCloseKey)(hKey);
  667. }
  668. LONG
  669. CRegistryChecks::DeleteKeyA(
  670. HKEY hKey,
  671. LPCSTR lpSubKey
  672. )
  673. {
  674. Check(hKey, lpSubKey, FALSE, TRUE, KEY_WRITE);
  675. return ORIGINAL_API(RegDeleteKeyA)(
  676. hKey,
  677. lpSubKey);
  678. }
  679. LONG
  680. CRegistryChecks::DeleteKeyW(
  681. HKEY hKey,
  682. LPCWSTR lpSubKey
  683. )
  684. {
  685. Check(hKey, lpSubKey, FALSE, TRUE, KEY_WRITE);
  686. return ORIGINAL_API(RegDeleteKeyW)(
  687. hKey,
  688. lpSubKey);
  689. }
  690. CRegistryChecks RRegistry;
  691. //
  692. // Hook APIs.
  693. //
  694. LONG
  695. APIHOOK(RegOpenKeyA)(
  696. HKEY hKey,
  697. LPSTR lpSubKey,
  698. PHKEY phkResult
  699. )
  700. {
  701. CRRegLock Lock;
  702. return RRegistry.OpenKeyExA(
  703. hKey,
  704. lpSubKey,
  705. 0,
  706. REG_OPTION_NON_VOLATILE,
  707. MAXIMUM_ALLOWED,
  708. NULL,
  709. phkResult,
  710. NULL,
  711. FALSE);
  712. }
  713. LONG
  714. APIHOOK(RegOpenKeyW)(
  715. HKEY hKey,
  716. LPWSTR lpSubKey,
  717. PHKEY phkResult
  718. )
  719. {
  720. CRRegLock Lock;
  721. return RRegistry.OpenKeyExW(
  722. hKey,
  723. lpSubKey,
  724. 0,
  725. REG_OPTION_NON_VOLATILE,
  726. MAXIMUM_ALLOWED,
  727. NULL,
  728. phkResult,
  729. NULL,
  730. FALSE);
  731. }
  732. LONG
  733. APIHOOK(RegOpenKeyExA)(
  734. HKEY hKey,
  735. LPCSTR lpSubKey,
  736. DWORD ulOptions,
  737. REGSAM samDesired,
  738. PHKEY phkResult
  739. )
  740. {
  741. CRRegLock Lock;
  742. return RRegistry.OpenKeyExA(
  743. hKey,
  744. lpSubKey,
  745. 0,
  746. REG_OPTION_NON_VOLATILE,
  747. samDesired,
  748. NULL,
  749. phkResult,
  750. NULL,
  751. FALSE);
  752. }
  753. LONG
  754. APIHOOK(RegOpenKeyExW)(
  755. HKEY hKey,
  756. LPCWSTR lpSubKey,
  757. DWORD ulOptions,
  758. REGSAM samDesired,
  759. PHKEY phkResult
  760. )
  761. {
  762. CRRegLock Lock;
  763. return RRegistry.OpenKeyExW(
  764. hKey,
  765. lpSubKey,
  766. 0,
  767. REG_OPTION_NON_VOLATILE,
  768. samDesired,
  769. NULL,
  770. phkResult,
  771. NULL,
  772. FALSE);
  773. }
  774. LONG
  775. APIHOOK(RegCreateKeyA)(
  776. HKEY hKey,
  777. LPCSTR lpSubKey,
  778. PHKEY phkResult
  779. )
  780. {
  781. CRRegLock Lock;
  782. return RRegistry.OpenKeyExA(
  783. hKey,
  784. lpSubKey,
  785. 0,
  786. REG_OPTION_NON_VOLATILE,
  787. MAXIMUM_ALLOWED,
  788. NULL,
  789. phkResult,
  790. NULL,
  791. TRUE);
  792. }
  793. LONG
  794. APIHOOK(RegCreateKeyW)(
  795. HKEY hKey,
  796. LPCWSTR lpSubKey,
  797. PHKEY phkResult
  798. )
  799. {
  800. CRRegLock Lock;
  801. return RRegistry.OpenKeyExW(
  802. hKey,
  803. lpSubKey,
  804. 0,
  805. REG_OPTION_NON_VOLATILE,
  806. MAXIMUM_ALLOWED,
  807. NULL,
  808. phkResult,
  809. NULL,
  810. TRUE);
  811. }
  812. LONG
  813. APIHOOK(RegCreateKeyExA)(
  814. HKEY hKey,
  815. LPCSTR lpSubKey,
  816. DWORD Reserved,
  817. LPSTR lpClass,
  818. DWORD dwOptions,
  819. REGSAM samDesired,
  820. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  821. PHKEY phkResult,
  822. LPDWORD lpdwDisposition
  823. )
  824. {
  825. CRRegLock Lock;
  826. return RRegistry.OpenKeyExA(
  827. hKey,
  828. lpSubKey,
  829. lpClass,
  830. dwOptions,
  831. samDesired,
  832. lpSecurityAttributes,
  833. phkResult,
  834. lpdwDisposition,
  835. TRUE);
  836. }
  837. LONG
  838. APIHOOK(RegCreateKeyExW)(
  839. HKEY hKey,
  840. LPCWSTR lpSubKey,
  841. DWORD Reserved,
  842. LPWSTR lpClass,
  843. DWORD dwOptions,
  844. REGSAM samDesired,
  845. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  846. PHKEY phkResult,
  847. LPDWORD lpdwDisposition
  848. )
  849. {
  850. CRRegLock Lock;
  851. return RRegistry.OpenKeyExW(
  852. hKey,
  853. lpSubKey,
  854. lpClass,
  855. dwOptions,
  856. samDesired,
  857. lpSecurityAttributes,
  858. phkResult,
  859. lpdwDisposition,
  860. TRUE);
  861. }
  862. LONG
  863. APIHOOK(RegQueryValueA)(
  864. HKEY hKey,
  865. LPCSTR lpSubKey,
  866. LPSTR lpValue,
  867. PLONG lpcbValue
  868. )
  869. {
  870. CRRegLock Lock;
  871. return RRegistry.QueryValueA(
  872. hKey,
  873. lpSubKey,
  874. lpValue,
  875. lpcbValue);
  876. }
  877. LONG
  878. APIHOOK(RegQueryValueW)(
  879. HKEY hKey,
  880. LPCWSTR lpSubKey,
  881. LPWSTR lpValue,
  882. PLONG lpcbValue
  883. )
  884. {
  885. CRRegLock Lock;
  886. return RRegistry.QueryValueW(
  887. hKey,
  888. lpSubKey,
  889. lpValue,
  890. lpcbValue);
  891. }
  892. LONG
  893. APIHOOK(RegQueryValueExA)(
  894. HKEY hKey,
  895. LPCSTR lpValueName,
  896. LPDWORD lpReserved,
  897. LPDWORD lpType,
  898. LPBYTE lpData,
  899. LPDWORD lpcbData
  900. )
  901. {
  902. CRRegLock Lock;
  903. return RRegistry.QueryValueExA(
  904. hKey,
  905. lpValueName,
  906. lpReserved,
  907. lpType,
  908. lpData,
  909. lpcbData);
  910. }
  911. LONG
  912. APIHOOK(RegQueryValueExW)(
  913. HKEY hKey,
  914. LPCWSTR lpValueName,
  915. LPDWORD lpReserved,
  916. LPDWORD lpType,
  917. LPBYTE lpData,
  918. LPDWORD lpcbData
  919. )
  920. {
  921. CRRegLock Lock;
  922. return RRegistry.QueryValueExW(
  923. hKey,
  924. lpValueName,
  925. lpReserved,
  926. lpType,
  927. lpData,
  928. lpcbData);
  929. }
  930. LONG
  931. APIHOOK(RegQueryInfoKeyA)(
  932. HKEY hKey,
  933. LPSTR lpClass,
  934. LPDWORD lpcbClass,
  935. LPDWORD lpReserved,
  936. LPDWORD lpcSubKeys,
  937. LPDWORD lpcbMaxSubKeyLen,
  938. LPDWORD lpcbMaxClassLen,
  939. LPDWORD lpcValues,
  940. LPDWORD lpcbMaxValueNameLen,
  941. LPDWORD lpcbMaxValueLen,
  942. LPDWORD lpcbSecurityDescriptor,
  943. PFILETIME lpftLastWriteTime
  944. )
  945. {
  946. CRRegLock Lock;
  947. return RRegistry.QueryInfoKeyA(
  948. hKey,
  949. lpClass,
  950. lpcbClass,
  951. lpReserved,
  952. lpcSubKeys,
  953. lpcbMaxSubKeyLen,
  954. lpcbMaxClassLen,
  955. lpcValues,
  956. lpcbMaxValueNameLen,
  957. lpcbMaxValueLen,
  958. lpcbSecurityDescriptor,
  959. lpftLastWriteTime);
  960. }
  961. LONG
  962. APIHOOK(RegQueryInfoKeyW)(
  963. HKEY hKey,
  964. LPWSTR lpClass,
  965. LPDWORD lpcbClass,
  966. LPDWORD lpReserved,
  967. LPDWORD lpcSubKeys,
  968. LPDWORD lpcbMaxSubKeyLen,
  969. LPDWORD lpcbMaxClassLen,
  970. LPDWORD lpcValues,
  971. LPDWORD lpcbMaxValueNameLen,
  972. LPDWORD lpcbMaxValueLen,
  973. LPDWORD lpcbSecurityDescriptor,
  974. PFILETIME lpftLastWriteTime
  975. )
  976. {
  977. CRRegLock Lock;
  978. return RRegistry.QueryInfoKeyW(
  979. hKey,
  980. lpClass,
  981. lpcbClass,
  982. lpReserved,
  983. lpcSubKeys,
  984. lpcbMaxSubKeyLen,
  985. lpcbMaxClassLen,
  986. lpcValues,
  987. lpcbMaxValueNameLen,
  988. lpcbMaxValueLen,
  989. lpcbSecurityDescriptor,
  990. lpftLastWriteTime);
  991. }
  992. LONG
  993. APIHOOK(RegSetValueA)(
  994. HKEY hKey,
  995. LPCSTR lpSubKey,
  996. DWORD dwType,
  997. LPCSTR lpData,
  998. DWORD cbData
  999. )
  1000. {
  1001. CRRegLock Lock;
  1002. return RRegistry.SetValueA(
  1003. hKey,
  1004. lpSubKey,
  1005. dwType,
  1006. lpData,
  1007. cbData);
  1008. }
  1009. LONG
  1010. APIHOOK(RegSetValueW)(
  1011. HKEY hKey,
  1012. LPCWSTR lpSubKey,
  1013. DWORD dwType,
  1014. LPCWSTR lpData,
  1015. DWORD cbData
  1016. )
  1017. {
  1018. CRRegLock Lock;
  1019. return RRegistry.SetValueW(
  1020. hKey,
  1021. lpSubKey,
  1022. dwType,
  1023. lpData,
  1024. cbData);
  1025. }
  1026. LONG
  1027. APIHOOK(RegSetValueExA)(
  1028. HKEY hKey,
  1029. LPCSTR lpSubKey,
  1030. DWORD Reserved,
  1031. DWORD dwType,
  1032. CONST BYTE * lpData,
  1033. DWORD cbData
  1034. )
  1035. {
  1036. CRRegLock Lock;
  1037. return RRegistry.SetValueExA(
  1038. hKey,
  1039. lpSubKey,
  1040. Reserved,
  1041. dwType,
  1042. lpData,
  1043. cbData);
  1044. }
  1045. LONG
  1046. APIHOOK(RegSetValueExW)(
  1047. HKEY hKey,
  1048. LPCWSTR lpSubKey,
  1049. DWORD Reserved,
  1050. DWORD dwType,
  1051. CONST BYTE * lpData,
  1052. DWORD cbData
  1053. )
  1054. {
  1055. CRRegLock Lock;
  1056. return RRegistry.SetValueExW(
  1057. hKey,
  1058. lpSubKey,
  1059. Reserved,
  1060. dwType,
  1061. lpData,
  1062. cbData);
  1063. }
  1064. LONG
  1065. APIHOOK(RegEnumValueA)(
  1066. HKEY hKey,
  1067. DWORD dwIndex,
  1068. LPSTR lpValueName,
  1069. LPDWORD lpcbValueName,
  1070. LPDWORD lpReserved,
  1071. LPDWORD lpType,
  1072. LPBYTE lpData,
  1073. LPDWORD lpcbData
  1074. )
  1075. {
  1076. CRRegLock Lock;
  1077. return RRegistry.EnumValueA(
  1078. hKey,
  1079. dwIndex,
  1080. lpValueName,
  1081. lpcbValueName,
  1082. lpReserved,
  1083. lpType,
  1084. lpData,
  1085. lpcbData);
  1086. }
  1087. LONG
  1088. APIHOOK(RegEnumValueW)(
  1089. HKEY hKey,
  1090. DWORD dwIndex,
  1091. LPWSTR lpValueName,
  1092. LPDWORD lpcbValueName,
  1093. LPDWORD lpReserved,
  1094. LPDWORD lpType,
  1095. LPBYTE lpData,
  1096. LPDWORD lpcbData
  1097. )
  1098. {
  1099. CRRegLock Lock;
  1100. return RRegistry.EnumValueW(
  1101. hKey,
  1102. dwIndex,
  1103. lpValueName,
  1104. lpcbValueName,
  1105. lpReserved,
  1106. lpType,
  1107. lpData,
  1108. lpcbData);
  1109. }
  1110. LONG
  1111. APIHOOK(RegEnumKeyA)(
  1112. HKEY hKey,
  1113. DWORD dwIndex,
  1114. LPSTR lpName,
  1115. DWORD cbName
  1116. )
  1117. {
  1118. CRRegLock Lock;
  1119. return RRegistry.EnumKeyExA(
  1120. hKey,
  1121. dwIndex,
  1122. lpName,
  1123. &cbName,
  1124. NULL,
  1125. NULL,
  1126. NULL,
  1127. NULL); // can this be null???
  1128. }
  1129. LONG
  1130. APIHOOK(RegEnumKeyW)(
  1131. HKEY hKey,
  1132. DWORD dwIndex,
  1133. LPWSTR lpName,
  1134. DWORD cbName
  1135. )
  1136. {
  1137. CRRegLock Lock;
  1138. return RRegistry.EnumKeyExW(
  1139. hKey,
  1140. dwIndex,
  1141. lpName,
  1142. &cbName,
  1143. NULL,
  1144. NULL,
  1145. NULL,
  1146. NULL);
  1147. }
  1148. LONG
  1149. APIHOOK(RegEnumKeyExA)(
  1150. HKEY hKey,
  1151. DWORD dwIndex,
  1152. LPSTR lpName,
  1153. LPDWORD lpcbName,
  1154. LPDWORD lpReserved,
  1155. LPSTR lpClass,
  1156. LPDWORD lpcbClass,
  1157. PFILETIME lpftLastWriteTime
  1158. )
  1159. {
  1160. CRRegLock Lock;
  1161. return RRegistry.EnumKeyExA(
  1162. hKey,
  1163. dwIndex,
  1164. lpName,
  1165. lpcbName,
  1166. lpReserved,
  1167. lpClass,
  1168. lpcbClass,
  1169. lpftLastWriteTime);
  1170. }
  1171. LONG
  1172. APIHOOK(RegEnumKeyExW)(
  1173. HKEY hKey,
  1174. DWORD dwIndex,
  1175. LPWSTR lpName,
  1176. LPDWORD lpcbName,
  1177. LPDWORD lpReserved,
  1178. LPWSTR lpClass,
  1179. LPDWORD lpcbClass,
  1180. PFILETIME lpftLastWriteTime
  1181. )
  1182. {
  1183. CRRegLock Lock;
  1184. return RRegistry.EnumKeyExW(
  1185. hKey,
  1186. dwIndex,
  1187. lpName,
  1188. lpcbName,
  1189. lpReserved,
  1190. lpClass,
  1191. lpcbClass,
  1192. lpftLastWriteTime);
  1193. }
  1194. LONG
  1195. APIHOOK(RegCloseKey)(HKEY hKey)
  1196. {
  1197. CRRegLock Lock;
  1198. return RRegistry.CloseKey(hKey);
  1199. }
  1200. LONG
  1201. APIHOOK(RegDeleteKeyA)(
  1202. HKEY hKey,
  1203. LPCSTR lpSubKey
  1204. )
  1205. {
  1206. CRRegLock Lock;
  1207. return RRegistry.DeleteKeyA(hKey, lpSubKey);
  1208. }
  1209. LONG
  1210. APIHOOK(RegDeleteKeyW)(
  1211. HKEY hKey,
  1212. LPCWSTR lpSubKey
  1213. )
  1214. {
  1215. CRRegLock Lock;
  1216. return RRegistry.DeleteKeyW(hKey, lpSubKey);
  1217. }
  1218. SHIM_INFO_BEGIN()
  1219. SHIM_INFO_DESCRIPTION(AVS_REGISTRYCHECKS_DESC)
  1220. SHIM_INFO_FRIENDLY_NAME(AVS_REGISTRYCHECKS_FRIENDLY)
  1221. SHIM_INFO_VERSION(1, 2)
  1222. SHIM_INFO_INCLUDE_EXCLUDE("E:msi.dll sxs.dll comctl32.dll ole32.dll oleaut32.dll")
  1223. SHIM_INFO_END()
  1224. /*++
  1225. Register hooked functions
  1226. Note we purposely ignore the cleanup because some apps call registry functions
  1227. during process detach.
  1228. --*/
  1229. HOOK_BEGIN
  1230. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_Console_READ,
  1231. AVS_HKCU_Console_READ,
  1232. AVS_HKCU_Console_READ_R,
  1233. AVS_HKCU_Console_READ_URL)
  1234. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_ControlPanel_READ,
  1235. AVS_HKCU_ControlPanel_READ,
  1236. AVS_HKCU_ControlPanel_READ_R,
  1237. AVS_HKCU_ControlPanel_READ_URL)
  1238. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_Environment_READ,
  1239. AVS_HKCU_Environment_READ,
  1240. AVS_HKCU_Environment_READ_R,
  1241. AVS_HKCU_Environment_READ_URL)
  1242. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_Identities_READ,
  1243. AVS_HKCU_Identities_READ,
  1244. AVS_HKCU_Identities_READ_R,
  1245. AVS_HKCU_Identities_READ_URL)
  1246. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_KeyboardLayout_READ,
  1247. AVS_HKCU_KeyboardLayout_READ,
  1248. AVS_HKCU_KeyboardLayout_READ_R,
  1249. AVS_HKCU_KeyboardLayout_READ_URL)
  1250. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_Printers_READ,
  1251. AVS_HKCU_Printers_READ,
  1252. AVS_HKCU_Printers_READ_R,
  1253. AVS_HKCU_Printers_READ_URL)
  1254. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_RemoteAccess_READ,
  1255. AVS_HKCU_RemoteAccess_READ,
  1256. AVS_HKCU_RemoteAccess_READ_R,
  1257. AVS_HKCU_RemoteAccess_READ_URL)
  1258. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_SessionInformation_READ,
  1259. AVS_HKCU_SessionInformation_READ,
  1260. AVS_HKCU_SessionInformation_READ_R,
  1261. AVS_HKCU_SessionInformation_READ_URL)
  1262. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_UNICODEProgramGroups_READ,
  1263. AVS_HKCU_UNICODEProgramGroups_READ,
  1264. AVS_HKCU_UNICODEProgramGroups_READ_R,
  1265. AVS_HKCU_UNICODEProgramGroups_READ_URL)
  1266. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_VolatileEnvironment_READ,
  1267. AVS_HKCU_VolatileEnvironment_READ,
  1268. AVS_HKCU_VolatileEnvironment_READ_R,
  1269. AVS_HKCU_VolatileEnvironment_READ_URL)
  1270. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCU_Windows31MigrationStatus_READ,
  1271. AVS_HKCU_Windows31MigrationStatus_READ,
  1272. AVS_HKCU_Windows31MigrationStatus_READ_R,
  1273. AVS_HKCU_Windows31MigrationStatus_READ_URL)
  1274. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKLM_HARDWARE_READ,
  1275. AVS_HKLM_HARDWARE_READ,
  1276. AVS_HKLM_HARDWARE_READ_R,
  1277. AVS_HKLM_HARDWARE_READ_URL)
  1278. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKLM_SAM_READ,
  1279. AVS_HKLM_SAM_READ,
  1280. AVS_HKLM_SAM_READ_R,
  1281. AVS_HKLM_SAM_READ_URL)
  1282. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKLM_SECURITY_READ,
  1283. AVS_HKLM_SECURITY_READ,
  1284. AVS_HKLM_SECURITY_READ_R,
  1285. AVS_HKLM_SECURITY_READ_URL)
  1286. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKLM_SYSTEM_READ,
  1287. AVS_HKLM_SYSTEM_READ,
  1288. AVS_HKLM_SYSTEM_READ_R,
  1289. AVS_HKLM_SYSTEM_READ_URL)
  1290. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKCC_READ,
  1291. AVS_HKCC_READ,
  1292. AVS_HKCC_READ_R,
  1293. AVS_HKCC_READ_URL)
  1294. DUMP_VERIFIER_LOG_ENTRY(VLOG_HKUS_READ,
  1295. AVS_HKUS_READ,
  1296. AVS_HKUS_READ_R,
  1297. AVS_HKUS_READ_URL)
  1298. DUMP_VERIFIER_LOG_ENTRY(VLOG_NON_HKCU_WRITE,
  1299. AVS_NON_HKCU_WRITE,
  1300. AVS_NON_HKCU_WRITE_R,
  1301. AVS_NON_HKCU_WRITE_URL)
  1302. APIHOOK_ENTRY(ADVAPI32.DLL, RegOpenKeyA)
  1303. APIHOOK_ENTRY(ADVAPI32.DLL, RegOpenKeyW)
  1304. APIHOOK_ENTRY(ADVAPI32.DLL, RegOpenKeyExA)
  1305. APIHOOK_ENTRY(ADVAPI32.DLL, RegOpenKeyExW)
  1306. APIHOOK_ENTRY(ADVAPI32.DLL, RegCreateKeyA)
  1307. APIHOOK_ENTRY(ADVAPI32.DLL, RegCreateKeyW)
  1308. APIHOOK_ENTRY(ADVAPI32.DLL, RegCreateKeyExA)
  1309. APIHOOK_ENTRY(ADVAPI32.DLL, RegCreateKeyExW)
  1310. APIHOOK_ENTRY(ADVAPI32.DLL, RegCloseKey)
  1311. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueA)
  1312. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueW)
  1313. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueExA)
  1314. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueExW)
  1315. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryInfoKeyA)
  1316. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryInfoKeyW)
  1317. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueA)
  1318. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueW)
  1319. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueExA)
  1320. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueExW)
  1321. APIHOOK_ENTRY(ADVAPI32.DLL, RegEnumValueA)
  1322. APIHOOK_ENTRY(ADVAPI32.DLL, RegEnumValueW)
  1323. APIHOOK_ENTRY(ADVAPI32.DLL, RegEnumKeyA)
  1324. APIHOOK_ENTRY(ADVAPI32.DLL, RegEnumKeyW)
  1325. APIHOOK_ENTRY(ADVAPI32.DLL, RegEnumKeyExA)
  1326. APIHOOK_ENTRY(ADVAPI32.DLL, RegEnumKeyExW)
  1327. APIHOOK_ENTRY(ADVAPI32.DLL, RegDeleteKeyA)
  1328. APIHOOK_ENTRY(ADVAPI32.DLL, RegDeleteKeyW)
  1329. HOOK_END
  1330. IMPLEMENT_SHIM_END