Closed GoogleCodeExporter closed 8 years ago
We'll compare with windbg and investigate in particular the ControlArea
structure.
Original comment by michael.hale@gmail.com
on 13 Dec 2011 at 3:13
Turns out I still have access to the live machine from which this memory dump
was taken. I started up windbg and checked a few things. From the above
comment, note the important factors:
VAD node @81df20b8 Start 7ffda000 End 7ffdafff Tag Vadl
ControlArea @81df20a0 Segment 00000000
Invalid Address 0x0008000A, instantiating FileName
So the MMVAD_LONG is at 81df20b8 for starting address 7ffda000, the
CONTROL_AREA is allegedly 81df20a0, and from there the
CONTROL_AREA.FilePointer.FileName is invalid. The process we're dealing with is
winlogon.exe:
kd> !process 0 0
PROCESS 81dff6a8 SessionId: 0 Cid: 01dc Peb: 7ffdf000 ParentCid: 017c
DirBase: 168ae060 ObjectTable: e12b80d0 HandleCount: 520.
Image: winlogon.exe
kd> !vad 81dff6a8 + 250
81df20b8 ( 4) 7ffda 7ffda 1 Private READWRITE
kd> dt _MMVAD_LONG 81df20b8
nt!_MMVAD_LONG
+0x000 u1 : __unnamed
+0x004 LeftChild : 0x81de7888 _MMVAD
+0x008 RightChild : 0x81df2520 _MMVAD
+0x00c StartingVpn : 0x7ffda
+0x010 EndingVpn : 0x7ffda
+0x014 u : __unnamed
+0x018 ControlArea : 0x81df20a0 _CONTROL_AREA
+0x01c FirstPrototypePte : (null)
+0x020 LastContiguousPte : 0x81df2e70 _MMPTE
+0x024 u2 : __unnamed
+0x028 u3 : __unnamed
+0x030 u4 : __unnamed
So there really is an MMVAD_LONG at the address printed by vadinfo, and its
CONTROL_AREA really is at 0x81df20a0. No issues with Volatility's VAD parsing
yet per se. Now let's check out the CA:
kd> dt _CONTROL_AREA 0x81df20a0
nt!_CONTROL_AREA
+0x000 Segment : (null)
+0x004 DereferenceList : _LIST_ENTRY [ 0x12f0 - 0x136f ]
+0x00c NumberOfSectionReferences : 0x84000001
+0x010 NumberOfPfnReferences : 0xa080004
+0x014 NumberOfMappedViews : 0x6c646156
+0x018 NumberOfSystemCacheViews : 0x81e05e18
+0x01c NumberOfUserReferences : 0x81de7888
+0x020 u : __unnamed
+0x024 FilePointer : 0x0007ffda _FILE_OBJECT
+0x028 WaitingForDeletion : 0x0007ffda _EVENT_COUNTER
+0x02c ModifiedWriteCount : 1
+0x02e FlushInProgressCount : 0x8488
+0x030 WritableUserReferences : 0x81df20a0
+0x034 QuadwordPad : 0
All the crazy values printed by vadinfo are correct, just as they appear in the
windbg output. The specific member causing the vadinfo command to abort is
FilePointer = 0x0007ffda. See the line:
http://code.google.com/p/volatility/source/browse/trunk/volatility/plugins/vadin
fo.py#84
....format(FO.obj_offset, FO.FileName.Buffer, FO.FileName))
When accessing FO.FileName, it causes obj.BaseObject to raise
InvalidOffsetError. This call is made from VADInfo.write_vad_control() and
there is a try/except block around it, but only for catching AttributeError:
try:
self.write_vad_control(outfd, vad)
except AttributeError:
pass
So a possible fix, that allows vadinfo to continue printing the other vads
instead of aborting:
try:
self.write_vad_control(outfd, vad)
except (AttributeError, obj.InvalidOffsetError):
pass
I'd like to discuss if this placement of the fix is good, or if you want to
place it elsewhere or do something else entirely. As long as vadinfo doesn't
come to a complete halt when parsing these invalid fields.
By the way, you might notice that ControlArea.FilePointer (0x0007ffda) is
followed by ControlArea.WaitingForDeletion which is also 0x0007ffda. That
sounds ironically similar to the StartingVpn and EndingVpn values of the
MMVAD_LONG itself:
+0x00c StartingVpn : 0x7ffda
+0x010 EndingVpn : 0x7ffda
If the MMVAD_LONG is at 81df20b8 and the ControlArea pointer is 0x81df20a0,
that means the ControlArea points to -0x18 bytes behind the actual MMVAD_LONG.
What is the significance of 0x18? Its the offset of MMVAD_LONG.ControlArea:
+0x018 ControlArea
What the fuzz?
Original comment by michael.hale@gmail.com
on 14 Dec 2011 at 7:16
Attaching some supporting data for LabarumXP
Original comment by michael.hale@gmail.com
on 14 Dec 2011 at 7:32
Attachments:
At first I just thought this was something crazy and isolated to the current
state of my w2k3sp1 system. But after rebooting, there are still similar issues
(and not just with the winlogon process). Also going back to some XP and Win7
systems, the ControlArea is often not even in kernel mode. For example:
VAD node @821d69c8 Start 7ffde000 End 7ffdefff Tag Vadl
Flags: MemCommit, NoChange, PrivateMemory
Commit Charge: 1 Protection: 4
ControlArea @00010100 Segment 0057005c
Dereference list: Flink 004e0049, Blink 004f0044
NumberOfSectionReferences: 5439575 NumberOfPfnReferences: 7536732
NumberOfMappedViews: 7536761 NumberOfUserReferences: 3342445
WaitingForDeletion Event: 002e0064
Flags: BeingCreated, CollidedFlush, DebugSymbolsLoaded, DeleteOnClose,
FailAllIo, FilePointerNull, Image
FileObject: none
First prototype PTE: 82293bd8 Last contiguous PTE: 823cd638
Flags2: LongVad, OneSecured
File offset: 00000000
Is there a flag somewhere that says if the ControlArea is used/unused and the
OS just sets that flag rather than NULL-ing out the ControlArea pointer when
its not in use?
In some cases I've even seen ControlArea be 00000000. We should not be printing
the ControlArea fields if the pointer is NULL. For example:
VAD node @81a59770 Start 00160000 End 0025ffff Tag Vadl
Flags: PrivateMemory
Commit Charge: 63 Protection: 4
ControlArea @00000000 Segment 30000000
Dereference list: Flink f000ff53, Blink f000e2c3
NumberOfSectionReferences: 4026597203 NumberOfPfnReferences: 4026597203
NumberOfMappedViews: 4026597204 NumberOfUserReferences: 4026597203
WaitingForDeletion Event: f0000b01
Flags: BeingDeleted, BeingPurged, Commit, CopyOnWrite, File, FloppyMedia,
GlobalOnlyPerSession, Image, NoCache, PhysicalMemory, Reserve, Rom, WasPurged
FileObject: none
First prototype PTE: 00000000 Last contiguous PTE: 00000000
Flags2: LongVad, ReadOnly
File offset: 00000000
How does that pass the check in vadinfo anyway?
CA = vad.get_control_area()
if not CA:
#debug.b()
return
We end up having to do this:
if not CA or CA == 0:
But that still doesn't prevent us from printing the fields of a ControlArea if
the pointer is 1 instead of 0. Also note due to
http://code.google.com/p/volatility/issues/detail?id=144 most of the vad flags
are being printed incorrectly bc of overlay issues.
Original comment by michael.hale@gmail.com
on 14 Dec 2011 at 8:21
A friend chimed in that VADs with the PrivateMemory flag set never have a valid
ControlArea (even if ControlArea is not NULL). We can use this as an indicator
of when to print the ControlArea members or not. However, in order to test if
the PrivateMemory bit is set, we'll need to first address issues 143 and 144.
Original comment by michael.hale@gmail.com
on 14 Dec 2011 at 10:33
This issue was closed by revision r1161.
Original comment by michael.hale@gmail.com
on 15 Dec 2011 at 9:53
Original issue reported on code.google.com by
michael.hale@gmail.com
on 29 Oct 2011 at 12:15