Welcome to the new Woodmann RCE Messageboards Regroupment
Please be patient while the rest of the site is restored.

To all Members of the old RCE Forums:
In order to log in, it will be necessary to reset your forum login password ("I forgot my password") using the original email address you registered with. You will be sent an email with a link to reset your password for that member account.

The old vBulletin forum was converted to phpBB format, requiring the passwords to be reset. If this is a problem for some because of a forgotten email address, please feel free to re-register with a new username. We are happy to welcome old and new members back to the forums! Thanks.

All new accounts are manually activated before you can post. Any questions can be PM'ed to Kayaker.

NTFS MFT Internals

Interesting low-level stuff, operating system related issues, packer/vx acrobatics, drivers and non-newbie programming in general, including win32 assembly and whatever else.
User avatar
Posts: 4169
Joined: Thu Oct 26, 2000 11:00 am

Post by Kayaker »

No worries Waxford, your detailing of your findings is mucho appreciated, it's nice to discuss something new for a change. Yes, it's certainly not an easy subject matter and there's definitely a lot to absorb in how the NTFS is laid out. Let alone the undocumented code paths you're trying to follow. I changed the title to hopefully draw others into the thread.

Thanks for the clarification on why you think Contig might not be working. Yeah, in the first link I posted it didn't work, but in the second it apparently did, as expected. Interestingly, I tried running chkdsk and it did find an error in the MFT Bitmap:

Code: Select all

CHKDSK discovered free space marked as allocated in the master file table (MFT) bitmap.
Correcting errors in the Volume Bitmap.
Windows found problems with the file system.
Run CHKDSK with the /F (fix) option to correct these.
After running chkdsk /f several times, all errors disappeared. However, Contig still gives the Failed to open C:\$Mft::$BITMAP: error.
To be fair though, this is a VM I'm trying this on.
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

i didnt have time to verify or reproduce or check the things so i cant reply any queries
i will just post generic thoughts on certain highlights

mft is was always 2 fragments as far as i have seen
if i have a severely fragmented mft i run fsutil usn deletejournal /n <drive> and recreate it (use query and save the max and alloc numbers first)
this normally brings back mft to 2 fragments

i normally run some boot defraggers (ultradefrag from source forge for example ) windows defrag yells that it needs 15% commision to work i cant even afford 1 % sometimes on my real machine

at the moment my mft is 93% full with 2 fragments and the fragmented file is always $bitmap

Code: Select all

Master File Table (MFT) fragmentation
    Total MFT size                             = 308 MB
    MFT record count                           = 295,224
    Percent MFT in use                         = 93 %
    Total MFT fragments                        = 2

Fragments 	Size 	Filename 	         Comment 	Status
10	       40 Kb	C:\$MFT::$BITMAP	- 	locked
as far as i have seen defragging BITMAP is kinda impossible as it has details about each and every sector including a reference to itself

i still dont believe shell and ole ole plays significant role in the process the object is created in R0 with ObCreateObjName & sisters and the handle is created with obpCreateObHandle and brothers does shell and ole send some undocumented DeviceIoControl to ntfs.sys

NtCreateFile ->IoCreateFile -> IopCreateFile->ObopenObjectByName -> lookup which goes on into obinsertDirectoryEntry etc loops is how a new file is created
User avatar
Posts: 4169
Joined: Thu Oct 26, 2000 11:00 am

Post by Kayaker »

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 ... 85%29.aspx

I used fsutil to create the hard link (fsutil hardlink create NewFilename ExistingFilename)

http://www.microsoft.com/resources/docu ... x?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: Select all

>> IRP_MJ_SET_INFORMATION Drv:Ntfs, Dev:#822AA020, IRP:81BDF5B8, Proc:fsutil.exe, Thr:618
          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: Select all

typedef struct _FILE_LINK_INFORMATION {
  BOOLEAN ReplaceIfExists;
  HANDLE  RootDirectory;
  ULONG   FileNameLength;
  WCHAR   FileName[1];
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."


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.
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

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.
well you can get it for free with windbg alone :)

Code: Select all

lkd> [B].foreach /pS 1 /ps 100 (place {!object \Ntfs} ) {dt nt!_device_object -y -a Driv->maj place }[/B]
   +0x008 DriverObject : 
      +0x038 MajorFunction : 
       [00] 0xa952a918        long  +0
       [01] 0x804f355a        long  nt!IopInvalidDeviceRequest+0
       [02] 0xa952a958        long  +0
       [03] 0xf73d1f2f        long  Ntfs!NtfsFsdRead+0
       [04] 0xa952aa20        long  +0
       [05] 0xf73f54b9        long  Ntfs!NtfsFsdDispatchWait+0
       [06] [B]0xa952aa60[/B]        long  +0      <---------------- IRP_MJ_SET_INFORMATION (mine is hooked by avast see below)
       [07] 0xf73f54b9        long  Ntfs!NtfsFsdDispatchWait+0
       [08] 0xf73f54b9        long  Ntfs!NtfsFsdDispatchWait+0
       [09] 0xf740f0e5        long  Ntfs!NtfsFsdFlushBuffers+0
       [10] 0xf73f5604        long  Ntfs!NtfsFsdDispatch+0
       [11] 0xf73f5604        long  Ntfs!NtfsFsdDispatch+0
       [12] 0xf73f71bd        long  Ntfs!NtfsFsdDirectoryControl+0
       [13] 0xf73f9958        long  Ntfs!NtfsFsdFileSystemControl+0
       [14] 0xf73f5604        long  Ntfs!NtfsFsdDispatch+0
       [15] 0x804f355a        long  nt!IopInvalidDeviceRequest+0
       [16] 0xf73e37f2        long  Ntfs!NtfsFsdShutdown+0
       [17] 0xf7448ce9        long  Ntfs!NtfsFsdLockControl+0
       [18] 0xa952a9bc        long  +0
       [19] 0x804f355a        long  nt!IopInvalidDeviceRequest+0
       [20] 0xf73f5604        long  Ntfs!NtfsFsdDispatch+0
       [21] 0xf73f5604        long  Ntfs!NtfsFsdDispatch+0
       [22] 0x804f355a        long  nt!IopInvalidDeviceRequest+0
       [23] 0x804f355a        long  nt!IopInvalidDeviceRequest+0
       [24] 0x804f355a        long  nt!IopInvalidDeviceRequest+0
       [25] 0xf73f54b9        long  Ntfs!NtfsFsdDispatchWait+0
       [26] 0xf73f54b9        long  Ntfs!NtfsFsdDispatchWait+0
       [27] 0xf7411a0e        long  Ntfs!NtfsFsdPnp+0
