I was trying to think of a way to break into ntfs.sys code which would lead to the MFT being accessed, relatively directly. So I used both OSR's IrpTracker and APSoft's IrpTrace to log the ntfs IRPs used during file creation, opening or saving.
Needless to say there was way too much activity, so I needed something very specific to reduce the noise. I decided to focus on the creation of a hard link (not a shortcut) to a file, thinking that that would be added to the MFT for the file.
The specific IRP to be logged is IRP_MJ_SET_INFORMATION, and the specific InformationClass to look for is FileLinkInformation. This is the IRP used to create an NTFS hard link to an existing file, which can be done with the CreateHardLink() API.
http://msdn.microsoft.com/en-us/library/windows/hardware/ff549366%28v=vs.85%29.aspx
I used fsutil to create the hard link (fsutil hardlink create NewFilename ExistingFilename)
http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/fsutil_hardlink.mspx?mfr=true
Here is the result from IrpTrace for IRP_MJ_SET_INFORMATION / FileLinkInformation, when I created a hard link called 'alink' for the file C:\a.txt
>fsutil hardlink create alink a.txt
Code:
>> IRP_MJ_SET_INFORMATION Drv:Ntfs, Dev:#822AA020, IRP:81BDF5B8, Proc:fsutil.exe, Thr:618
Control: E0 (SL_INVOKE_ON_CANCEL | SL_INVOKE_ON_SUCCESS | SL_INVOKE_ON_ERROR)
FileObject: 82312368
CompletionRoutine: F83C0408 (sr.sys+408h)
Context: B263BB78
> Lenfo)
FileObject: 81B72028
or ReplaceIfExists: 0 (False)
or AdvanceOnly: 0 (False)
or ClusterCount: 0
or DeleteHandle: 0
SystemBuffer: 81C9B1C0
[Hex Dump]: 00 00 00 00 00 00 00 00 |
18 00 00 00 5C 00 3F 00 | \ ?
3F 00 5C 00 43 00 3A 00 |? \ C :
5C 00 61 00 6C 00 69 00 |\ a l i
6E 00 6B 00 00 00 00 00 |n k
<< IRP_MJ_SET_INFORMATION Drv:Ntfs, Dev:#822AA020, IRP:81BDF5B8- STATUS_SUCCESS (Proc:fsutil.exe, Thr:618)
If we go back to the definition of IRP_MJ_SET_INFORMATION we see that the Hex Dump above is the FILE_LINK_INFORMATION structure contained in Irp->AssociatedIrp.SystemBuffer
Code:
typedef struct _FILE_LINK_INFORMATION {
BOOLEAN ReplaceIfExists;
HANDLE RootDirectory;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;
There is one more bit of info given by IrpTracker that I didn't show, which may be the return from the hook in Ntfs, and it points to the _NtfsCompleteRequest function.
So what we've got now is an ntfs function to break on (_NtfsCompleteRequest) and a conditional parameter to test for (Irp->AssociatedIrp.SystemBuffer => FILE_LINK_INFORMATION.FileName). Tracing back from that should lead to the calling code.
Or, more directly, do a general break on the ntfs main Dispatch routine for IRP_MJ_SET_INFORMATION where IrpSp->Parameters.SetFile.FileInformationClass == FileLinkInformation
The IRP would have been issued via a fsutil CreateHardLink() call.
EDIT: This is found simply with Softice.
'Driver ntfs' gives offset of IRP_MJ_SET_INFORMATION, referencing with IDA points to
.text:00003ABB ; __stdcall NtfsFsdSetInformation
Or, all the IRP Major Functions are clearly listed in the INIT DriverEntry section with symbols anyway, so you can get it all from IDA alone.
My thinking then is that one might be able to trace from the breakpoint to the writing of the hardlink to the MFT.
EDIT: Function names of interest encountered:
NtfsUpdateScbFromFileObject, NtfsLookupInFileRecord, NtfsChangeAttributeValue, etc.....
so, yeah.
Here are a couple of links that support what should happen in theory at least:
"when you create a new hardlink for a file, ntfs will create a new filename($30) attribute in mft."
http://www.flexhex.com/docs/articles/hard-links.phtml
http://www.osronline.com/showthread.cfm?link=228355
Ultimately I don't know if this would provide an answer to whatever the current question is, it was just of a way of trying to get "into" the MFT.
Bookmarks