Save persistent data to a file

During a precreate call, I would like to store some information about the file transaction that just happened, it should actually be real simple to just spit out some data to a file, after I spit this information into a file, I want to be able to read this information from the file that was just saved, the file name would be static. I am pretty new to minifilter driver development, and this is my final item before its complete. I tried to use fstream.h, which imports just fine, but I can’t use any of the methods provided by the class, ofstream is just simply undefined.

You can use any CRTL functions from a driver.

You need to use the Native Windows API: ZwCreateFile, ZwWriteFile, ZwReadFile. The harder part will be parsing the data. Yuck.

But why a FILE? You’d be much better off, and your life would be easier, if you stored the data In the Registry.

Peter

1 Like

Peter, you are right, your suggestion is brilliant, I forgot all about Zw. To answer your question I have thought about the registry. The product I am putting together is a security product, and if I use the registry then the data is accessible/hackable even if encrypted. With a file minifilter, I am in control of who opens the files which puts me in a good position to block access to the file from anything but my minifilter. I suppose at a deep level, the registry is a set of files, so it might be possible to block access to that segment of the registry. I really wanted to use the registry so maybe I will do some trail and error.

Thank you so much Peter for your answer, you got me on the path to working again. I am on my way to finishing this thing thanks to you!

Peter, sorry for asking another noob question, can you please tell me what might be wrong with this code? I have tested it every way but up and still gives me an invalid parameter error:

WCHAR* ProgramLogFile = L"\??\C:\Users\cf.txt";
HANDLE LogFileHandle;
LARGE_INTEGER AllocationSize;
UNICODE_STRING LogFileName;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;

				NTSTATUS Status;

				
				RtlInitUnicodeString(&LogFileName, ProgramLogFile);
				InitializeObjectAttributes(
					&ObjectAttributes,
					&LogFileName,
					OBJ_CASE_INSENSITIVE | OBJ_PERMANENT | OBJ_OPENIF,
					NULL,
					NULL
				);
				AllocationSize.QuadPart = 6000000;
				Status = ZwCreateFile(
					&LogFileHandle,
					FILE_ANY_ACCESS,
					&ObjectAttributes,
					&IoStatusBlock,
					&AllocationSize,
					FILE_ATTRIBUTE_NORMAL,
					0,
					FILE_SUPERSEDE,
					FILE_SYNCHRONOUS_IO_NONALERT,
					NULL,
					0
				);

				if (NT_SUCCESS(Status)) {
					DbgPrint("Success");
				}
				else {
					DbgPrint("Failure");
				}

I figured this out, thanks anyway.

The first line should be

    WCHAR * ProgramLogFile = L"\\??\\C:\\Users\\cf.txt";

As a C programmer, you MUST get in the habit of doubling your backslashes.

Alternatively, you can use forward slashes. Few people know it, but Windows APIs all accept slashes in either direction. It’s only the Windows command line that stubbornly refuses to accept forward slashes.

1 Like

Alternatively, you can use forward slashes.

Alternatively, you can use raw string literals (the “R” designator) … which are much easier to read. Then never worry about escaping in those long path names.

Peter

I will keep those things in mind, thank you both!

or don’t hard code the path at all, but read it from the registry or other configuration?

To answer your question I have thought about the registry. The product I am putting together is a security product, and if I use the registry then the data is accessible/hackable even if encrypted.

I’m not sure this is a valid argument since you can register a registry callback to block access to your registry values: https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-cmregistercallback

I haven’t done it myself, but I know it should be possible…

So you think that your security product will be more secure by using hard coded paths to disk locations that might not exist? Instead of a configured location you want to use a string constant that can be read out of your binary? As easily or more than reading them out of the registry or a config file

And any sophisticated attacker can redirect your path to anywhere they choose regardless of how you try to protect how it gets configured. So what exactly are you trying to achieve?