Thanks very much for digging into this MHL :)
Glad I'm not going crazy!


On 9 May 2016 at 18:40, Michael Ligh <michael.ligh@mnin.org> wrote:
Hey Adam,

Good news...you're not crazy! That was a tricky one. Basically, the
tagDESKTOP.windows() API is at fault. It sometimes yields pointers to
tagWND and other times it yields tagWND. This in part depends on how you
call the API.

For example, here:

https://github.com/volatilityfoundation/volatility/blob/master/volatility/plugins/gui/windows.py#L53

"for wnd, _level in desktop.windows(desktop.DeskInfo.spwnd):"

At that point, spwnd is a pointer to tagWND. Also here:

https://github.com/volatilityfoundation/volatility/blob/master/volatility/plugins/gui/win32k_core.py#L480

"for xwin, xlevel in self.windows(cur.spwndChild"

At that point, spwndChild is a pointer to tagWND as well. However,
earlier inside the API, you see this:

https://github.com/volatilityfoundation/volatility/blob/master/volatility/plugins/gui/win32k_core.py#L471

"cur = cur.spwndNext.dereference()"

At that point, cur is not a pointer to tagWND, its actually just a
tagWND. I haven't fixed this in the code yet, but that is the issue.
When the windows plugin prints wnd.obj_offset, sometimes that's the
address of tagWND and sometimes its the address of the pointer that
points to tagWND.

Try a quick patch to see if it resolves the issue for you:

$ git diff
diff --git a/volatility/plugins/gui/windows.py
b/volatility/plugins/gui/windows.py
index 8d4f469..b475570 100644
--- a/volatility/plugins/gui/windows.py
+++ b/volatility/plugins/gui/windows.py
@@ -51,6 +51,10 @@ class Windows(messagehooks.MessageHooks):
                 outfd.write("Window context: {0}\\{1}\\{2}\n\n".format(
                     winsta.dwSessionId, winsta.Name, desktop.Name))
                 for wnd, _level in desktop.windows(desktop.DeskInfo.spwnd):
+
+                    if wnd._vol_name == "spwnd":
+                        wnd = wnd.dereference()
+
                     outfd.write("Window Handle: #{0:x} at {1:#x}, Name:
{2}\n".format(
                         wnd.head.h, wnd.obj_offset, str(wnd.strName or '')
                     ))


Thanks,
MHL

