Windows, or more precisely, Windows and NTFS has — or rather _had_ ... more on that later — an extremely cool feature: Transactions on the file system. You can basically perform a bunch of operations, create files, modify files, delete files and then either "commit" all of it or "rollback" all of. The underlying Windows API functions belongs to something called Kernel Transaction Manager (KTM) and it's even cooler than _just_ atomic transaction on files: it allows operations on _resources_. Windows ships with two of those already integrated: the file system (TxF) and the Windows registry (TxR). But as a developer you can write a so-called _resource manager_ offering your "thing" to KTM. There's probably some rich corporate history here that I'm completely ignorant to but I can only assume the hope of the team behind this was that KTM will at some point become standard for all kinds of components running on a Windows operating system: just imagine a database being integrated as well as, say, a queuing system. As a user of those transactions, you could de-queue a message and act on the database and KTM would promise that it either all worked or the message was never de-queued. And it would promise that also across, say, a power loss.
It's obviously quite a lot of work to implement your own KTM transaction manager and that's also not the scope of this blag post but I wanted to give it as context anyway. What is the scope of this post you might ask: I wanted to show a minimal example to write a file with KTM. No real reason, just to understand the technology a bit better. And with "understand the technology" I mainly mean how many zero I need to pass to the Windows API functions. A trivial evasion technique for malware leveraging KTM certainly is to just do all operations and housekeeping within a transaction and maybe even never commit it or only commit it very late. It will leave no traces on the file system before that final commit. A quick web search also suggests, there is much more shenanigans you can do, but now to the sad part: The sheer usage of KTM is already a pretty strong signature for something phishy going on. Microsoft deprecated the API and threatened to remove it anytime. So no legitimate tool will start using it nowadays.
Without further ado here is a minimal example:
```c
#include <stdio.h>
#include <windows.h>
#include <guiddef.h>
#include <ktmw32.h>
int main(void) {
static const char payload[] = "written inside a KTM transaction\r\n";
static const WCHAR path[] = L"demo.txt";
HANDLE hTrans = CreateTransaction(0, 0, 0, 0, 0, 0, L"MyTransaction");
HANDLE hFile = CreateFileTransactedW(path, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0, hTrans, 0, 0);
DWORD written = 0;
WriteFile(hFile, payload, (DWORD) (sizeof payload - 1), &written, 0);
CloseHandle(hFile);
CommitTransaction(hTrans);
CloseHandle(hTrans);
return 0;
}
```
You can compile it with `gcc -Werror -Wall -pedantic -o write.exe write.c -lktmw32`. In a real application you should of course check all the return codes to make sure nothing crashed on the way, but for the sake of readability, I left all that out. And when you put `RollbackTransaction` there instead of `CommitTransaction` the program will behave as if none of this ever happened.
Again, I think this is pretty cool stuff. Sad that it's already over before I even knew it existed.