avast hook for fsdsetinfo call

Code: Select all

[B]lkd> uf 0xa952aa60[/B]
a952aa60 8bff            mov     edi,edi
a952aa62 55              push    ebp
a952aa63 8bec            mov     ebp,esp
a952aa65 803d943655a900  cmp     byte ptr [aswSP+0x4f694 (a9553694)],0
a952aa6c 7526            jne     aswSP+0x26a94 [B](a952aa94)[/B]  

[B]a952aa94 5d[/B]              pop     ebp
a952aa95 ff25682255a9    jmp     dword ptr [aswSP+0x4e268 ([B]a9552268)[/B]]

lkd> [B]ln poi(a9552268)[/B]
(f73d2abb)   Ntfs!NtfsFsdSetInformation   |  (f73d2c3f)   Ntfs!NtfsSetBothCacheSizes
[B]Exact matches:
    Ntfs!NtfsFsdSetInformation = <no type information>
hows dat fer braggin my 1337 windbag skillzzzzjj

oops i hear @w going will ya wanna tell me what tis dat

it takes the DeviceObject pointer from Global NameSpace (\)
or you can find the driver object directly from \FileSystem\Ntfs also
Device object contains a pointer to DriverObject which lists the resolved address for all IRP_MJ's in an array
the pS ps crap is to cut off junk the work is done by dt -a switch to expand the array -y switch to input partial names
User avatar
Posts: 4169
Joined: Thu Oct 26, 2000 11:00 am

Post by Kayaker »

Lol, I knew that was coming.

So, Windbag master, now that you mention it, I'm curious if Avast also hooks ZwSetInformationFile, or instead it's doing it at the lower level IRP_MJ_SET_INFORMATION stage only, to presumably make it harder to anti-anti?
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

you mean avast leaves anything unhooked ? nah impossible it hooks every imaginable function it hooks even if the function doesn't exist

lkd> r $t0 = 0 ; .foreach (plcae { !grep -i -e "asw" -c "dpS nt!KiServiceTable l?0x11c" } ) {r$t0 = @$t0+1} ; ? @$t0
Evaluate expression: 112 = 00000070

so it is hooking 0x70 out of 0x11c functions

thread hijacked :) split it will ya if someone posts kav hooks more than avast mcafee never hooks but overwrites the os

some error i hard counted and didnt see 112 hooks but 50 odd hooks still and this script matches it with !chkimg output

lkd> .shell -ci "dpS nt!KiServiceTable l?0x11c" grep -i asw | wc -l
.shell: Process exited

Code: Select all

lkd> .shell -ci "dpS nt!KiServiceTable l?0x11c" grep -i asw | wc -l
.shell: Process exited
lkd> .shell -ci "dpS nt!KiServiceTable l?0x11c" grep -n -i asw
10: a945d610 aswSnx+0x18610
18: a95115fa aswSP+0xd5fa
20: a945e0e6 aswSnx+0x190e6
26: a94a1b36 aswSnx+0x5cb36
36: a9469f18 aswSnx+0x24f18
37: a9469f64 aswSnx+0x24f64
39: a946a0fe aswSnx+0x250fe
42: a94a14ea aswSnx+0x5c4ea
44: a9469e86 aswSnx+0x24e86
51: a9469fa8 aswSnx+0x24fa8
52: a9469ece aswSnx+0x24ece
54: a945e5e4 aswSnx+0x195e4
55: a946a0b8 aswSnx+0x250b8
58: a945ee9c aswSnx+0x19e9c
62: a945d676 aswSnx+0x18676
64: a94a21fc aswSnx+0x5d1fc
66: a94a24b2 aswSnx+0x5d4b2
69: a9462596 aswSnx+0x1d596
72: a94a2067 aswSnx+0x5d067
74: a94a1ed2 aswSnx+0x5ced2
84: a95116c2 aswSP+0xd6c2
98: a945d25e aswSnx+0x1825e
110: a945d6dc aswSnx+0x186dc
112: a946298c aswSnx+0x1d98c
113: a945f92c aswSnx+0x1a92c
115: a9469f42 aswSnx+0x24f42
116: a9469f86 aswSnx+0x24f86
118: a946a122 aswSnx+0x25122
120: a94a1846 aswSnx+0x5c846
121: a9469eac aswSnx+0x24eac
123: a9461e78 aswSnx+0x1ce78
126: a946a036 aswSnx+0x25036
127: a9469ef6 aswSnx+0x24ef6
129: a946226e aswSnx+0x1d26e
132: a946a0dc aswSnx+0x250dc
138: a9511822 aswSP+0xd822
161: a94a1d4d aswSnx+0x5cd4d
164: a945f7f8 aswSnx+0x1a7f8
178: a94a1b9f aswSnx+0x5cb9f
181: a945f34e aswSnx+0x1a34e
193: a951e744 aswSP+0x1a744
205: a94a0b30 aswSnx+0x5bb30
212: a945d742 aswSnx+0x18742
213: a945d7a8 aswSnx+0x187a8
214: a945ed16 aswSnx+0x19d16
241: a945d2f8 aswSnx+0x182f8
242: a945d4ce aswSnx+0x184ce
248: a94a2303 aswSnx+0x5d303
250: a945d45c aswSnx+0x1845c
254: a945f066 aswSnx+0x1a066
255: a945f1c8 aswSnx+0x1a1c8
256: a945d556 aswSnx+0x18556
258: a945eb54 aswSnx+0x19b54
259: a945ecf6 aswSnx+0x19cf6
263: a950fc42 aswSP+0xbc42
269: a945d80e aswSnx+0x1880e
278: a945e142 aswSnx+0x19142
.shell: Process exited

