Closed GoogleCodeExporter closed 8 years ago
Original comment by michael.hale@gmail.com
on 7 Oct 2011 at 2:01
Due to some porting activity, the above link above should now be:
https://github.com/carlpulley/volatility/tree/v1.3/memory_plugins/honeynet
Original comment by carl.pulley
on 9 Oct 2011 at 1:08
Thanks for the update Carl. I think someone got started on porting the heaps
plugin already. I'll ask him to post the current draft here for feedback.
Nice work on the plugins and honeynet challenge!
Original comment by michael.hale@gmail.com
on 9 Oct 2011 at 2:46
That'd be great.
I'm planning on doing a bit more porting work over the next week (mainly with
the exportfile plugin - I want to include some code for extracting memory
mapped files from _FILE_OBJECT's). If time is left, I'll use it to start work
on porting the stack plugin (I have a number of enhancements for it that I'll
consider once the basic code is ported).
Thanks for the interest and help.
Original comment by carl.pulley
on 9 Oct 2011 at 3:45
[deleted comment]
[deleted comment]
[deleted comment]
Bug fixed version, hopefully. Also in plugin format. Sorry about the hassle
earlier.
Original comment by marko.th...@gmail.com
on 14 Oct 2011 at 9:27
Attachments:
Inspiring to see how nicely my ugly heaps code has been cleaned up. Nice work
Marko.
The basic (but ugly!) stack code has also now been ported across to 2.0 (see
https://github.com/carlpulley/volatility/blob/master/exportstack.py) - sorry,
but this code is not as clean as Marko's. It is also worth noting that this
plugin has a number of overlaps with MHL's threads plugin (primary differences:
threads has a nice tagging and search mechanism; my stacks code will attempt to
unwind kernel and user mode stacks).
The file extraction plugin is almost fully functional now. I've just got to
finish the code for reconstructing files from extracted memory pages (that will
get completed this weekend). All memory pages belonging to shared cache and
memory mapped files are now extracted and saved (I still need to look at
private cache maps). There's also a --pool option to just dump any _FILE_OBJECT
that you can find!
Original comment by carl.pulley
on 14 Oct 2011 at 2:02
updated version of heap plugin
Original comment by marko.th...@gmail.com
on 13 Nov 2011 at 9:34
Fixed version of the heaps plugin.
Original comment by marko.th...@gmail.com
on 15 Nov 2011 at 6:45
Attachments:
Has there been any work on cleaning up the stack plugin? I have been
experimenting with it and it's old stack-frame lookup function could use some
love.
First, stack frames seems to be 4-byte aligned on 32-bit machines and 16-byte
aligned on 64-bit machines, which would speed up the old stack frame search.
(See http://msdn.microsoft.com/en-us/library/aa290049(v=vs.71).aspx).
Furthermore, the current old stack-frame search skips searching for an EBP
value once one old stack frame was found pointing to that EBP. There may other
old frames pointing to the same EBP value if the frame called multiple
functions that have all returned, and one of those functions had a parameter
list larger than the entire other function (not sure how this will look):
old_n old_n+1
--------
| ebp <- we could still find this
old esp unknown-> --------- | eip
| local | input <- from here on down it's overwritten by old_n
| ebp | input
| eip | input
| return | return
esp-> --------- --------
| current | current
By searching for both EBP's we can find more old stack frames. For example:
Thread @ 0x80f57228. PPID: 480. TID: 584. CrossThreadFlags: 0
Initial Stack: [KERNEL]
Stack: 0xfc2b2000-0xfc2b5000. Size: 0x3000
Teb @ 0x7ffdb000. User Stack: 0x65c000-0x660000. Size: 0x4000
Trapframe @ 0xfc2b4d64
EDX: 0x9ac80. ECX: 0xffffffff. EAX: 0xc0. EDI: 0x1. ESI: 0x0. EBX: 0x0
EBP: 0x65ffb4. EIP: 0x7c90eb94. ERR: 0x0. ESP: 0x65fcec
DR0: 0x0. DR1: 0x0. DR2: 0x0. DR3: 0x0. DR6: 0x0. DR7: 0x0.
[Current+1] EIP: 0x7c90eb94. EBP: 0x65fad4 -> 0x65ffb4.
[Current+2] EIP: 0x7c90d625. EBP: 0x65fa0c -> 0x65ffb4.
[Current+3] EIP: 0x7c90e57c. EBP: 0x65f9ec -> 0x65fa0c.
[Current] EIP: 0x7c90eb94. EBP: 0x65ffb4
[Current-1] EIP: 0x7c80b50b. EBP: 0x65ffec.
Note how [Current+1] and [Current+2] were both called by the [Current] frame.
Original comment by tamas.k....@gmail.com
on 20 Mar 2013 at 5:13
Hi Tamas,
I'll look into incorporating these ideas into the exportstack.py code over the next week (I'll report back as soon as I have something viable).
Thank you very much for your feedback,
Carl.
Original comment by carl.pulley
on 20 Mar 2013 at 10:45
While you at it, I saw a #FIXME for the kernel ESP values and noticed you were
not reading the kernel EIP and EBP values either. I've been just poking around
and came across this:
http://blog.airesoft.co.uk/2009/02/grabbing-kernel-thread-contexts-the-process-e
xplorer-way. It's not entirely clear in this article, but based on it I seem to
have been able to also gather the kernel stack's EBP and EIP values, which do
help in unwinding the kernel stack:
esp=ethread.Tcb.KernelStack.v()
eip=self.flat_address_space.read_long(self.process_address_space.vtop(esp+8))
ebp=self.flat_address_space.read_long(self.process_address_space.vtop(esp+12))
Thread @ 0x80f97020. PPID: 1540. TID: 1912. CrossThreadFlags: 0
Initial Stack: [KERNEL]
Stack: 0xfba49000-0xfba4c000. Size: 0x3000
ESP: 0xfba4bc4c EIP: 0x8054498b. EBP: 0xfba4bc98.
[Current] EIP: 0x8054498b. EBP: 0xfba4bc98 <- 0xfba4bd48.
[Current-1] EIP: 0x8054060c. EBP: 0xfba4bd48 <- 0xfba4bd64.
[Current-2] EIP: 0x7c90eb94. EBP: 0xfba4bd64 <- 0xd6ff80.
Original comment by tamas.k....@gmail.com
on 21 Mar 2013 at 12:21
Also, in the stack_frame_iterator_up() function, you have:
ebp = self.flat_address_space.read_long(self.process_address_space.vtop(ebp))
This is fine for most cases, but the user stack can't be trusted to contain
valid ebp's. The only checking you have right now is to check if the ebp is
within the stack boundries (or if it's zero). What if for example the initial
stack's EBP is overwritten to point back to the current frame? That would make
the loop run forever.. so we may want to include some form of safety check to
break when we hit already visited stack frames.
Original comment by tamas.k....@gmail.com
on 21 Mar 2013 at 2:09
Just released a rewrite of the exportstack plugin that incorporates Tamas'
suggestions. Plugin now:
-extends malware.threads
-unwinds the exception handling stack
-has a good result correlation with WinDBG based stack unwinds.
Original comment by carl.pulley
on 30 Mar 2013 at 7:54
Nice work Carl! The plugin works great.
Also, I was exploring the values found around the ESP a bit more as I can't
find any more information on it. This is what I came up with so far:
esp = thread.Tcb.KernelStack.v()
*esp = points to an address on the kernel stack
*esp+4: 0x246, constant? I see it on both XP and Win7.
*esp+8: kernel EIP (according to link I already sent)
*esp+12: kernel EBP
*esp+16: thread base pointer
*esp+20: 0xffdff120 on XP
*esp+32: on XP pointer to WaitListBlock (thread base pointer+70).
*esp+36: thread base pointer
Now, if we read values lower from the esp, on XP:
*esp-4: thread base pointer or 0xffdff538
*esp-8: 0xffdff120
*esp-12: thread base pointer
*esp-16: 0x1f
On Win7:
*esp-4: thread base pointer
When *esp-8 is not 1, than *esp-16 is also the thread base pointer.
I figured I post it here in case it's useful for anything.
Original comment by tamas.k....@gmail.com
on 31 Mar 2013 at 12:00
I think it might be worthwhile exploring the integration of the stack plugin
with pdbparse's symbol lookup tool
(https://code.google.com/p/pdbparse/source/browse/trunk/examples/pdb_lookup.py).
It would enable us to translate the EIP values into symbols on the fly. The
most practical approach would be to extract the GUID+pdb filename from the
module's PE header the EIP maps to and download the pdb automatically to use
with pdb_lookup.
For example I was able to get this:
Thread @ 0x853da908. PPID: 4. TID: 1828. CrossThreadFlags: 43010
Start address: 0x8b51cd18
Stack: 0x92009000-0x9200bed0. Size: 0x2ed0.
Kernelstack @ 0x9200bae0
ECX: 0x9200bc30. EBP: 0x9200bb30. EIP: 0x82686766. ESP: 0x9200bae0
ntoskrnl.exe!@KiSwapContext@8
[Current] EIP: 0x8268c4f7. EBP: 0x9200bb30 -> 0x9200bb58. Size: 0x50
ntoskrnl.exe!_KiCommitThreadWait@16
[Current-1] EIP: 0x8268d1ed. EBP: 0x9200bb58 -> 0x9200bbbc. Size: 0x28
ntoskrnl.exe!_KeRemoveQueueEx@24
[Current-2] EIP: 0x826a732e. EBP: 0x9200bbbc -> 0x9200bbdc. Size: 0x64
ntoskrnl.exe!_KeRemoveQueue@12
[Current-3] EIP: 0x8b50708e. EBP: 0x9200bbdc -> 0x9200bc40. Size: 0x20
rdbss.sys!_RxpWorkerThreadDispatcher@8
[Current-4] EIP: 0x8b51cd32. EBP: 0x9200bc40 -> 0x9200bc50. Size: 0x64
rdbss.sys!_RxWorkerThreadDispatcher@4
[Current-5] EIP: 0x82818f5e. EBP: 0x9200bc50 -> 0x9200bc90. Size: 0x10
ntoskrnl.exe!_PspSystemThreadStartup@8
[Current-6] EIP: 0x826c0219. EBP: 0x9200bc90 -> 0x0. Size: 0x40
ntoskrnl.exe!_KiThreadStartup@4
For non-kernel processes it seems to work just as well but some modules don't
seem to have a IMAGE_DIRECTORY_ENTRY_DEBUG loaded in memory (win32k.sys and
ntdll.dll), so I can't get the GUID and consequently the pdb:
Target pid: 200
Walking STACKS of smss.exe
Thread @ 0x84b46930. PPID: 200. TID: 204. CrossThreadFlags: 43074
Start address: 0x76ea7098
Stack: 0x88bd4000-0x88bd6ed0. Size: 0x2ed0.
Kernelstack @ 0x88bd6648
ECX: 0x88bd6ab8. EBP: 0x88bd6698. EIP: 0x82686766. ESP: 0x88bd6648
ntoskrnl.exe!@KiSwapContext@8
[Current] EIP: 0x8268c4f7. EBP: 0x88bd6698 -> 0x88bd66c0. Size: 0x50
ntoskrnl.exe!_KiCommitThreadWait@16
[Current-1] EIP: 0x826884a4. EBP: 0x88bd66c0 -> 0x88bd683c. Size: 0x28
ntoskrnl.exe!_KeWaitForMultipleObjects@32
[Current-2] EIP: 0x82839796. EBP: 0x88bd683c -> 0x88bd6ac8. Size: 0x17c
ntoskrnl.exe!_ObpWaitForMultipleObjects@20
[Current-3] EIP: 0x82839503. EBP: 0x88bd6ac8 -> 0x88bd6c18. Size: 0x28c
ntoskrnl.exe!_NtWaitForMultipleObjects@20
[Current-4] EIP: 0x8264d1ea. EBP: 0x88bd6c18 -> 0x88bd6c34. Size: 0x150
ntoskrnl.exe!_KiFastCallEntry
[Current-5] EIP: 0x76ea70b4. EBP: 0x88bd6c34 -> 0x14fef8. Size: 0x1c
ntdll.dll!(null)
Teb @ 0x7ffdf000. User Stack: 0x14d000-0x150000. Size: 0x3000
Trapframe @ 0x88bd6c34
EDX: 0x2529c8. ECX: 0x0. EAX: 0x0. EDI: 0x25e760. ESI: 0x0. EBX: 0x7fff00000000
EBP: 0x14fef8. EIP: 0x76ea70b4. ERR: 0x0. ESP: 0x14fe44
DR0: 0x0. DR1: 0x0. DR2: 0x0. DR3: 0x0. DR6: 0x0. DR7: 0x7fff00000000.
ntdll.dll!(null)
[Current] EIP: 0x4821e946. EBP: 0x14fef8 -> 0x14ff3c. Size: 0xb4
smss.exe!_NtProcessStartupW_AfterSecurityCookieInitialized@4
[Current-1] EIP: 0x76e65e7a. EBP: 0x14ff3c -> 0x14ff7c. Size: 0x44
ntdll.dll!(null)
[Current-2] EIP: 0x76ec37c8. EBP: 0x14ff7c -> 0x14ff94. Size: 0x40
ntdll.dll!(null)
[Current-3] EIP: 0x0. EBP: 0x14ff94 -> 0x0. Size: 0x18
Original comment by tamas.k....@gmail.com
on 12 Apr 2013 at 10:39
In cases where IMAGE_DIRECTORY_ENTRY_DEBUG is paged out, you can also try
retrieving a copy of the PE based on its GUID, which is usually still paged
in, and then using that to get the PDB. I have some example code that does
this here:
http://18.26.6.153/~brendan/resolvetaps.py
-Brendan
Original comment by moo...@gmail.com
on 12 Apr 2013 at 11:48
Hi Brendan, thanks, I'll check again! My understanding was (and correct me if
I'm wrong) that if IMAGE_DIRECTORY_ENTRY_DEBUG is paged out I won't be able to
get the GUID. When it's paged out the debug type is reported as Unknown type:
IMAGE_DEBUG_TYPE_UNKNOWN.
Original comment by tamas.k....@gmail.com
on 13 Apr 2013 at 1:40
The PDB's GUID may be paged out, but the PE's GUID, which is just the
PE's FileHeader.TimeDateStamp
combined with its OptionalHeader.SizeOfImage. Since both of those are
generally in the first page of the executable they're usually in memory, so
you can use them to get the full PE from Microsoft's symbol server. The
process goes:
1. Try to get the PDB using IMAGE_DIRECTORY_ENTRY_DEBUG. If that fails,
2. Get the PE's TimeDateStamp+SizeOfImage and use it to download the full
PE from MS.
3. Use the downloaded PE's IMAGE_DIRECTORY_ENTRY_DEBUG to download the PDB.
Hope that helps!
Original comment by moo...@gmail.com
on 13 Apr 2013 at 2:32
Hi Tamas and Brenden,
I have some code that does exactly this - I will be able to release it within a week or so. I've some additional work to do so that functional ordinals can be better resolved (some process address spaces don't have the full set of module function names loaded, but often other process address spaces do - I need to finish unifying this collective data).
I also have some code that allows alternative stack unwind strategies to be
applied (e.g. so that CALL/RETs, ROP gadgets, etc. can be detected). This is
done in a manner similar to malware.thread tags and so should be extensible.
I'll report back once I'm done.
All the best,
Carl.
Original comment by carl.pulley
on 13 Apr 2013 at 8:53
Brendan: cool thanks, that makes sense. I'll give it a shot!
Carl: great, I'm very interested in the alternative unwind strategies =) When
you say "some process address spaces don't have the full set of module function
names loaded", do you mean the module export tables? The problem with the
export tables are, well, the unexported functions for which we need the debug
info.
Original comment by tamas.k....@gmail.com
on 13 Apr 2013 at 1:12
Hi Tamas,
currently I perform addr to symbol resolution as follows:
-determine module that the address lies in
-if PDB symbol resolution is possible (and the user hasn't disallowed it), download (if necessary) and load PDB symbol info. and resolve addr to nearest debugging symbol name (c.f. the process Brendan has described)
-if PDB symbol resolution is not possible, use the module exports to resolve the addr.
It currently looks like the exports function name information can vary between
process address spaces (here I'm thinking about processes that both load a
common module). So, in the failover case above, I need to unify this
information and so improve the accuracy of the exports-based resolution process.
Hopefully that clarifies the issue?
Carl.
Original comment by carl.pulley
on 13 Apr 2013 at 1:53
Hi Carl, thanks, yes, that sounds like a good approach. Brendan's trick to get
the full PE if the PDB guid is not available was a really nice hint =)
Trapframe @ 0x94acfc34
EDX: 0x0. ECX: 0x0. EAX: 0x76e903e7. EDI: 0x251c18. ESI: 0x2. EBX: 0x7fff00251c18
EBP: 0x1bfa20. EIP: 0x76ea70b4. ERR: 0x0. ESP: 0x1bf8c0
DR0: 0x0. DR1: 0x0. DR2: 0x0. DR3: 0x0. DR6: 0x0. DR7: 0x7fff00000000.
ntdll.dll!_KiFastSystemCallRet@0
[Current] EIP: 0x76e65e7a. EBP: 0x1bfa20 -> 0x1bfa60. Size: 0x160
ntdll.dll!_wcsspn
[Current-1] EIP: 0x76ec37c8. EBP: 0x1bfa60 -> 0x1bfa78. Size: 0x40
ntdll.dll!__RtlUserThreadStart@8
[Current-2] EIP: 0x0. EBP: 0x1bfa78 -> 0x0. Size: 0x18
Original comment by tamas.k....@gmail.com
on 13 Apr 2013 at 11:11
[deleted comment]
Hi,
just released some updates to the exportstack code. Stack frame unwinding is more modular and alternative unwind strategies can now be added. I've got implementations for the following types of unwinds:
-EBP/ESP frame unwinds
-CALL/RET unwinds
-exception frame unwinds
-prototype GS based extension to EBP/ESP unwinds (still has some kinks to work out)
-prototype gadget detection (not yet tested)
I haven't (yet) got any of the newer 64 bit based unwinds implemented (I still
need to look over some GDB sources etc. here).
Experimental (yara based) stack frame search functionality is injected into the
_EPROCESS object class.
I'm still not happy with performance, so we'll see what can be done here with
time.
All the best,
Carl.
Original comment by carl.pulley
on 18 May 2013 at 9:38
Hi guys, just doing some issue tracker clean up here. For now, I think it seems
reasonable that the authors of the plugins (Carl and Tamas) maintain these
plugins in their own code repositories. If it becomes a hassle for people to
download plugins from multiple sources, then we can reconsider bringing them
into the core code base. If you prefer to integrate them sooner than later,
feel free to reopen the issue and attach the most recent version of your plugin
here and we'll help to get it tested/applied. Thanks guys!
Original comment by michael.hale@gmail.com
on 7 Mar 2014 at 5:12
Original issue reported on code.google.com by
michael.hale@gmail.com
on 7 Oct 2011 at 2:01