Skip to content

Proving Editbox Structures in Windows 8 and 10

Bridgey the Geek edited this page Feb 16, 2017 · 3 revisions

Introduction

Editbox works well with Windows XP and Windows 7. There's some weirdness with Vista that seems to be more fundamental to Volatility than being Editbox, and it can't really be tested with 8 or 10.

The reason it can't be tested is because Editbox relies on Volatility being able to iterate the window objects so that Editbox can pick up on the !Edit in the atom class name. But in my testing, I haven't seen any such atom class names in 8 or 10. In fact, in 10, the windows plugin can't (yet) show process image file names or PIDs either. Ignoring that problem for now, how can I test whether the structures I have defined for Windows 7 are the same for Windows 8 or Windows 10? If I could find the window in memory then I could marshal it into the structure and see what happens. But there's a catch-22 here: we don't know where the Edit control is. How can we find it?

Taint the Memory

Tainting is the process of marking something so you can find it later. Simply, I can introduce something into the control that I can find in memory later and hopefully work backwards to the window object. You'd be forgiven for thinking that the answer is "type some text in the Edit control". This probably would work, but the text is actually pointed to by a double-referenced pointer so that's an extra step than the undo buffer. A pointer to the undo buffer is stored directly in the Edit's structure. So, the sensible thing is to put something we can find into the undo buffer.

I decided to start with Windows 10 because if the structure in Windows 10 is the same as Windows 7 it's a pretty safe bet that it's the same in Windows 8.

So, I fired up my VMware Windows 10 VM and opened up Notepad and typed some text in. I typed the term "cut2" and cut it from the control - this puts it in the control's undo buffer.

Process Overview

So, this is the plan:

  1. Dump the process memory with memdump.
  2. Locate the text in the undo buffer.
  3. Calculate the start of the window object based on the position of the undo buffer in the structure.

Let's Go!

1. Dump the process memory with memdump.

python vol.py -f "Win10x64-574f8f9a.vmem" --profile Win10x64 memdump --pid 3584 -D .
Volatility Foundation Volatility Framework 2.5
************************************************************************
Writing notepad.exe [  3584] to 3584.dmp

2. Locate the text in the undo buffer.

The text I cut from notepad is: cut2, which in Unicode will be c\x00u\x00t\x002\x00.

python vol.py --plugins ..\editbox -f "Win10x64-574f8f9a.vmem" --profile Win10x64 volshell --pid 3584
Volatility Foundation Volatility Framework 2.5
Current context: notepad.exe @ 0xffffe0004c0d9080, pid=3584, ppid=2776 DTB=0x262e8000
Welcome to volshell! Current memory image is:
file:///C:/Virtual%20Machines/Win10x64/Win10x64-574f8f9a.vmem
To get help, type 'hh()'
>>> find('c\x00u\x00t\x002\x00', max=0, length=32)
0xd604c4da72  63 00 75 00 74 00 32 00 20 00 63 00 75 00 00 00   c.u.t.2...c.u...
0xd604c4da82  00 00 00 00 00 00 00 00 00 00 00 00 00 00 e0 e6   ................
----------------
0xd604c50d60  63 00 75 00 74 00 32 00 00 00 00 00 00 00 00 00   c.u.t.2.........
0xd604c50d70  00 00 00 00 00 00 00 00 a1 a1 96 8d 00 0e 00 88   ................
----------------
0xd604c51042  63 00 75 00 74 00 32 00 20 00 00 00 00 00 00 00   c.u.t.2.........
0xd604c51052  00 00 00 00 00 00 73 a0 f8 8d 00 25 00 80 50 84   ......s....%..P.
----------------
0xd604c511e2  63 00 75 00 74 00 32 00 00 00 00 00 00 00 00 00   c.u.t.2.........
0xd604c511f2  00 00 00 00 00 00 69 a0 de 8d 00 32 00 80 60 6f   ......i....2..`o
----------------

So, four possible locations of the undo buffer:

  1. 0xd604c4da72
  2. 0xd604c50d60
  3. 0xd604c51042
  4. 0xd604c511e2

Assuming the structure is valid, in memory we'll see the pointer to the buffer (in little-endian), followed by an int32 of the position (5, in little-endian), followed by an int32 of the length (4, in little-endian). So, we can try and find it:

>>> find('\x72\xda\xc4\x04\xd6\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00', length=16)
>>> find('\x60\x0d\xc5\x04\xd6\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00', length=16)
0xd604c0c1d8  60 0d c5 04 d6 00 00 00 05 00 00 00 04 00 00 00   `...............
>>> find('\x42\x10\xc4\x04\xd6\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00', length=16)
>>> find('\xe2\x11\xc4\x04\xd6\x00\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00', length=16)
>>>

Ok, great! We have a likely candidate at 0xd604c0c1d8.

3. Calculate the start of the window object based on the position of the undo buffer in the structure.

If the structure is correct, this offset will be 0xA8 into the structure.

So, let's import the new plugin and add the new vtypes and classes...

>>> import volatility.plugins.editbox as editbox
>>> addrspace().profile.vtypes.update(editbox.editbox_vtypes_vista7810_x64)
>>> addrspace().profile.object_classes.update(editbox.Editbox2.editbox_classes)
>>> addrspace().profile.compile()

Now we can construct an object starting at our offset, (well, the offset - 0xA8)...

>>> edit = obj.Object('COMCTL_EDIT', offset=0xd604c0c1d8 - 0xA8, vm=proc().get_process_address_space())

The big reveal!

>>> dt(edit)
[COMCTL_EDIT COMCTL_EDIT] @ 0xD604C0C130
0x0   : hBuf                           919260233736
0x10  : nChars                         10
0x18  : selStart                       5
0x20  : selEnd                         5
0x34  : pwdChar                        0
0x40  : hWnd                           66092
0x60  : parenthWnd                     66072
0xa8  : undoBuf                        919203024224
0xb0  : undoPos                        5
0xb4  : undoLen                        4
0x140 : bEncKey                        0

Phew! And to use the class's own functions: Meta data first...

>>> edit.dump_meta(sys.stdout)
nChars            : 10
selStart          : 5
selEnd            : 5
isPwdControl      : False
undoPos           : 5
undoLen           : 4
address-of undoBuf: 0xd604c50d60
undoBuf           : cut2

Then contents...

>>> edit.dump_data(sys.stdout)
cut1  cut3

So, it looks pretty good. It looks like the important bits of the structure are the same for Windows 10 64-bit as they are for Windows 7 64-bit. We should really check that Windows 8 is the same and that the 32-bit versions are the same, but that's for another day.

You can’t perform that action at this time.