volatility3
volatility3 copied to clipboard
Feature: new renderer support `Mermaid` 🧜♀️ (for tree relationship).
Description
Hello, everyone in the community! 🙂
Through dot
-based rendering in Volatility
, we were able to conduct an effective analysis by visualizing the relationship between processes and the composition of VAD
in the form of trees.
Volatility 3
now helps us visualize tree-like information through Depth, but there are limitations.
I thought a lot about whether to migrate dot
first.
Dot is still a good visualization tool and helps many developers and analysts.
However, I would like to propose a new instrument called mermaid
.
Mermaid
, (Repository) is a good tool for dynamically rendering charts or graphs based on markdowns.
When we sometimes had to share dots with the outside world using dot
s, we needed to share files, take screenshots, or have a separate viewer.
However, mermaid
has the advantage of being able to share and write graphs neatly in SVG
form easily in markdown or web. (Github also officially supports this and is included as an example in this PR.)
Of course, if you want to use Mermaid more precisely, you need to change the rendering structure. (Unlike before, we don't seem to have the means to configure rendering on each plugin.) But I think it can get better gradually.
I submitted a PR for the basic Mermaid
rendering code. This is sufficient to indicate tree relationships such as PID
and PPID
, and feedback from other analysts was also available.
- [x] Create Mermaid renderer skeleton code
- [x] Constructing Trees (Node, Edge Data)
- [ ] Refactoring for relation decision
- [ ] Test for plugins
- [ ] Code Review
Command
> python3 vol.py -f 32.vmem -r mermaid windows.pstree
Result
Terminal Text
> python3 vol.py -f case.vmem -r mermaid windows.pstree
Volatility 3 Framework 2.2.0
Formatting...0.00 PDB scanning finished
graph TD
0 --> 4[PID:4<br>PPID:0<br>ImageFileName:System<br>OffsetV:0x86359280<br>Threads:106<br>Handles:-<br>SessionId:N/A<br>Wow64:False<br>CreateTime:2022-04-26 04:57:11.000000 <br>ExitTime:N/A<br>]
4 --> 304[PID:304<br>PPID:4<br>ImageFileName:smss.exe<br>OffsetV:0x8c82f040<br>Threads:4<br>Handles:-<br>SessionId:N/A<br>Wow64:False<br>CreateTime:2022-04-26 04:57:11.000000 <br>ExitTime:N/A<br>]
4 --> 92[PID:92<br>PPID:4<br>ImageFileName:Registry<br>OffsetV:0x87e28640<br>Threads:4<br>Handles:-<br>SessionId:N/A<br>Wow64:False<br>CreateTime:2022-04-26 04:57:06.000000 <br>ExitTime:N/A<br>]
Embedded
graph TD
0 --> 4[PID:4<br>PPID:0<br>ImageFileName:System<br>OffsetV:0x86359280<br>Threads:106<br>Handles:-<br>SessionId:N/A<br>Wow64:False<br>CreateTime:2022-04-26 04:57:11.000000 <br>ExitTime:N/A<br>]
4 --> 304[PID:304<br>PPID:4<br>ImageFileName:smss.exe<br>OffsetV:0x8c82f040<br>Threads:4<br>Handles:-<br>SessionId:N/A<br>Wow64:False<br>CreateTime:2022-04-26 04:57:11.000000 <br>ExitTime:N/A<br>]
4 --> 92[PID:92<br>PPID:4<br>ImageFileName:Registry<br>OffsetV:0x87e28640<br>Threads:4<br>Handles:-<br>SessionId:N/A<br>Wow64:False<br>CreateTime:2022-04-26 04:57:06.000000 <br>ExitTime:N/A<br>]
4 --> 1564[PID:1564<br>PPID:4<br>ImageFileName:MemCompression<br>OffsetV:0x863b35c0<br>Threads:18<br>Handles:-<br>SessionId:N/A<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
384 --> 404[PID:404<br>PPID:384<br>ImageFileName:csrss.exe<br>OffsetV:0x9244c0c0<br>Threads:14<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
384 --> 480[PID:480<br>PPID:384<br>ImageFileName:wininit.exe<br>OffsetV:0x92530040<br>Threads:8<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
480 --> 616[PID:616<br>PPID:480<br>ImageFileName:services.exe<br>OffsetV:0x8cd14040<br>Threads:12<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 768[PID:768<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x92596680<br>Threads:25<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
768 --> 2976[PID:2976<br>PPID:768<br>ImageFileName:SearchApp.exe<br>OffsetV:0x9d18d600<br>Threads:29<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:18.000000 <br>ExitTime:N/A<br>]
768 --> 4544[PID:4544<br>PPID:768<br>ImageFileName:dllhost.exe<br>OffsetV:0x863d5040<br>Threads:8<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:20.000000 <br>ExitTime:N/A<br>]
768 --> 4072[PID:4072<br>PPID:768<br>ImageFileName:StartMenuExper<br>OffsetV:0x977b6040<br>Threads:35<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:18.000000 <br>ExitTime:N/A<br>]
768 --> 4200[PID:4200<br>PPID:768<br>ImageFileName:backgroundTask<br>OffsetV:0xa1c9e640<br>Threads:7<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:19.000000 <br>ExitTime:N/A<br>]
768 --> 4780[PID:4780<br>PPID:768<br>ImageFileName:mobsync.exe<br>OffsetV:0xa833a800<br>Threads:8<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:22.000000 <br>ExitTime:N/A<br>]
768 --> 5148[PID:5148<br>PPID:768<br>ImageFileName:RuntimeBroker.<br>OffsetV:0x965657c0<br>Threads:10<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:24.000000 <br>ExitTime:N/A<br>]
768 --> 3792[PID:3792<br>PPID:768<br>ImageFileName:SppExtComObj.E<br>OffsetV:0xa04db040<br>Threads:8<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:17.000000 <br>ExitTime:N/A<br>]
768 --> 4464[PID:4464<br>PPID:768<br>ImageFileName:dllhost.exe<br>OffsetV:0xa1ce0800<br>Threads:8<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:19.000000 <br>ExitTime:N/A<br>]
768 --> 1044[PID:1044<br>PPID:768<br>ImageFileName:WmiPrvSE.exe<br>OffsetV:0x9d01f600<br>Threads:11<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:18.000000 <br>ExitTime:N/A<br>]
768 --> 2132[PID:2132<br>PPID:768<br>ImageFileName:RuntimeBroker.<br>OffsetV:0x9d082680<br>Threads:21<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:18.000000 <br>ExitTime:N/A<br>]
768 --> 2460[PID:2460<br>PPID:768<br>ImageFileName:RuntimeBroker.<br>OffsetV:0x9d1df040<br>Threads:16<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:18.000000 <br>ExitTime:N/A<br>]
616 --> 2444[PID:2444<br>PPID:616<br>ImageFileName:sppsvc.exe<br>OffsetV:0x9bdae7c0<br>Threads:9<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
616 --> 2060[PID:2060<br>PPID:616<br>ImageFileName:SearchIndexer.<br>OffsetV:0x9d18a040<br>Threads:22<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:18.000000 <br>ExitTime:N/A<br>]
2060 --> 4984[PID:4984<br>PPID:2060<br>ImageFileName:SearchFilterHo<br>OffsetV:0xa834c840<br>Threads:6<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:23.000000 <br>ExitTime:N/A<br>]
2060 --> 4916[PID:4916<br>PPID:2060<br>ImageFileName:SearchProtocol<br>OffsetV:0xa1d5f040<br>Threads:9<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:23.000000 <br>ExitTime:N/A<br>]
616 --> 1940[PID:1940<br>PPID:616<br>ImageFileName:spoolsv.exe<br>OffsetV:0x863fb880<br>Threads:13<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
616 --> 3220[PID:3220<br>PPID:616<br>ImageFileName:NisSrv.exe<br>OffsetV:0xa043e840<br>Threads:9<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:15.000000 <br>ExitTime:N/A<br>]
616 --> 1436[PID:1436<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x977a87c0<br>Threads:17<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
616 --> 1820[PID:1820<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x863d5840<br>Threads:21<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 1444[PID:1444<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x89ba1580<br>Threads:25<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 2088[PID:2088<br>PPID:616<br>ImageFileName:MsMpEng.exe<br>OffsetV:0x8c24c040<br>Threads:29<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
616 --> 1072[PID:1072<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x965d1680<br>Threads:65<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
1072 --> 336[PID:336<br>PPID:1072<br>ImageFileName:sihost.exe<br>OffsetV:0x97777880<br>Threads:21<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
1072 --> 1580[PID:1580<br>PPID:1072<br>ImageFileName:taskhostw.exe<br>OffsetV:0x977b67c0<br>Threads:12<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
616 --> 1200[PID:1200<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x9761d880<br>Threads:21<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
1200 --> 2360[PID:2360<br>PPID:1200<br>ImageFileName:ctfmon.exe<br>OffsetV:0x9bdae040<br>Threads:12<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
616 --> 1968[PID:1968<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x863de880<br>Threads:19<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
616 --> 3120[PID:3120<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x9bd05480<br>Threads:10<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:15.000000 <br>ExitTime:N/A<br>]
616 --> 1472[PID:1472<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x8636f840<br>Threads:6<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 1092[PID:1092<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x965d3440<br>Threads:21<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 3656[PID:3656<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x9777b040<br>Threads:9<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:16.000000 <br>ExitTime:N/A<br>]
616 --> 1108[PID:1108<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x965db040<br>Threads:22<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 2780[PID:2780<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x9daf9640<br>Threads:39<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:14.000000 <br>ExitTime:N/A<br>]
2780 --> 4708[PID:4708<br>PPID:2780<br>ImageFileName:rundll32.exe<br>OffsetV:0xa1d5c040<br>Threads:5<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:22.000000 <br>ExitTime:N/A<br>]
616 --> 352[PID:352<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x97777080<br>Threads:17<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:13.000000 <br>ExitTime:N/A<br>]
616 --> 3040[PID:3040<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x89bee040<br>Threads:13<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:15.000000 <br>ExitTime:N/A<br>]
616 --> 868[PID:868<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x9652a680<br>Threads:18<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 1764[PID:1764<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x863cd040<br>Threads:14<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 1644[PID:1644<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x863c1040<br>Threads:14<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 1264[PID:1264<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x976336c0<br>Threads:31<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
616 --> 1784[PID:1784<br>PPID:616<br>ImageFileName:svchost.exe<br>OffsetV:0x863d0840<br>Threads:7<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
480 --> 752[PID:752<br>PPID:480<br>ImageFileName:fontdrvhost.ex<br>OffsetV:0x925997c0<br>Threads:8<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
480 --> 652[PID:652<br>PPID:480<br>ImageFileName:lsass.exe<br>OffsetV:0x92474040<br>Threads:14<br>Handles:-<br>SessionId:0<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
472 --> 496[PID:496<br>PPID:472<br>ImageFileName:csrss.exe<br>OffsetV:0x92533080<br>Threads:15<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
472 --> 576[PID:576<br>PPID:472<br>ImageFileName:winlogon.exe<br>OffsetV:0x9256c680<br>Threads:8<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
576 --> 760[PID:760<br>PPID:576<br>ImageFileName:fontdrvhost.ex<br>OffsetV:0x92599040<br>Threads:8<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
576 --> 956[PID:956<br>PPID:576<br>ImageFileName:dwm.exe<br>OffsetV:0x96565040<br>Threads:22<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:12.000000 <br>ExitTime:N/A<br>]
576 --> 2860[PID:2860<br>PPID:576<br>ImageFileName:userinit.exe<br>OffsetV:0x9db7b840<br>Threads:6<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:14.000000 <br>ExitTime:N/A<br>]
2860 --> 2892[PID:2892<br>PPID:2860<br>ImageFileName:explorer.exe<br>OffsetV:0x9db92080<br>Threads:71<br>Handles:-<br>SessionId:1<br>Wow64:False<br>CreateTime:2022-04-26 04:57:15.000000 <br>ExitTime:N/A<br>]
Detail Screenshot

If you are interested in or have any comments on this PR, please feel free to leave a thread! 🙌
This looks like it'll be really awesome, but I'm afraid the renderer is hard coded with column names to produce the relationships (PID
and PPID
). Given that the parental relationship is already known by the TreeGrid (which rows are children), it should be fairly easy to remove the plugin specific parts of it?
I'd suggest giving each node a random identifier and then the first node that's one level higher before it, is it's parent (so each time there's a step down, pop the node on the end of a parent list, and use the end of the list as the parent, and each step up pop it off the list). That will make the renderer much more generic and work with any tree-based plugin, rather than just those that output PID
and PPID
. I'll be happy to re-review once it's been updated, but at the moment that immediately blocks it from inclusion in its current form.|
Another option would be to make this a very handy additional tool to run over existing output methods (such as JSON, JSONL or similar) if you'd prefer?
This looks like it'll be really awesome, but I'm afraid the renderer is hard coded with column names to produce the relationships (
PID
andPPID
). Given that the parental relationship is already known by the TreeGrid (which rows are children), it should be fairly easy to remove the plugin specific parts of it?I'd suggest giving each node a random identifier and then the first node that's one level higher before it, is it's parent (so each time there's a step down, pop the node on the end of a parent list, and use the end of the list as the parent, and each step up pop it off the list). That will make the renderer much more generic and work with any tree-based plugin, rather than just those that output
PID
andPPID
. I'll be happy to re-review once it's been updated, but at the moment that immediately blocks it from inclusion in its current form.|Another option would be to make this a very handy additional tool to run over existing output methods (such as JSON, JSONL or similar) if you'd prefer?
@ikelos That's right, I think you gave me a good guide about the part I was worried about.
If so, we will change this PR to Draft PR because we still need more work and we are not ready for the review. If the prepared code is completed according to the feedback soon and it is enough to receive a review, I will request it again.
I hope it will be a good feature that many people will use. Please give me a lot of advice! 🙂
Another option would be to make this a very handy additional tool to run over existing output methods (such as JSON, JSONL or similar) if you'd prefer?
@ikelos Could you give me a little more detail about the this comment, I'll try it the way you first suggested it, but if it's a good suggestion to improve further, I'll be happy to accept it.
@ikelos Could you give me a little more detail about the this comment, I'll try it the way you first suggested it, but if it's a good suggestion to improve further, I'll be happy to accept it.
Sure, I just meant you could write it as a separate tool which takes in the existing output from volatility3 and then produces the mermaid output from that, so something like:
volatility3 -f inputfile.dmp -r json plugin.name | your-new-program -o mermaid.out
If you really wanted you could write a separate program (or a volshell snippet) which could do the same thing. I think that make it a renderer makes more sense, but if it was tricky to make it generic then this would be another option. 5:)
@ikelos Could you give me a little more detail about the this comment, I'll try it the way you first suggested it, but if it's a good suggestion to improve further, I'll be happy to accept it.
Sure, I just meant you could write it as a separate tool which takes in the existing output from volatility3 and then produces the mermaid output from that, so something like:
volatility3 -f inputfile.dmp -r json plugin.name | your-new-program -o mermaid.out
If you really wanted you could write a separate program (or a volshell snippet) which could do the same thing. I think that make it a renderer makes more sense, but if it was tricky to make it generic then this would be another option. 5:)
@ikelos Ah I understand, but I also think the best way is to implement it as a renderer. Thank you for the detailed explanation. 🙂