lkd> !chkimg -d -np nt
    80501bc8-80501bcb  4 bytes - nt!KiServiceTable+24
	[ ec cb 60 80:10 d6 45 a9 ]
    80501be8-80501beb  4 bytes - nt!KiServiceTable+44 (+0x20)
	[ 30 de 59 80:fa 15 51 a9 ]
    80501bf0-80501bf3  4 bytes - nt!KiServiceTable+4c (+0x08)
	[ 44 c9 5c 80:e6 e0 45 a9 ]
    80501c08-80501c0b  4 bytes - nt!KiServiceTable+64 (+0x18)
	[ ba 1c 5b 80:36 1b 4a a9 ]
    80501c30-80501c37  8 bytes - nt!KiServiceTable+8c (+0x28)
	[ ce 51 60 80 70 d4 60 80:18 9f 46 a9 64 9f 46 a9 ]
    80501c3c-80501c3f  4 bytes - nt!KiServiceTable+98 (+0x0c)
	[ cc dc 56 80:fe a0 46 a9 ]
    80501c48-80501c4b  4 bytes - nt!KiServiceTable+a4 (+0x0c)
	[ 44 a3 61 80:ea 14 4a a9 ]
    80501c50-80501c53  4 bytes - nt!KiServiceTable+ac (+0x08)
	[ 68 d8 60 80:86 9e 46 a9 ]
    80501c6c-80501c73  8 bytes - nt!KiServiceTable+c8 (+0x1c)
	[ 5c 07 5a 80 04 b2 60 80:a8 9f 46 a9 ce 9e 46 a9 ]
    80501c78-80501c7f  8 bytes - nt!KiServiceTable+d4 (+0x0c)
	[ 88 72 5c 80 38 d1 60 80:e4 e5 45 a9 b8 a0 46 a9 ]
    80501c88-80501c8b  4 bytes - nt!KiServiceTable+e4 (+0x10)
	[ bc 9d 63 80:9c ee 45 a9 ]
    80501c98-80501c9b  4 bytes - nt!KiServiceTable+f4 (+0x10)
	[ 2a d1 60 80:76 d6 45 a9 ]
    80501ca0-80501ca3  4 bytes - nt!KiServiceTable+fc (+0x08)
	[ e0 a7 61 80:fc 21 4a a9 ]
    80501ca8-80501cab  4 bytes - nt!KiServiceTable+104 (+0x08)
	[ b0 a9 61 80:b2 24 4a a9 ]
    80501cb4-80501cb7  4 bytes - nt!KiServiceTable+110 (+0x0c)
	[ ce 38 5b 80:96 25 46 a9 ]
    80501cc0-80501cc3  4 bytes - nt!KiServiceTable+11c (+0x0c)
	[ 90 ab 61 80:67 20 4a a9 ]
    80501cc8-80501ccb  4 bytes - nt!KiServiceTable+124 (+0x08)
	[ fa ad 61 80:d2 1e 4a a9 ]
    80501cf0-80501cf3  4 bytes - nt!KiServiceTable+14c (+0x28)
	[ 70 84 5a 80:c2 16 51 a9 ]
    80501d28-80501d2b  4 bytes - nt!KiServiceTable+184 (+0x38)
	[ fa 95 57 80:5e d2 45 a9 ]
    80501d58-80501d5b  4 bytes - nt!KiServiceTable+1b4 (+0x30)
	[ 2a d1 60 80:dc d6 45 a9 ]
    80501d60-80501d67  8 bytes - nt!KiServiceTable+1bc (+0x08)
	[ 32 c5 61 80 66 b1 61 80:8c 29 46 a9 2c f9 45 a9 ]
    80501d6c-80501d73  8 bytes - nt!KiServiceTable+1c8 (+0x0c)
	[ ce 52 60 80 48 d5 60 80:42 9f 46 a9 86 9f 46 a9 ]
    80501d78-80501d7b  4 bytes - nt!KiServiceTable+1d4 (+0x0c)
	[ a4 dd 56 80:22 a1 46 a9 ]
    80501d80-80501d87  8 bytes - nt!KiServiceTable+1dc (+0x08)
	[ 22 b7 61 80 40 d9 60 80:46 18 4a a9 ac 9e 46 a9 ]
    80501d8c-80501d8f  4 bytes - nt!KiServiceTable+1e8 (+0x0c)
	[ 16 13 5c 80:78 1e 46 a9 ]
    80501d98-80501d9f  8 bytes - nt!KiServiceTable+1f4 (+0x0c)
	[ 92 f7 59 80 fe b2 60 80:36 a0 46 a9 f6 9e 46 a9 ]
    80501da4-80501da7  4 bytes - nt!KiServiceTable+200 (+0x0c)
	[ a2 15 5c 80:6e 22 46 a9 ]
    80501db0-80501db3  4 bytes - nt!KiServiceTable+20c (+0x0c)
	[ 5a d2 60 80:dc a0 46 a9 ]
    80501dc8-80501dcb  4 bytes - nt!KiServiceTable+224 (+0x18)
	[ 88 da 5a 80:22 18 51 a9 ]
    80501e24-80501e27  4 bytes - nt!KiServiceTable+280 (+0x5c)
	[ 64 ba 61 80:4d 1d 4a a9 ]
    80501e30-80501e33  4 bytes - nt!KiServiceTable+28c (+0x0c)
	[ cc b0 5b 80:f8 f7 45 a9 ]
    80501e68-80501e6b  4 bytes - nt!KiServiceTable+2c4 (+0x38)
	[ 68 85 61 80:9f 1b 4a a9 ]
    80501e74-80501e77  4 bytes - nt!KiServiceTable+2d0 (+0x0c)
	[ e6 74 5c 80:4e f3 45 a9 ]
    80501ea4-80501ea7  4 bytes - nt!KiServiceTable+300 (+0x30)
	[ 66 9d 61 80:44 e7 51 a9 ]
    80501ed4-80501ed7  4 bytes - nt!KiServiceTable+330 (+0x30)
	[ 24 bd 61 80:30 0b 4a a9 ]
    80501ef0-80501efb  12 bytes - nt!KiServiceTable+34c (+0x1c)
	[ ec cb 60 80 ec cb 60 80:42 d7 45 a9 a8 d7 45 a9 ]
    80501f64-80501f6b  8 bytes - nt!KiServiceTable+3c0 (+0x74)
	[ 20 5f 60 80 d6 90 64 80:f8 d2 45 a9 ce d4 45 a9 ]
    80501f80-80501f83  4 bytes - nt!KiServiceTable+3dc (+0x1c)
	[ b6 88 61 80:03 23 4a a9 ]
    80501f88-80501f8b  4 bytes - nt!KiServiceTable+3e4 (+0x08)
	[ 3c 91 60 80:5c d4 45 a9 ]
    80501f98-80501fa3  12 bytes - nt!KiServiceTable+3f4 (+0x10)
	[ 6a ad 5c 80 dc ab 5c 80:66 f0 45 a9 c8 f1 45 a9 ]
    80501fa8-80501faf  8 bytes - nt!KiServiceTable+404 (+0x10)
	[ aa 8c 5c 80 a4 8e 5c 80:54 eb 45 a9 f6 ec 45 a9 ]
    80501fbc-80501fbf  4 bytes - nt!KiServiceTable+418 (+0x14)
	[ 8e 97 57 80:42 fc 50 a9 ]
    80501fd4-80501fd7  4 bytes - nt!KiServiceTable+430 (+0x18)
	[ bc 15 5f 80:0e d8 45 a9 ]
    80501ff8-80501ffb  4 bytes - nt!KiServiceTable+454 (+0x24)
	[ 90 98 5a 80:42 e1 45 a9 ]
    8059b832-8059b835  4 bytes - nt!NtReplyWaitReceivePortEx+5ec
	[ 35 c7 f9 ff:a2 47 ec 28 ]
    805b1ce0-805b1ce4  5 bytes - nt!ObMakeTemporaryObject (+0x164ae)
	[ 8b ff 55 8b ec:e9 b5 5f f7 28 ]
    805b8b58-805b8b5c  5 bytes - nt!ObInsertObject (+0x6e78)
	[ 8b ff 55 8b ec:e9 57 0c f7 28 ]
    805c73ea-805c73f0  7 bytes - nt!NtCreateProcessEx (+0xe892)
	[ 6a 0c 68 d8 9e 4d 80:e9 15 3a f6 28 cc cc ]
