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.

873 lines
24 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. WindowsFileProtection.cpp
  5. Abstract:
  6. This AppVerifier shim hooks the file I/O APIs that could
  7. potentially change a file under Windows File Protection.
  8. When one of the files is accessed or modified, an event
  9. is written to the log.
  10. Notes:
  11. This is a general purpose shim.
  12. History:
  13. 06/25/2001 rparsons Created
  14. 11/26/2001 rparsons Remove unused local variables.
  15. Make SHFileOperation more efficent.
  16. --*/
  17. #include "precomp.h"
  18. #include "rtlutils.h"
  19. #include "sfc.h"
  20. IMPLEMENT_SHIM_BEGIN(WindowsFileProtection)
  21. #include "ShimHookMacro.h"
  22. //
  23. // verifier log entries
  24. //
  25. BEGIN_DEFINE_VERIFIER_LOG(WindowFileProtection)
  26. VERIFIER_LOG_ENTRY(VLOG_WFP_COPYFILE)
  27. VERIFIER_LOG_ENTRY(VLOG_WFP_MOVEFILE)
  28. VERIFIER_LOG_ENTRY(VLOG_WFP_DELETEFILE)
  29. VERIFIER_LOG_ENTRY(VLOG_WFP_REPLACEFILE)
  30. VERIFIER_LOG_ENTRY(VLOG_WFP_WRITEFILE)
  31. VERIFIER_LOG_ENTRY(VLOG_WFP_OPENFILE)
  32. VERIFIER_LOG_ENTRY(VLOG_WFP_SHFILEOP)
  33. END_DEFINE_VERIFIER_LOG(WindowFileProtection)
  34. INIT_VERIFIER_LOG(WindowFileProtection);
  35. APIHOOK_ENUM_BEGIN
  36. APIHOOK_ENUM_ENTRY(CreateFileA)
  37. APIHOOK_ENUM_ENTRY(CreateFileW)
  38. APIHOOK_ENUM_ENTRY(OpenFile)
  39. APIHOOK_ENUM_ENTRY(CopyFileA)
  40. APIHOOK_ENUM_ENTRY(CopyFileW)
  41. APIHOOK_ENUM_ENTRY(CopyFileExA)
  42. APIHOOK_ENUM_ENTRY(CopyFileExW)
  43. APIHOOK_ENUM_ENTRY(DeleteFileA)
  44. APIHOOK_ENUM_ENTRY(DeleteFileW)
  45. APIHOOK_ENUM_ENTRY(MoveFileA)
  46. APIHOOK_ENUM_ENTRY(MoveFileW)
  47. APIHOOK_ENUM_ENTRY(MoveFileExA)
  48. APIHOOK_ENUM_ENTRY(MoveFileExW)
  49. APIHOOK_ENUM_ENTRY(MoveFileWithProgressA)
  50. APIHOOK_ENUM_ENTRY(MoveFileWithProgressW)
  51. APIHOOK_ENUM_ENTRY(ReplaceFileA)
  52. APIHOOK_ENUM_ENTRY(ReplaceFileW)
  53. APIHOOK_ENUM_ENTRY(SHFileOperationA)
  54. APIHOOK_ENUM_ENTRY(SHFileOperationW)
  55. APIHOOK_ENUM_ENTRY(_lcreat)
  56. APIHOOK_ENUM_ENTRY(_lopen)
  57. APIHOOK_ENUM_ENTRY(NtCreateFile)
  58. APIHOOK_ENUM_ENTRY(NtOpenFile)
  59. APIHOOK_ENUM_END
  60. /*++
  61. ANSI wrapper for SfcIsFileProtected.
  62. --*/
  63. BOOL
  64. IsFileProtected(
  65. LPCSTR pszFileName
  66. )
  67. {
  68. LPWSTR pwszWideFileName = NULL;
  69. int nLen = 0;
  70. BOOL fReturn = FALSE;
  71. //
  72. // Convert from ANSI to Unicode.
  73. //
  74. nLen = lstrlenA(pszFileName);
  75. if (nLen) {
  76. pwszWideFileName = (LPWSTR)RtlAllocateHeap(RtlProcessHeap(),
  77. HEAP_ZERO_MEMORY,
  78. (nLen + 1) * sizeof(WCHAR));
  79. if (!pwszWideFileName) {
  80. DPFN(eDbgLevelError, "[IsFileProtected] Failed to allocate memory");
  81. return FALSE;
  82. }
  83. if (!MultiByteToWideChar(CP_ACP,
  84. 0,
  85. pszFileName,
  86. -1,
  87. pwszWideFileName,
  88. nLen * sizeof(WCHAR))) {
  89. DPFN(eDbgLevelError, "[IsFileProtected] ANSI -> Unicode failed");
  90. goto cleanup;
  91. }
  92. fReturn = SfcIsFileProtected(NULL, pwszWideFileName);
  93. }
  94. cleanup:
  95. if (pwszWideFileName) {
  96. RtlFreeHeap(RtlProcessHeap(), 0, pwszWideFileName);
  97. }
  98. return (fReturn);
  99. }
  100. /*++
  101. Wraps SfcIsFileProtected for NT path names.
  102. --*/
  103. BOOL
  104. IsNtFileProtected(
  105. IN PUNICODE_STRING pstrNtFileName
  106. )
  107. {
  108. NTSTATUS status;
  109. RTL_UNICODE_STRING_BUFFER DosPath;
  110. BOOL fReturn = FALSE;
  111. UCHAR DosPathBuffer[MAX_PATH * 2];
  112. if (!pstrNtFileName) {
  113. DPFN(eDbgLevelError, "[IsNtFileProtected] Invalid parameter");
  114. return FALSE;
  115. }
  116. //
  117. // Convert from an NT path to a DOS path.
  118. //
  119. RtlInitUnicodeStringBuffer(&DosPath, DosPathBuffer, sizeof(DosPathBuffer));
  120. status = ShimAssignUnicodeStringBuffer(&DosPath, pstrNtFileName);
  121. if (!NT_SUCCESS(status)) {
  122. DPFN(eDbgLevelError, "[IsNtFileProtected] Failed to initialize DOS path buffer");
  123. return fReturn;
  124. }
  125. status = ShimNtPathNameToDosPathName(0, &DosPath, NULL, NULL);
  126. if (!NT_SUCCESS(status)) {
  127. DPFN(eDbgLevelError, "[IsNtFileProtected] Failed to convert NT \"%ls\" to DOS path",
  128. pstrNtFileName->Buffer);
  129. goto cleanup;
  130. }
  131. //
  132. // Now check for a protected file.
  133. //
  134. if (SfcIsFileProtected(NULL, DosPath.String.Buffer)) {
  135. fReturn = TRUE;
  136. }
  137. cleanup:
  138. RtlFreeUnicodeStringBuffer(&DosPath);
  139. return (fReturn);
  140. }
  141. BOOL
  142. APIHOOK(CopyFileA)(
  143. LPCSTR lpExistingFileName,
  144. LPCSTR lpNewFileName,
  145. BOOL bFailIfExists
  146. )
  147. {
  148. //
  149. // Ensure that the destination is not protected.
  150. //
  151. if (!bFailIfExists && IsFileProtected(lpNewFileName)) {
  152. VLOG(VLOG_LEVEL_ERROR,
  153. VLOG_WFP_COPYFILE,
  154. "API: CopyFileA Filename: %s",
  155. lpNewFileName);
  156. }
  157. return ORIGINAL_API(CopyFileA)(lpExistingFileName,
  158. lpNewFileName,
  159. bFailIfExists);
  160. }
  161. BOOL
  162. APIHOOK(CopyFileW)(
  163. LPCWSTR lpExistingFileName,
  164. LPCWSTR lpNewFileName,
  165. BOOL bFailIfExists
  166. )
  167. {
  168. //
  169. // Ensure that the destination is not protected.
  170. //
  171. if (!bFailIfExists && SfcIsFileProtected(NULL, lpNewFileName)) {
  172. VLOG(VLOG_LEVEL_ERROR,
  173. VLOG_WFP_COPYFILE,
  174. "API: CopyFileW Filename: %ls",
  175. lpNewFileName);
  176. }
  177. return ORIGINAL_API(CopyFileW)(lpExistingFileName,
  178. lpNewFileName,
  179. bFailIfExists);
  180. }
  181. BOOL
  182. APIHOOK(CopyFileExA)(
  183. LPCSTR lpExistingFileName,
  184. LPCSTR lpNewFileName,
  185. LPPROGRESS_ROUTINE lpProgressRoutine,
  186. LPVOID lpData,
  187. LPBOOL pbCancel,
  188. DWORD dwCopyFlags
  189. )
  190. {
  191. //
  192. // Ensure that the destination is not protected.
  193. //
  194. if (!(dwCopyFlags & COPY_FILE_FAIL_IF_EXISTS) &&
  195. IsFileProtected(lpNewFileName)) {
  196. VLOG(VLOG_LEVEL_ERROR,
  197. VLOG_WFP_COPYFILE,
  198. "API: CopyFileExA Filename: %s",
  199. lpNewFileName);
  200. }
  201. return ORIGINAL_API(CopyFileExA)(lpExistingFileName,
  202. lpNewFileName,
  203. lpProgressRoutine,
  204. lpData,
  205. pbCancel,
  206. dwCopyFlags);
  207. }
  208. BOOL
  209. APIHOOK(CopyFileExW)(
  210. LPCWSTR lpExistingFileName,
  211. LPCWSTR lpNewFileName,
  212. LPPROGRESS_ROUTINE lpProgressRoutine,
  213. LPVOID lpData,
  214. LPBOOL pbCancel,
  215. DWORD dwCopyFlags
  216. )
  217. {
  218. //
  219. // Ensure that the destination is not protected.
  220. //
  221. if (!(dwCopyFlags & COPY_FILE_FAIL_IF_EXISTS) &&
  222. SfcIsFileProtected(NULL, lpNewFileName)) {
  223. VLOG(VLOG_LEVEL_ERROR,
  224. VLOG_WFP_COPYFILE,
  225. "API: CopyFileExW Filename: %ls",
  226. lpNewFileName);
  227. }
  228. return ORIGINAL_API(CopyFileExW)(lpExistingFileName,
  229. lpNewFileName,
  230. lpProgressRoutine,
  231. lpData,
  232. pbCancel,
  233. dwCopyFlags);
  234. }
  235. BOOL
  236. APIHOOK(DeleteFileA)(
  237. LPCSTR lpFileName
  238. )
  239. {
  240. if (IsFileProtected(lpFileName)) {
  241. VLOG(VLOG_LEVEL_ERROR,
  242. VLOG_WFP_DELETEFILE,
  243. "API: DeleteFileA Filename: %s",
  244. lpFileName);
  245. }
  246. return ORIGINAL_API(DeleteFileA)(lpFileName);
  247. }
  248. BOOL
  249. APIHOOK(DeleteFileW)(
  250. LPCWSTR lpFileName
  251. )
  252. {
  253. if (SfcIsFileProtected(NULL, lpFileName)) {
  254. VLOG(VLOG_LEVEL_ERROR,
  255. VLOG_WFP_DELETEFILE,
  256. "API: DeleteFileW Filename: %ls",
  257. lpFileName);
  258. }
  259. return ORIGINAL_API(DeleteFileW)(lpFileName);
  260. }
  261. BOOL
  262. APIHOOK(MoveFileA)(
  263. LPCSTR lpExistingFileName,
  264. LPCSTR lpNewFileName
  265. )
  266. {
  267. //
  268. // Ensure that the source or destination is not protected.
  269. //
  270. if (IsFileProtected(lpExistingFileName) ||
  271. IsFileProtected(lpNewFileName)) {
  272. VLOG(VLOG_LEVEL_ERROR,
  273. VLOG_WFP_MOVEFILE,
  274. "API: MoveFileA Filename: %s Filename: %s",
  275. lpExistingFileName,
  276. lpNewFileName);
  277. }
  278. return ORIGINAL_API(MoveFileA)(lpExistingFileName,
  279. lpNewFileName);
  280. }
  281. BOOL
  282. APIHOOK(MoveFileW)(
  283. LPCWSTR lpExistingFileName,
  284. LPCWSTR lpNewFileName
  285. )
  286. {
  287. //
  288. // Ensure that the source or destination is not protected.
  289. //
  290. if (SfcIsFileProtected(NULL, lpExistingFileName) ||
  291. SfcIsFileProtected(NULL, lpNewFileName)) {
  292. VLOG(VLOG_LEVEL_ERROR,
  293. VLOG_WFP_MOVEFILE,
  294. "API: MoveFileW Filename: %ls Filename: %ls",
  295. lpExistingFileName,
  296. lpNewFileName);
  297. }
  298. return ORIGINAL_API(MoveFileW)(lpExistingFileName,
  299. lpNewFileName);
  300. }
  301. BOOL
  302. APIHOOK(MoveFileExA)(
  303. LPCSTR lpExistingFileName,
  304. LPCSTR lpNewFileName,
  305. DWORD dwFlags
  306. )
  307. {
  308. //
  309. // Ensure that the source or destination is not protected.
  310. //
  311. if (IsFileProtected(lpExistingFileName) ||
  312. IsFileProtected(lpNewFileName)) {
  313. VLOG(VLOG_LEVEL_ERROR,
  314. VLOG_WFP_MOVEFILE,
  315. "API: MoveFileExA Filename: %s Filename: %s",
  316. lpExistingFileName,
  317. lpNewFileName);
  318. }
  319. return ORIGINAL_API(MoveFileExA)(lpExistingFileName,
  320. lpNewFileName,
  321. dwFlags);
  322. }
  323. BOOL
  324. APIHOOK(MoveFileExW)(
  325. LPCWSTR lpExistingFileName,
  326. LPCWSTR lpNewFileName,
  327. DWORD dwFlags
  328. )
  329. {
  330. //
  331. // Ensure that the source or destination is not protected.
  332. //
  333. if (SfcIsFileProtected(NULL, lpExistingFileName) ||
  334. SfcIsFileProtected(NULL, lpNewFileName)) {
  335. VLOG(VLOG_LEVEL_ERROR,
  336. VLOG_WFP_MOVEFILE, "API: MoveFileExW Filename: %ls Filename: %ls",
  337. lpExistingFileName,
  338. lpNewFileName);
  339. }
  340. return ORIGINAL_API(MoveFileExW)(lpExistingFileName,
  341. lpNewFileName,
  342. dwFlags);
  343. }
  344. BOOL
  345. APIHOOK(MoveFileWithProgressA)(
  346. LPCSTR lpExistingFileName,
  347. LPCSTR lpNewFileName,
  348. LPPROGRESS_ROUTINE lpProgressRoutine,
  349. LPVOID lpData,
  350. DWORD dwFlags
  351. )
  352. {
  353. //
  354. // Ensure that the source or destination is not protected.
  355. //
  356. if (IsFileProtected(lpExistingFileName) ||
  357. IsFileProtected(lpNewFileName)) {
  358. VLOG(VLOG_LEVEL_ERROR,
  359. VLOG_WFP_MOVEFILE,
  360. "API: MoveFileWithProgressA Filename: %s Filename: %s",
  361. lpExistingFileName,
  362. lpNewFileName);
  363. }
  364. return ORIGINAL_API(MoveFileWithProgressA)(lpExistingFileName,
  365. lpNewFileName,
  366. lpProgressRoutine,
  367. lpData,
  368. dwFlags);
  369. }
  370. BOOL
  371. APIHOOK(MoveFileWithProgressW)(
  372. LPCWSTR lpExistingFileName,
  373. LPCWSTR lpNewFileName,
  374. LPPROGRESS_ROUTINE lpProgressRoutine,
  375. LPVOID lpData,
  376. DWORD dwFlags
  377. )
  378. {
  379. //
  380. // Ensure that the source or destination is not protected.
  381. //
  382. if (SfcIsFileProtected(NULL, lpExistingFileName) ||
  383. SfcIsFileProtected(NULL, lpNewFileName)) {
  384. VLOG(VLOG_LEVEL_ERROR,
  385. VLOG_WFP_MOVEFILE,
  386. "API: MoveFileWithProgressW Filename: %ls Filename: %ls",
  387. lpExistingFileName,
  388. lpNewFileName);
  389. }
  390. return ORIGINAL_API(MoveFileWithProgressW)(lpExistingFileName,
  391. lpNewFileName,
  392. lpProgressRoutine,
  393. lpData,
  394. dwFlags);
  395. }
  396. BOOL
  397. APIHOOK(ReplaceFileA)(
  398. LPCSTR lpReplacedFileName,
  399. LPCSTR lpReplacementFileName,
  400. LPCSTR lpBackupFileName,
  401. DWORD dwReplaceFlags,
  402. LPVOID lpExclude,
  403. LPVOID lpReserved
  404. )
  405. {
  406. //
  407. // Ensure that the destination is not protected.
  408. //
  409. if (IsFileProtected(lpReplacedFileName)) {
  410. VLOG(VLOG_LEVEL_ERROR,
  411. VLOG_WFP_REPLACEFILE,
  412. "API: ReplaceFileA Filename: %s",
  413. lpReplacedFileName);
  414. }
  415. return ORIGINAL_API(ReplaceFileA)(lpReplacedFileName,
  416. lpReplacementFileName,
  417. lpBackupFileName,
  418. dwReplaceFlags,
  419. lpExclude,
  420. lpReserved);
  421. }
  422. BOOL
  423. APIHOOK(ReplaceFileW)(
  424. LPCWSTR lpReplacedFileName,
  425. LPCWSTR lpReplacementFileName,
  426. LPCWSTR lpBackupFileName,
  427. DWORD dwReplaceFlags,
  428. LPVOID lpExclude,
  429. LPVOID lpReserved
  430. )
  431. {
  432. //
  433. // Ensure that the destination is not protected.
  434. //
  435. if (SfcIsFileProtected(NULL, lpReplacedFileName)) {
  436. VLOG(VLOG_LEVEL_ERROR,
  437. VLOG_WFP_REPLACEFILE,
  438. "API: ReplaceFileW Filename: %ls",
  439. lpReplacedFileName);
  440. }
  441. return ORIGINAL_API(ReplaceFileW)(lpReplacedFileName,
  442. lpReplacementFileName,
  443. lpBackupFileName,
  444. dwReplaceFlags,
  445. lpExclude,
  446. lpReserved);
  447. }
  448. void
  449. ReportProtectedFileA(
  450. LPCSTR pszFilePath
  451. )
  452. {
  453. UINT uSize = 0;
  454. if (pszFilePath) {
  455. while (TRUE) {
  456. if (IsFileProtected(pszFilePath)) {
  457. VLOG(VLOG_LEVEL_ERROR,
  458. VLOG_WFP_SHFILEOP,
  459. "API: SHFileOperationA Filename: %s", pszFilePath);
  460. }
  461. uSize = lstrlenA(pszFilePath) + 1;
  462. pszFilePath += uSize;
  463. if (*pszFilePath == '\0') {
  464. break;
  465. }
  466. }
  467. }
  468. }
  469. void
  470. ReportProtectedFileW(
  471. LPCWSTR pwszFilePath
  472. )
  473. {
  474. UINT uSize = 0;
  475. if (pwszFilePath) {
  476. while (TRUE) {
  477. if (SfcIsFileProtected(NULL, pwszFilePath)) {
  478. VLOG(VLOG_LEVEL_ERROR,
  479. VLOG_WFP_SHFILEOP,
  480. "API: SHFileOperationW Filename: %ls", pwszFilePath);
  481. }
  482. uSize = lstrlenW(pwszFilePath) + 1;
  483. pwszFilePath += uSize;
  484. if (*pwszFilePath == '\0') {
  485. break;
  486. }
  487. }
  488. }
  489. }
  490. int
  491. APIHOOK(SHFileOperationA)(
  492. LPSHFILEOPSTRUCTA lpFileOp
  493. )
  494. {
  495. //
  496. // If they're going to rename files on collision, don't bother.
  497. //
  498. if (!(lpFileOp->fFlags & FOF_RENAMEONCOLLISION)) {
  499. ReportProtectedFileA(lpFileOp->pFrom);
  500. ReportProtectedFileA(lpFileOp->pTo);
  501. }
  502. return ORIGINAL_API(SHFileOperationA)(lpFileOp);
  503. }
  504. int
  505. APIHOOK(SHFileOperationW)(
  506. LPSHFILEOPSTRUCTW lpFileOp
  507. )
  508. {
  509. //
  510. // If they're going to rename files on collision, don't bother.
  511. //
  512. if (!(lpFileOp->fFlags & FOF_RENAMEONCOLLISION)) {
  513. ReportProtectedFileW(lpFileOp->pFrom);
  514. ReportProtectedFileW(lpFileOp->pTo);
  515. }
  516. return ORIGINAL_API(SHFileOperationW)(lpFileOp);
  517. }
  518. HANDLE
  519. APIHOOK(CreateFileA)(
  520. LPCSTR lpFileName,
  521. DWORD dwDesiredAccess,
  522. DWORD dwShareMode,
  523. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  524. DWORD dwCreationDisposition,
  525. DWORD dwFlagsAndAttributes,
  526. HANDLE hTemplateFile
  527. )
  528. {
  529. if (IsFileProtected(lpFileName) &&
  530. (dwDesiredAccess & GENERIC_WRITE ||
  531. dwDesiredAccess & GENERIC_READ)) {
  532. VLOG(VLOG_LEVEL_ERROR,
  533. VLOG_WFP_OPENFILE,
  534. "API: CreateFileA Filename: %s",
  535. lpFileName);
  536. }
  537. return ORIGINAL_API(CreateFileA)(lpFileName,
  538. dwDesiredAccess,
  539. dwShareMode,
  540. lpSecurityAttributes,
  541. dwCreationDisposition,
  542. dwFlagsAndAttributes,
  543. hTemplateFile);
  544. }
  545. HANDLE
  546. APIHOOK(CreateFileW)(
  547. LPCWSTR lpFileName,
  548. DWORD dwDesiredAccess,
  549. DWORD dwShareMode,
  550. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  551. DWORD dwCreationDisposition,
  552. DWORD dwFlagsAndAttributes,
  553. HANDLE hTemplateFile
  554. )
  555. {
  556. if (SfcIsFileProtected(NULL, lpFileName) &&
  557. (dwDesiredAccess & GENERIC_WRITE ||
  558. dwDesiredAccess & GENERIC_READ)) {
  559. VLOG(VLOG_LEVEL_ERROR,
  560. VLOG_WFP_OPENFILE,
  561. "API: CreateFileW Filename: %ls",
  562. lpFileName);
  563. }
  564. return ORIGINAL_API(CreateFileW)(lpFileName,
  565. dwDesiredAccess,
  566. dwShareMode,
  567. lpSecurityAttributes,
  568. dwCreationDisposition,
  569. dwFlagsAndAttributes,
  570. hTemplateFile);
  571. }
  572. HFILE
  573. APIHOOK(OpenFile)(
  574. LPCSTR lpFileName,
  575. LPOFSTRUCT lpReOpenBuff,
  576. UINT uStyle
  577. )
  578. {
  579. if (IsFileProtected(lpFileName) &&
  580. (uStyle & OF_READWRITE ||
  581. uStyle & OF_CREATE ||
  582. uStyle & OF_DELETE)) {
  583. VLOG(VLOG_LEVEL_ERROR,
  584. VLOG_WFP_OPENFILE,
  585. "API: OpenFile Filename: %s",
  586. lpFileName);
  587. }
  588. return ORIGINAL_API(OpenFile)(lpFileName,
  589. lpReOpenBuff,
  590. uStyle);
  591. }
  592. HFILE
  593. APIHOOK(_lopen)(
  594. LPCSTR lpPathName,
  595. int iReadWrite
  596. )
  597. {
  598. if (IsFileProtected(lpPathName) &&
  599. (iReadWrite & OF_READWRITE ||
  600. iReadWrite & OF_WRITE)) {
  601. VLOG(VLOG_LEVEL_ERROR,
  602. VLOG_WFP_OPENFILE,
  603. "API: _lopen Filename: %s",
  604. lpPathName);
  605. }
  606. return ORIGINAL_API(_lopen)(lpPathName,
  607. iReadWrite);
  608. }
  609. HFILE
  610. APIHOOK(_lcreat)(
  611. LPCSTR lpPathName,
  612. int iAttribute
  613. )
  614. {
  615. if (IsFileProtected(lpPathName) && iAttribute != 1) {
  616. VLOG(VLOG_LEVEL_ERROR,
  617. VLOG_WFP_OPENFILE,
  618. "API: _lcreat Filename: %s",
  619. lpPathName);
  620. }
  621. return ORIGINAL_API(_lcreat)(lpPathName,
  622. iAttribute);
  623. }
  624. NTSTATUS
  625. APIHOOK(NtCreateFile)(
  626. PHANDLE FileHandle,
  627. ACCESS_MASK DesiredAccess,
  628. POBJECT_ATTRIBUTES ObjectAttributes,
  629. PIO_STATUS_BLOCK IoStatusBlock,
  630. PLARGE_INTEGER AllocationSize,
  631. ULONG FileAttributes,
  632. ULONG ShareAccess,
  633. ULONG CreateDisposition,
  634. ULONG CreateOptions,
  635. PVOID EaBuffer,
  636. ULONG EaLength
  637. )
  638. {
  639. if (IsNtFileProtected(ObjectAttributes->ObjectName)) {
  640. VLOG(VLOG_LEVEL_ERROR, VLOG_WFP_OPENFILE,
  641. "API: NtCreateFile Filename: %ls",
  642. ObjectAttributes->ObjectName->Buffer);
  643. }
  644. return ORIGINAL_API(NtCreateFile)(FileHandle,
  645. DesiredAccess,
  646. ObjectAttributes,
  647. IoStatusBlock,
  648. AllocationSize,
  649. FileAttributes,
  650. ShareAccess,
  651. CreateDisposition,
  652. CreateOptions,
  653. EaBuffer,
  654. EaLength);
  655. }
  656. NTSTATUS
  657. APIHOOK(NtOpenFile)(
  658. PHANDLE FileHandle,
  659. ACCESS_MASK DesiredAccess,
  660. POBJECT_ATTRIBUTES ObjectAttributes,
  661. PIO_STATUS_BLOCK IoStatusBlock,
  662. ULONG ShareAccess,
  663. ULONG OpenOptions
  664. )
  665. {
  666. if (IsNtFileProtected(ObjectAttributes->ObjectName)) {
  667. VLOG(VLOG_LEVEL_ERROR, VLOG_WFP_OPENFILE,
  668. "API: NtOpenFile Filename: %ls",
  669. ObjectAttributes->ObjectName->Buffer);
  670. }
  671. return ORIGINAL_API(NtOpenFile)(FileHandle,
  672. DesiredAccess,
  673. ObjectAttributes,
  674. IoStatusBlock,
  675. ShareAccess,
  676. OpenOptions);
  677. }
  678. SHIM_INFO_BEGIN()
  679. SHIM_INFO_DESCRIPTION(AVS_WINFILEPROTECT_DESC)
  680. SHIM_INFO_FRIENDLY_NAME(AVS_WINFILEPROTECT_FRIENDLY)
  681. SHIM_INFO_VERSION(1, 4)
  682. SHIM_INFO_INCLUDE_EXCLUDE("E:rpcrt4.dll kernel32.dll")
  683. SHIM_INFO_END()
  684. /*++
  685. Register hooked functions.
  686. --*/
  687. HOOK_BEGIN
  688. DUMP_VERIFIER_LOG_ENTRY(VLOG_WFP_COPYFILE,
  689. AVS_WFP_COPYFILE,
  690. AVS_WFP_GENERAL_R,
  691. AVS_WFP_GENERAL_URL)
  692. DUMP_VERIFIER_LOG_ENTRY(VLOG_WFP_MOVEFILE,
  693. AVS_WFP_MOVEFILE,
  694. AVS_WFP_GENERAL_R,
  695. AVS_WFP_GENERAL_URL)
  696. DUMP_VERIFIER_LOG_ENTRY(VLOG_WFP_DELETEFILE,
  697. AVS_WFP_DELETEFILE,
  698. AVS_WFP_GENERAL_R,
  699. AVS_WFP_GENERAL_URL)
  700. DUMP_VERIFIER_LOG_ENTRY(VLOG_WFP_REPLACEFILE,
  701. AVS_WFP_REPLACEFILE,
  702. AVS_WFP_GENERAL_R,
  703. AVS_WFP_GENERAL_URL)
  704. DUMP_VERIFIER_LOG_ENTRY(VLOG_WFP_WRITEFILE,
  705. AVS_WFP_WRITEFILE,
  706. AVS_WFP_GENERAL_R,
  707. AVS_WFP_GENERAL_URL)
  708. DUMP_VERIFIER_LOG_ENTRY(VLOG_WFP_OPENFILE,
  709. AVS_WFP_OPENFILE,
  710. AVS_WFP_GENERAL_R,
  711. AVS_WFP_GENERAL_URL)
  712. DUMP_VERIFIER_LOG_ENTRY(VLOG_WFP_SHFILEOP,
  713. AVS_WFP_SHFILEOP,
  714. AVS_WFP_GENERAL_R,
  715. AVS_WFP_GENERAL_URL)
  716. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileA)
  717. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileW)
  718. APIHOOK_ENTRY(KERNEL32.DLL, OpenFile)
  719. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileA)
  720. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileW)
  721. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileExA)
  722. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileExW)
  723. APIHOOK_ENTRY(KERNEL32.DLL, DeleteFileA)
  724. APIHOOK_ENTRY(KERNEL32.DLL, DeleteFileW)
  725. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileA)
  726. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileW)
  727. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileExA)
  728. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileExW)
  729. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileWithProgressA)
  730. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileWithProgressW)
  731. APIHOOK_ENTRY(KERNEL32.DLL, ReplaceFileA)
  732. APIHOOK_ENTRY(KERNEL32.DLL, ReplaceFileW)
  733. APIHOOK_ENTRY(SHELL32.DLL, SHFileOperationA)
  734. APIHOOK_ENTRY(SHELL32.DLL, SHFileOperationW)
  735. // 16-bit compatibility file routines.
  736. APIHOOK_ENTRY(KERNEL32.DLL, _lopen)
  737. APIHOOK_ENTRY(KERNEL32.DLL, _lcreat)
  738. APIHOOK_ENTRY(NTDLL.DLL, NtCreateFile)
  739. APIHOOK_ENTRY(NTDLL.DLL, NtOpenFile)
  740. HOOK_END
  741. IMPLEMENT_SHIM_END