On 5/7/16 10:27 AM, Bridgey theGeek wrote:
> Hi Michael,
>
> Full transcript below (including a couple of dec to hex translations of
> seemingly pertinent values).
> As you can see, I'm in the context of explorer.exe (pid 2528) - the
> process owning the window objects.
>
> $ python vol.py --profile VistaSP1x86 -f VistaSP1x86*.vmem volshell
> Volatility Foundation Volatility Framework 2.5
> Current context: System @ 0x831528a0, pid=4, ppid=0 DTB=0x122000
> Welcome to volshell! Current memory image is:
> file:///slw/VMware%20VMs/VistaSP1x86/VistaSP1x86-09beecd1.vmem
> To get help, type 'hh()'
>>>> cc(pid=2528)
> Current context: explorer.exe @ 0x8384e1a0, pid=2528, ppid=2404
> DTB=0x3db8b3e0
>>>> o1 = obj.Object('tagWND', offset=0xfe817078,
> vm=proc().get_process_address_space())
>>>> o1
> [tagWND tagWND] @ 0xFE817078
>>>> o1.head
> [CType head] @ 0xFE817078
>>>> o1.head.h
> <Void pointer to [0xFE8172A0]>
>>>> dt(o1.head)
> [CType head] @ 0xFE817078
> 0x0   : h                              4269896352
> 0x4   : cLockObj                       0
> 0x8   : pti                            79
> 0xc   : rpdesk                         453
> 0x10  : pSelf                          399
>>>> hex(4269896352)
> '0xfe8172a0'
>>>> o2 = obj.Object('tagWND', offset=0xfe807390,
> vm=proc().get_process_address_space())
>>>> o2
> [tagWND tagWND] @ 0xFE807390
>>>> o2.head
> [CType head] @ 0xFE807390
>>>> o2.head.h
> <Void pointer to [0x000100BC]>
>>>> dt(o2.head)
> [CType head] @ 0xFE807390
> 0x0   : h                              65724
> 0x4   : cLockObj                       2
> 0x8   : pti                            4265924192
> 0xc   : rpdesk                         2345598544
> 0x10  : pSelf                          4269831056
>>>> hex(4269831056)
> '0xfe807390'
>
> Appreciate your help!
>
> Adam
>
>
> On 7 May 2016 at 16:49, Michael Ligh <michael.ligh@mnin.org
> <mailto:michael.ligh@mnin.org>> wrote:
>
>     Hey Adam,
>
>     For each of the objects (o1 and o2) can you paste the output from the
>     following commands (ignore the addresses in my examples):
>
>     >>> o1
>     [tagWND tagWND] @ 0xBCA30658
>     >>> o1.head
>     [CType head] @ 0xBCA30658
>     >>> o1.head.h
>     <Void pointer to [0xBCA306E8]>
>     >>> dt(o1.head)
>     [CType head] @ 0xBCA30658
>     0x0   : h                              3164800744
>     0x4   : cLockObj                       0
>     0x8   : pti                            0
>     0xc   : rpdesk                         0
>     0x10  : pSelf                          0
>     >>> dd(o1.head.h, length = 4)
>     bca306e8  0002002e
>
>     Also, what context are you in when running the commands? By that I mean,
>     what is the value of proc() when you're doing
>     proc().get_process_address_space()?
>
>     MHL
>
>     On 5/7/16 9:02 AM, Bridgey theGeek wrote:
>     > Hi all,
>     >
>     > Doing some work with the windows plugin for VistaSP1x86.
>     > I have the following two fragments from the output:
>     >
>     > Window Handle: #20130 at 0xfe817078, Name:
>     > ClassAtom: 0xc052, Class: ConsoleProgmanHandle
>     > SuperClassAtom: 0xc018, SuperClass: Edit
>     > pti: 0xfde11e90, Tid: 3432 at 0x839714e0
>     > ppi: 0xff54be50, Process: explorer.exe, Pid: 2528
>     > Visible: Yes
>     > Left: 82, Top: 456, Bottom: 379, Right: 473
>     > Style Flags: WS_CHILD,WS_OVERLAPPED,WS_VISIBLE
>     > ExStyle Flags: WS_EX_LTRREADING,WS_EX_RIGHTSCROLLBAR,WS_EX_LEFT
>     > Window procedure: 0x7520d0d4
>     >
>     > Window Handle: #100bc at 0xfe807390, Name:
>     > ClassAtom: 0xc052, Class: ConsoleProgmanHandle
>     > SuperClassAtom: 0xc018, SuperClass: Edit
>     > pti: 0xfe44d660, Tid: 2552 at 0x837c8778
>     > ppi: 0xff54be50, Process: explorer.exe, Pid: 2528
>     > Visible: No
>     > Left: 11, Top: 542, Bottom: 229, Right: 559
>     > Style Flags: WS_CHILD,WS_OVERLAPPED
>     > ExStyle Flags:
>     > WS_EX_CLIENTEDGE,WS_EX_LTRREADING,WS_EX_RIGHTSCROLLBAR,WS_EX_LEFT
>     > Window procedure: 0x751f01c6
>     >
>     > Both are from the same instance of explorer.exe.
>     >
>     > Viewing windows.py, it shows that the "Window Handle" is simply the
>     > value of: wnd.head.h
>     >
>     > Now consider this from volshell:
>     >>>> o1 = obj.Object('tagWND', offset=0xfe817078,
>     > vm=proc().get_process_address_space())
>     >>>> dd(o1.head.h, length=4)
>     > fe8172a0  00020130
>     >
>     > This seems logical: head.h is a void pointer. If we follow the pointer
>     > we get the handle: 20130.
>     >
>     > If I do the same with the other one:
>     >>>> o2 = obj.Object('tagWND', offset=0xfe807390,
>     > vm=proc().get_process_address_space())
>     >>>> dd(o2.head.h, length=4)
>     > 000100bc  00000000
>     >
>     > In this example, the handle is the VALUE of head.h, that is, you
>     > shouldn't follow the pointer.
>     >
>     > Volatility seems to know this because it displays the handles as 100bc
>     > rather than 0.
>     >
>     > I searched the Volatility code to see if I could find how this is
>     being
>     > done, but I couldn't.
>     > So, how?? What rule don't I know??
>     >
>     > Thanks!
>     >
>     >
>     > _______________________________________________
>     > Vol-users mailing list
>     > Vol-users@volatilityfoundation.org <mailto:Vol-users@volatilityfoundation.org>
>     > http://lists.volatilityfoundation.org/mailman/listinfo/vol-users
>     >
>
>