249 errors : nt (80501bc8-805c73f0)
Posts: 35
Joined: Sun Oct 30, 2011 6:27 am

Post by deepzero »

woah, can oyu explain how your lkd-kung-fu works?

I am guessing you somehow check in which module a given address lies, and if it contains "asw" it's an avast module? Really dont see that in the script, though...
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

woah, can oyu explain how your lkd-kung-fu works?
which form you want explained snake in monkeys shadow or cats paw ?
i guess ill smoke pot and trip the chair see if you can dodge

dpS = display data by de-referrencing a pointer and resolving the symbol associated with the de-referenced pointer

how it works

lets find the address of nt!kiServiceTable

lkd> x nt!KiServiceTable
80501ba4 nt!KiServiceTable = <no type information> assuming you open this memory address in a hexeditor you will see

lkd> db nt!KiServiceTable l10
80501ba4 ba 99 59 80 36 6e 5e 80-94 a6 5e 80 68 6e 5e 80 ..Y.6n^...^.hn^.

that address is pointing to 0x805999ba

lkd> dd nt!KiServiceTable l1
80501ba4 805999ba

now if you open this memory address in hexeditor you will see

lkd> db 805999ba
805999ba 68 9c 00 00 00 68 40 91-4d 80 e8 67 e5 f9 ff 64 [email protected]

