EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Prevent File Content Change

Also by EldoS: RawDisk
Access locked and protected files in Windows, read and write disks and partitions and more.
#32490
Posted: 03/04/2015 10:22:57
by Mohamed Saher (Basic support level)
Joined: 03/04/2015
Posts: 6

I am trying to get notification via callback when file is being opened or written to in order to prevent the write action. In another words, have the file read only. And if possible know how to filter write access to such mask depending on trusted process names.

My current problem is that I receive the write callback after a delay and it goes in a recursive action and doesn't stop neither does it stop the write action to the file. I pasting the small snippet am working with hopefully someone would pin point what am doing wrong. Thanks in advance.

Code
LPCSTR g_Guid = "18189531-48ED-43fc-8582-E8BD2F9AB533";
CallbackFilter g_CbFlt;

void CbFltOpenFileC(
   CallbackFilter *Sender,
   LPWSTR FileName,
   PACCESS_MASK DesiredAccess,
   PDWORD FileAttributes,
   PWORD ShareMode,
   PDWORD CreateOptions,
   PWORD CreateDisposition,
   LPBOOL VirtualFile,
   LPBOOL ProcessRequest
   );

void CbFltWriteFileC(
   CallbackFilter *Sender,
   LPWSTR FileName,
   __int64 *Position,
   PVOID Buffer,
   PDWORD BytesToWrite,
   BOOL CachedWrite,
   PVOID* Context,
   LPBOOL ProcessRequest
   );

int main(int argc, char *argv[]) {
   try {
      PCHAR sRegKey = "__REMOVED__";

      g_CbFlt.SetRegistrationKey(sRegKey);

      g_CbFlt.SetOnWriteFileC(CbFltWriteFileC);
      g_CbFlt.SetOnOpenFileC(CbFltOpenFileC);

      g_CbFlt.AddFilterAccessRule(L"*.txt", (CallbackFilter::CbFltAccessFlags)0x00000001L);
      g_CbFlt.AddFilterCallbackRule(L"C:\\testfolder\\test\\*.txt", (CallbackFilter::CbFltCallbackFlags)(0x00020000L));

      g_CbFlt.AttachFilter(1000);
      g_CbFlt.SetProcessFailedRequests(TRUE);
      g_CbFlt.SetReadWriteFileInPreCreatePath(FALSE);
      g_CbFlt.SetFlushFilesOnClose(FALSE);
   }
   catch (ECBFltError err){
      fprintf(stderr, "[-] ERROR: %ws\r\n", err.Message());
   }

   getchar();

   g_CbFlt.DetachFilter();

   return EXIT_SUCCESS;
}

void CbFltOpenFileC(
   CallbackFilter* Sender,
   LPWSTR FileName,
   PACCESS_MASK DesiredAccess,
   PDWORD FileAttributes,
   PWORD ShareMode,
   PDWORD CreateOptions,
   PWORD CreateDisposition,
   LPBOOL VirtualFile,
   LPBOOL ProcessRequest
   ) {
   
   fprintf(stdout, "[+] Attempting to open %ws\r\n", FileName);

   if (*DesiredAccess & FILE_WRITE_DATA) {
      throw ECBFltError(ERROR_ACCESS_DENIED);
   }

   *ProcessRequest = TRUE;
}

void CbFltWriteFileC(
   CallbackFilter* Sender,
   LPWSTR FileName,
   __int64 *Position,
   PVOID Buffer,
   PDWORD BytesToWrite,
   BOOL CachedWrite,
   PVOID* Context,
   LPBOOL ProcessRequest
   ) {
   
   fprintf(stdout, "[+] Attempting to write to file %ws\r\n", FileName);
   throw ECBFltError(ERROR_ACCESS_DENIED);
   
   *ProcessRequest = FALSE;
}
#32491
Posted: 03/04/2015 10:46:23
by Vladimir Cherniga (EldoS Corp.)

Try to add GENERIC_WRITE, FILE_APPEND_DATA flags to the test of DesiredAccess value.
#32498
Posted: 03/04/2015 13:16:21
by Mohamed Saher (Basic support level)
Joined: 03/04/2015
Posts: 6

I did the following:

Code
if (((*DesiredAccess == GENERIC_WRITE) || (*DesiredAccess == FILE_APPEND_DATA))  & FILE_WRITE_DATA) {
      throw ECBFltError(ERROR_ACCESS_DENIED);
   }


However, it still doesn't work, and after I open the file, edit it and close, I keep getting callback for write attempts recursively and it keeps going forever. Am I doing something majorly wrong here?
#32499
Posted: 03/04/2015 13:26:30
by Eugene Mayevski (EldoS Corp.)

Please also handle OnFileCreateC event (and do the same checks as in OnFileOpenC).


Sincerely yours
Eugene Mayevski
#32500
Posted: 03/04/2015 14:04:43
by Mohamed Saher (Basic support level)
Joined: 03/04/2015
Posts: 6

I did that as well, nothing changed. Could you post an example or a snippet if possible?
#32501
Posted: 03/04/2015 14:16:01
by Eugene Mayevski (EldoS Corp.)

DesiredAccess is a MASK, i.e. a combination of individual bits. See https://msdn.microsoft.com/en-us/libra...85%29.aspx

You check it in the wrong way. The check must be like

Code
if (((*DesiredAccess & GENERIC_WRITE) != 0) || (*DesiredAccess & FILE_APPEND_DATA) != 0)|| (*DesiredAccess & FILE_WRITE_DATA) != 0))
{
  throw ...
}


Use this check in both OnCreateFileC and OnOpenFileC. If this is done right, you'll never get OnFileWriteC .


Sincerely yours
Eugene Mayevski
#32502
Posted: 03/04/2015 14:45:40
by Mohamed Saher (Basic support level)
Joined: 03/04/2015
Posts: 6

Thanks a lot Eugene, actually you were right, I found out that I used the wrong mask also for the filter addition. Should have been the mask for FileCreateFlag and not FileWriteFlag.

Original buggy code
Code
g_CbFlt.AddFilterCallbackRule(L"C:\\testfolder\\test\\*.txt", (CallbackFilter::CbFltCallbackFlags)(0x00020000L));


Correct code
Code
g_CbFlt.AddFilterCallbackRule(L"C:\\testfolder\\test\\*.txt", (CallbackFilter::CbFltCallbackFlags)(0x00040000L));


--halsten
Also by EldoS: BizCrypto
Components for BizTalk® and SQL Server® Integration Services that let you securely store and transfer information in your business automation solutions.

Reply

Statistics

Topic viewed 3254 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!