I decided to write these tutorials to help others with the creation of plugins for ProcDOT. My hope is that these tutorials will help with some of the frustration and issues I have had when creating plugins. For these tutorials, we need to have our system setup properly.
Most, if not all, of my plugins are written in python. Why python? I wanted to have a language that could be used on both Windows and Linux so I did not have to write separate plugins for each. This also helps with maintaining plugins because if you can get it to work on one system, it should work on the other, for the most part.
Another thing to note. I also try to stick with LinuxShellScript and WindowsBatchScript for the architecture. This is so I don't need to create different pdp files for 32 and 64 bit systems.
I'm not going to go into how to setup ProcDOT. If I have to explain that then you probably shouldn't be reading this yet.
For these tutorials, I will be using Windows, ProcDOT 1.2 [Build 55u], and python2.7. You can download python2.7 here. When installing python, make sure the executable is in the system path. You need to be able to call python from the command line for these tutorials to work.
In this post, we will create our first plugin. As we go through other tutorials, this plugin will come in handy for troubleshooting and plugin development.
ProcDOT's plugins consist of two parts:
- The plugin descriptor file
- The plugin itself
The following table lists the keynames and their uses for the descriptor file:
Keyname | Description | Possible values | Supported plugin types |
Name | Specifies the name of the plugin. | [Ascii] | all |
Author | Specifies the name of the author. | [Ascii] | all |
Description | Specifies a description for the plugin. | [Ascii] | all |
Version | Specifies the version of the plugin. | [Ascii] | all |
Type | Specifies the type of the plugin. Currently 3 types are supported: - ContextMenuItemForGraph ... The plugin is available through the context menu that popps up when the right mouse button is pressed while hovering the canvas area of the graph. - EventHandler ... The plugin is automatically registered (and therefore called) as an eventhandler for the given event constant(s) via "Event = " or "Events = ". - MainMenuItem ... The plugin is available through the main menu item "Plugins". Currently there can exist 9 main menu item plugins in maximum. |
ContextMenuItemForGraph EventHandler MainMenuItem |
all |
Architecture | Specifies the architecture the plugin was developed for. | Linux32BitExe Linux32BitSo Linux64BitExe Linux64BitSo LinuxShellScript Windows32BitDll Windows32BitExe Windows64BitDll Windows64BitExe WindowsBatchScript |
all |
File | Specifies the file to be used as the actual plugin. | [Filename] | all |
Priority | Specifies the position of the actual plugin in case of multiple matching plugins from 1 to 9 with 1 being the highest priority and 9 being the lowest. | 1 - 9 | all |
RunHidden | Tells ProcDOT to run the actual plugin hidden hennce preventing any windows from popping up. (1 = True, 0 = False) | 1 / 0 | all |
RunExclusively | Tells ProcDOT to not run any other non-exclusive plugin in parallel to this one. (1 = True, 0 = False) | 1 / 0 | all |
CanOverrideOtherPlugins | Specifies that if the actual plugin exits with a return code of 1 any other plugin being in the queue waiting to run will be skipped. (1 = True, 0 = False) | 1 / 0 | all |
CanOverrideProcDot | Specifies that if the actual plugin exits with a return code of 1 any following builtin functionality of ProcDOT will be skipped. (1 = True, 0 = False) | 1 / 0 | all |
CanBeVerified | Specifies that this plugin can also be called in verification mode
(Environmentvariable PROCDOTPLUGIN_VerificationRun) to decide if it's
able to handle the hovered node or situation. (1 = True, 0 = False) The actual plugin needs to exit with a return code of 1 to signal that it's able to properly handle an according "real" call. |
1 / 0 | all |
Event or Events |
Specifies the event (or events seperated with colons) for which the actual plugin shall be registered for as an event handler. | BeforeLeftClickOnGraph BeforeLeftDblClickOnGraph BeforeMiddleClickOnGraph BeforeMiddleDblClickOnGraph BeforeRightClickOnGraph BeforeRightDblClickOnGraph AfterLeftClickOnGraph AfterLeftDblClickOnGraph AfterMiddleClickOnGraph AfterMiddleDblClickOnGraph AfterRightClickOnGraph AfterRightDblClickOnGraph BeforeRefresh AfterRefresh BeforeProcmonButtonClick AfterProcmonButtonClick BeforeWindumpButtonClick AfterWindumpButtonClick BeforeLauncherButtonClick AfterLauncherButtonClick BeforeSwitchToFrameMode AfterSwitchToFrameMode BeforeSwitchToNormalMode AfterSwitchToNormalMode BeforeTimelineFirstFrame AfterTimelineFirstFrame BeforeTimelinePreviousFrame AfterTimelinePreviousFrame BeforeTimelineNextFrame AfterTimelineNextFrame BeforeTimelineLastFrame AfterTimelineLastFrame BeforeTimelinePlayAnimation AfterTimelinePlayAnimation BeforeTimelineStopAnimation AfterTimelineStopAnimation |
EventHandler |
Figure 1. From ProcDOT's documentation.
Let's begin by making a plugin for the Main Menu that opens the Windows command prompt. Although this plugin will not be very useful right now, it will be in later posts to help write other plugins. Back to the descriptor file.
Create a file named cmd_line.pdp in the ProcDOT plugin folder. If you do not have this folder, it can be created in the same folder the ProcDOT executable is located in. Inside this file we will place the following:
Name = cmd
Author = <your name>
Description = Open cmd prompt from ProcDOT's Main Menu
Version = 1
Type = MainMenuItem
Architecture = WindowsBatchScript
File = cmd_line.bat
Priority = 9
RunHidden = 0
RunExclusively = 1
CanOverrideOtherPlugins = 0
CanOverrideProcdot = 0
Now that we have our descriptor file, we can start to create our plugin. Notice in the descriptor file, File = cmd_line.bat. This will be our plugin. In the plugin directory, create a file called cmd_line.bat and place the following inside:
@setlocal enabledelayedexpansion && python -x "%~f0" %* & exit /b !ERRORLEVEL!
#!/usr/bin/env python
import os
os.system("start /wait cmd /K")
Lets break down what what this plugin will do:
Because we are calling our plugin in a batch file, the first line, @setlocal enabledelayedexpansion && python -x "%~f0" %* & exit /b !ERRORLEVEL!, calls python and executes the rest of the script through the python interpreter. This is so we do not have to associate .py files with python itself.
The rest of the lines are our python code to open the command prompt.
Lets fire up ProcDOT and see if our new plugin works.
When we click on the Plugins menu, there should be an entry called cmd.
Lets double check to make sure there are no errors in out plugin. We can do this by clicking on the Plugins-Manager. If there are not any errors, your screen should look like the one below.
We can also view the details of the plugin by clicking on the plugin from the Plugins-Manager menu.
Time to load up a pcap and a procmon trace to see if everything is working with the plugin Once the graph is generated, open the Plugins menu and select cmd. If everything worked you should have a command prompt open on your screen. If we type set | find /i "procdot" into this cmd prompt, we should see a list of ProcDOT variables to work with.
Success! We have created our first plugin.
In the upcoming post, we will use this plugin to create and troubleshoot other plugins.