wouldn't make much sense in hexeditor so you would have to resort to disassembling and seeing if this is code or you can guess this is code because 68 is opcode for push you see two 68 and one e8 for call push 9c / push 804d9140 call negative offset (fff9e567) so if this is code does it have name ? symbol ??

so you would need to do list nearest symbol ln

lkd> ln 805999ba
(805999ba) nt!NtAcceptConnectPort | (8059a0a8) nt!NtCompleteConnectPort
Exact matches:
nt!NtAcceptConnectPort = <no type information>

dpS does all this for you and will spit nt!NtAcceptConnectPort if you provide it the first address / symbol

lkd> dpS 80501ba4 l1
805999ba nt!NtAcceptConnectPort

lkd> dpS nt!KiServiceTable l1
805999ba nt!NtAcceptConnectPort

so when you do dpS on a range of Address each line of output will have the module name symbol name

now on an unhooked machine service table entries should all point to address in ntos/ntkern
if the address points to an address that does not lie in ntos/ntkern then it must be hooked

and dpS dutifully would resolve the module name atleast + a bogus / exported nearest symbol like


like this

lkd> dpS nt!KiServiceTable+40 l3
8060bae6 nt!NtAllocateUuids
a95115fa aswSP+0xd5fa
805a5a70 nt!NtAreMappedFilesTheSame

so service table entry 0x11 is hooked by one aswmodule

on an unhooked machine that would NtAllocateVirtualMemory

Code: Select all

NtAllocateUuids 				0x0010  	 0x0010  	 0x0010  	 0x0010  												
NtAllocateVirtualMemory 		0x0011  	 0x0011  	 0x0011  	 0x0011  												
NtAreMappedFilesTheSame 		0x0012  	 0x0012  	 0x0012  	 0x0012  			
what is the module information for aswxxxx

Code: Select all

lkd> lm f a a95115fa
start    end        module name
a9504000 a955b800   aswSP    \SystemRoot\System32\Drivers\aswSP.SYS

lm m asw* in windbg will get the names of all other modules that starts with asw

running this one liner from a command prompt will tell  this file's manufacturer  
(can be fake  info is ok only  for prima facie investigation any tom can call dick hairy)

C:\>for /F %I IN ( 'DIR  /b C:\WINDOWS\SYSTEM32\DRIVERS\ASW*.sys') DO wmic datafile where name="c:\\windows\\system32\\drivers\\%~I" get manufacturer /format:list
Manufacturer=AVAST Software
so what is the script doing
User avatar
Posts: 3605
Joined: Fri Jan 26, 2001 6:28 pm

Post by Woodmann »

Crane style ? :p


Sorry, I just had to.
Learn Or Die.
Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

crane style ? oh possible i just edited the original posts output
cranes can have big beek so it can reach farther
it can now indicate the service function index on each hooked function

the number in front of the output is 1 based index service function entry is 0 based index so you need to minus 1 from each number to get the unhooked function

cranes can wait for long too till suitable fish comes by

Code: Select all

lkd> .for (r $t0 =0; @$t0 < 0x11c*4;  r $t0 = @$t0+4) { .if ( poi([email protected]$t0) > 806cf980)  { .printf "Service index 0x%x is hooked by 0x%x %y\n", @@masm(@$t0/4) , @@masm(poi([email protected]$t0)) ,@@masm(poi([email protected]$t0)) } }
Service index 0x9 is hooked by 0xa945d610 aswSnx+0x18610 (a945d610)
Service index 0x11 is hooked by 0xa95115fa aswSP+0xd5fa (a95115fa)
Service index 0x13 is hooked by 0xa945e0e6 aswSnx+0x190e6 (a945e0e6)
Service index 0x19 is hooked by 0xa94a1b36 aswSnx+0x5cb36 (a94a1b36)
Service index 0x23 is hooked by 0xa9469f18 aswSnx+0x24f18 (a9469f18)

Service index 0x10c is hooked by 0xa945d80e aswSnx+0x1880e (a945d80e)
Service index 0x115 is hooked by 0xa945e142 aswSnx+0x19142 (a945e142)

Senior Member
Posts: 1535
Joined: Wed Dec 08, 2004 11:12 am

Post by blabberer »

@ k avast is hooking all these functions
( i got bored looking up jooru metasploit etc for function names setup a clean vm and got the unaltered service function names from it to a txt file for comparison and tweaked the script above to use that file )

the tweaked script as follows

Code: Select all

r $t1 =-1 ;.foreach /ps 1 ( place { dpS nt!KiServiceTable l?0x11c } ) { r $t0 = place; r $t1 = @$t1 + 1; .if( @$t0 > 0x806cf980) { .printf "Service Function %08x is hooked by %08x %y\n" , @$t1, @$t0 , @$t0};  } 
r $t1 =-1 ;.foreach /ps 1 ( place { dpS nt!KiServiceTable l?0x11c } ) { r $t0 = place; r $t1 = @$t1 + 1; .if( @$t0 > 0x806cf980) { .shell -ci ".printf \"%08d\n\" , @$t1" gawk {"print $1"} > h.txt & grep -f h.txt service_functions.txt} } }

the result as follows

Code: Select all

lkd> $$>a< .\scripts\print_hooked_ssdt_functions.txt
Service Function 00000009 is hooked by a945d610 aswSnx+0x18610 (a945d610)
Service Function 00000017 is hooked by a95115fa aswSP+0xd5fa (a95115fa)
Service Function 00000019 is hooked by a945e0e6 aswSnx+0x190e6 (a945e0e6)
Service Function 00000025 is hooked by a94a1b36 aswSnx+0x5cb36 (a94a1b36)
Service Function 00000035 is hooked by a9469f18 aswSnx+0x24f18 (a9469f18)
Service Function 00000036 is hooked by a9469f64 aswSnx+0x24f64 (a9469f64)
Service Function 00000038 is hooked by a946a0fe aswSnx+0x250fe (a946a0fe)
Service Function 00000041 is hooked by a94a14ea aswSnx+0x5c4ea (a94a14ea)
Service Function 00000043 is hooked by a9469e86 aswSnx+0x24e86 (a9469e86)
Service Function 00000050 is hooked by a9469fa8 aswSnx+0x24fa8 (a9469fa8)
Service Function 00000051 is hooked by a9469ece aswSnx+0x24ece (a9469ece)
Service Function 00000053 is hooked by a945e5e4 aswSnx+0x195e4 (a945e5e4)
Service Function 00000054 is hooked by a946a0b8 aswSnx+0x250b8 (a946a0b8)
Service Function 00000057 is hooked by a945ee9c aswSnx+0x19e9c (a945ee9c)
Service Function 00000061 is hooked by a945d676 aswSnx+0x18676 (a945d676)
Service Function 00000063 is hooked by a94a21fc aswSnx+0x5d1fc (a94a21fc)
Service Function 00000065 is hooked by a94a24b2 aswSnx+0x5d4b2 (a94a24b2)
Service Function 00000068 is hooked by a9462596 aswSnx+0x1d596 (a9462596)
Service Function 00000071 is hooked by a94a2067 aswSnx+0x5d067 (a94a2067)
Service Function 00000073 is hooked by a94a1ed2 aswSnx+0x5ced2 (a94a1ed2)
Service Function 00000083 is hooked by a95116c2 aswSP+0xd6c2 (a95116c2)
Service Function 00000097 is hooked by a945d25e aswSnx+0x1825e (a945d25e)
Service Function 00000109 is hooked by a945d6dc aswSnx+0x186dc (a945d6dc)
Service Function 00000111 is hooked by a946298c aswSnx+0x1d98c (a946298c)
Service Function 00000112 is hooked by a945f92c aswSnx+0x1a92c (a945f92c)
Service Function 00000114 is hooked by a9469f42 aswSnx+0x24f42 (a9469f42)
Service Function 00000115 is hooked by a9469f86 aswSnx+0x24f86 (a9469f86)
Service Function 00000117 is hooked by a946a122 aswSnx+0x25122 (a946a122)
Service Function 00000119 is hooked by a94a1846 aswSnx+0x5c846 (a94a1846)
Service Function 00000120 is hooked by a9469eac aswSnx+0x24eac (a9469eac)
Service Function 00000122 is hooked by a9461e78 aswSnx+0x1ce78 (a9461e78)
Service Function 00000125 is hooked by a946a036 aswSnx+0x25036 (a946a036)
Service Function 00000126 is hooked by a9469ef6 aswSnx+0x24ef6 (a9469ef6)
Service Function 00000128 is hooked by a946226e aswSnx+0x1d26e (a946226e)
Service Function 00000131 is hooked by a946a0dc aswSnx+0x250dc (a946a0dc)
Service Function 00000137 is hooked by a9511822 aswSP+0xd822 (a9511822)
Service Function 00000160 is hooked by a94a1d4d aswSnx+0x5cd4d (a94a1d4d)
Service Function 00000163 is hooked by a945f7f8 aswSnx+0x1a7f8 (a945f7f8)
Service Function 00000177 is hooked by a94a1b9f aswSnx+0x5cb9f (a94a1b9f)
Service Function 00000180 is hooked by a945f34e aswSnx+0x1a34e (a945f34e)
Service Function 00000192 is hooked by a951e744 aswSP+0x1a744 (a951e744)
Service Function 00000204 is hooked by a94a0b30 aswSnx+0x5bb30 (a94a0b30)
Service Function 00000211 is hooked by a945d742 aswSnx+0x18742 (a945d742)
Service Function 00000212 is hooked by a945d7a8 aswSnx+0x187a8 (a945d7a8)
Service Function 00000213 is hooked by a945ed16 aswSnx+0x19d16 (a945ed16)
Service Function 00000240 is hooked by a945d2f8 aswSnx+0x182f8 (a945d2f8)
Service Function 00000241 is hooked by a945d4ce aswSnx+0x184ce (a945d4ce)
Service Function 00000247 is hooked by a94a2303 aswSnx+0x5d303 (a94a2303)
Service Function 00000249 is hooked by a945d45c aswSnx+0x1845c (a945d45c)
Service Function 00000253 is hooked by a945f066 aswSnx+0x1a066 (a945f066)
Service Function 00000254 is hooked by a945f1c8 aswSnx+0x1a1c8 (a945f1c8)
Service Function 00000255 is hooked by a945d556 aswSnx+0x18556 (a945d556)
Service Function 00000257 is hooked by a945eb54 aswSnx+0x19b54 (a945eb54)
Service Function 00000258 is hooked by a945ecf6 aswSnx+0x19cf6 (a945ecf6)
Service Function 00000262 is hooked by a950fc42 aswSP+0xbc42 (a950fc42)
Service Function 00000268 is hooked by a945d80e aswSnx+0x1880e (a945d80e)
Service Function 00000277 is hooked by a945e142 aswSnx+0x19142 (a945e142)

00000009 nt!NtAddBootEntry (8064986f)

00000017 nt!NtAllocateVirtualMemory (805691ea)

00000019 nt!NtAssignProcessToJobObject (805a2c27)

00000025 nt!NtClose (80567aed)

00000035 nt!NtCreateEvent (80570022)

00000036 nt!NtCreateEventPair (80649ec0)

00000038 nt!NtCreateIoCompletion (8058fc37)

00000041 nt!NtCreateKey (8057376f)

00000043 nt!NtCreateMutant (805775c8)

00000050 nt!NtCreateSection (80565333)

00000051 nt!NtCreateSemaphore (8057b80d)

00000053 nt!NtCreateThread (80578803)

00000054 nt!NtCreateTimer (80588a6b)

00000057 nt!NtDebugActiveProcess (8065bf7d)

00000061 nt!NtCancelDeviceWakeupRequest (8062c782)

00000063 nt!NtDeleteKey (80597ffa)

00000065 nt!NtDeleteValueKey (80595c1a)

00000068 nt!NtDuplicateObject (805748c2)

00000071 nt!NtEnumerateKey (80573e7d)

00000073 nt!NtEnumerateValueKey (8057fb2b)

00000083 nt!NtFreeVirtualMemory (80569b15)

00000097 nt!NtLoadDriver (805a425d)

00000109 nt!NtCancelDeviceWakeupRequest (8062c782)

00000111 nt!NtNotifyChangeKey (80593faa)

00000112 nt!NtNotifyChangeMultipleKeys (80594073)

00000114 nt!NtOpenEvent (8057fc98)

00000115 nt!NtOpenEventPair (80649fb3)

00000117 nt!NtOpenIoCompletion (80616dab)

00000119 nt!NtOpenKey (80568f68)

00000120 nt!NtOpenMutant (80577676)

00000122 nt!NtOpenProcess (80574aa9)

00000125 nt!NtOpenSection (8056e467)

00000126 nt!NtOpenSemaphore (805dd9ac)

00000128 nt!NtOpenThread (8059323b)

00000131 nt!NtOpenTimer (80649de9)

00000137 nt!NtProtectVirtualMemory (80574e58)

00000160 nt!NtQueryKey (80573b86)

00000163 nt!NtQueryObject (80580a94)

00000177 nt!NtQueryValueKey (8056a419)

00000180 nt!NtQueueApcThread (8058f954)

00000192 nt!NtRenameKey (8064f526)

00000204 nt!NtRestoreKey (8064fa19)

00000211 nt!NtAddBootEntry (8064986f)

00000212 nt!NtAddBootEntry (8064986f)

00000213 nt!NtSetContextThread (8062e33f)

00000240 nt!NtSetSystemInformation (805a8349)

00000241 nt!NtSetSystemPowerState (8066848b)

00000247 nt!NtSetValueKey (8057bc5b)

00000249 nt!NtShutdownSystem (80647ef7)

00000253 nt!NtSuspendProcess (8062ff21)

00000254 nt!NtSuspendThread (805e05ab)

00000255 nt!NtSystemDebugControl (8064aa57)

00000257 nt!NtTerminateProcess (805839b9)

00000258 nt!NtTerminateThread (80577f1f)

00000262 nt!NtUnloadDriver (8061a212)

00000268 nt!NtVdmControl (805c02da)

00000277 nt!NtWriteVirtualMemory (8057f712)
Senior Member
Posts: 1001
Joined: Tue Apr 06, 2004 11:00 am

Post by WaxfordSqueers »

blabberer wrote:i still dont believe shell and ole ole plays significant role in the process
Sorry I haven't been around for a while. I have intended to find out more about NTFS but matters beyond my control have intervened. Hopefully I'll get back to it sometime.

I have a healthy 500 gig drive tied up because I want to use it to inspect the damage. I have decided the NTFS file system cannot be recovered so I'm going to reformat the drive. The reason I think it can't be recovered is because most of the files that make up the MFT have been overwritten. The index files are all there, or seem to be.

About shell and ole. The reason I think they are involved is that I have traced right through to NTFS.sys from Windows Explorer and another file manager. Using softice, I have traced from Explorer through shell32 to ntfs.sys and back to shell32. I can see references to shell32 and ntfs.sys in the stack with return addresses from ntfs.sys right back to shell32.

As you know, Explorer is based on a namespace system that uses its own file record structures, called ITEMID structures. Each file in an NTFS system is identified in Explorer with one structure per file. Those structures have to lead to the NTFS system somehow and shell32 is the shell manager that handles those structures.

I could be wrong but it makes sense to me that shell32 calls into the NTFS structure somehow. A structure in shell 32 is called early on which contains information about the file being loaded. The structure tells the system whether the file is an executable, or whatever type of file it is. From there, the code goes deep into shell32, ole32, shlwapi with seemingly endless parsing of the file ITEMID structure.

There may be some reference somewhere in that structure to the MFT.

I have set breakpoints while in Explorer to break before shell32, then traced into shell32. I have also traced to just after the Explorer.exe entry point in U32 then set a breakpoint for a function in ntfs.sys.

If I look at the stack along the way I can see shell32 listed as a return address.

Unfortunately, due to the depth of the nesting, and the seemingly endless checks on file structure after file structure in shell32, I have lost my way. I can set a breakpoint on a file and get to ntfs.sys no problem, it's just that when I get there the file seems to already have been found.

If I have some spare time and a clear enough mind, I may just try it with more tenacity sometime. There are times when I get lost that I take shortcuts to get back to a point in the code and I think I am jumping over important code that calls into ntfs before the disk is accessed.

Sometimes I get lost in win32.sys which is a major pain to get out of. Other times I get caught in waitforsingleobject, etc., and at other times I get caught in the code of other apps. As Kayaker pointed out, in a VM, it's easy to get caught in the VM code.

Ntfs.sys is surprisingly easy to trace through once you're in it, but there are times when it returns all the way back to an address in shell32 then all the way back to ntfs.sys.
Senior Member
Posts: 1001
Joined: Tue Apr 06, 2004 11:00 am

Post by WaxfordSqueers »

WaxfordSqueers wrote: I can see references to shell32 and ntfs.sys in the stack with return addresses from ntfs.sys right back to shell32.
Here's a handwritten copy of the stack I made while tracing a while back. It's not complete with regard to all return addresses. Those addresses shown are return addresses of the function in the following line.

I put a BP on [email protected] and when it broke, this was most of the stack:

Code: Select all

F73109E2	[email protected]
		[email protected]
804E37F7	Ntfs!_loc_38248
F73A306B	Ntoskrnl!IofCallDriver
8057216E	Ntoskrnl!IofCallDriver
804DE7Ec	Ntoskrnl!NtQueryDirectoryFile
77F742F9	K32!GetLongPathNameW
7E1EA64D	Shlwapi!.text + 132F9
7E1EA56D	urlmon!.text + 9646
77F74185	urlmon!.text + 2AA3
77F740EF	Shlwapi!.text + 13185
7CA04C37	Shlwapi!.text + 130EF
7CA04173	Shell32!CRegFolder::GetOverlayIndex
7CA040FA	Shell32!CInfoTip::AddRef
7CA03071	Shell32!CShellCmdFileIcon::'vftable'
7CA02FCE	Shell32!CDefView::FindItem
7CA02F6A	Shell32!CFSFolder::HandlerCreateInstance
7CA0F71B	Shell32!CDragImages::Show
7CA0F5A7	Shell32!CShellLink::_ShortRetTimeout
7CAA5D63	Shell32!CShellLink::_UpdateIconFrom.....
7CAAAAFC	Shell32!CDUIView::Release 
The functions shown are generalized areas in the dlls and don't necessarily indicate the exact function being executed. It's plain to see, however, that Shell32 leads to NTFS.sys.

I am still not sure where in the file location process this takes place. It seems to me the file I am looking for was found before this code appeared.

Note that the last call came from shlwapi which is the Shell lite version. Then there's a call into kernel32 to GetLongPathNameW and FindFirstFile.

This could be a search for the file date/time info required at a later time, after the file has been located.

It should be noted that I traced this code initially from Windows file explorer by setting a BP on a window in Explorer and double-clicking the file I wanted to load. The BP breaks in the Explorer process then runs through shell32, shwlapi and ole32.

I have a stack trace somewhere of the beginning of that process if it interests anyone. The initial stack info is concerned more with identifying the window clicked in Explorer and checking lparam and wparam in the message.
Senior Member
Posts: 1001
Joined: Tue Apr 06, 2004 11:00 am

Post by WaxfordSqueers »

WaxfordSqueers wrote:Here's a handwritten copy of the stack I made while tracing a while back.
Have not done anything important but made a small discovery related to the MFT.

The hard drive on my laptop had been going since 2009 with all sorts of file activity. As a result, the MFT had become split into 2 sections with the two dataruns sequences clearly indicated in the $MFT file near the end of the $80 attribute. I have since upgraded the hard drive to a larger drive and cloned the old OS to the larger drive, complete with split MFT.

I tried to defrag the MFT using Contig from Sysinternals and an older version of Diskeeper, which I bought years ago. Contig claimed the MFT was defragmented but it left it in two pieces. Same with Diskeeper, even though it has the abilty to defrag the MFT during a reboot.

I had read that Raxco Perfectdisk had the ability to defrag the MFT as well so I d/led the 30 day trial for version 13. The grid of the disk it supplies has the MFT highlighted in yellow. I let it analyze the disk and it found the disk defragged adequately. However, when I ran a defrag for the heck of it, Perfectdisk did an optimization that took more than an hour.

During the optimization, I watched it move the squares marked as MFT. However I knew my MFT was located at cluster 0xC0000 and after the defrag it was still there. The surprising thing was that SMFT now showed the MFT as being in one piece. It appears as if Perfectdisk did actually affect it significantly, although $MFT was in exactly the same cluster space at 0xC0000.

I am not pushing Perfectdisk but I am thinking of buying it based on the fact it did what it claimed it would do and it provides a grid one can watch as it works. I have just begun the 30 day trial so I'll keep an eye on it to see if there is any instability, or interference with the OS or other apps.
Senior Member
Posts: 1001
Joined: Tue Apr 06, 2004 11:00 am

Post by WaxfordSqueers »

Kayaker wrote:Lol, I knew that was coming.

So, Windbag master, now that you mention it, I'm curious if Avast also hooks ZwSetInformationFile, or instead it's doing it at the lower level IRP_MJ_SET_INFORMATION stage only, to presumably make it harder to anti-anti?
I know this comment is old but it just so happens I was messing with gmer the other day and it shows everything that is hooked under the 'Rootkit' tab. I'm sure you have more sophisticated ways of finding hooks but gmer seems to do a good job.

At least, it shows all the hooks if you leave everything checked to the right of the main screen.