-
-
Notifications
You must be signed in to change notification settings - Fork 1
EndUser
This document explains how to run mona, how to get help for individual commands, how global options influence searches, and where to find the full command reference.
You can run mona from both WinDBG / WinDBGX and Immunity Debugger.
In WinDBG, mona is typically launched through PyKD and Python 3.9:
!load pykd
!py -3.9 C:\Tools\mona3\mona.py
That works, but it is much more convenient to create an alias so you can simply run:
!mona
Create the alias like this:
as !mona !py -3.9 C:\Tools\mona3\mona.py
If you are using WinDBG Classic, use the debugger -c flag when launching it so PyKD is loaded and the alias is created automatically at startup:
windbg.exe -hd -c "!load pykd; as !mona !py -3.9 C:\Tools\mona3\mona.py"
This is the recommended way to work, because it lets you open WinDBG and immediately use !mona without having to manually run setup commands every session.
For WinDBGX, you can do the same setup once through the startup settings:
- Go to
File > Settings > Debugging settings > Startup - Add:
!load pykd
as !mona !py -3.9 C:\Tools\mona3\mona.py
In Immunity, mona.py is run as a PyCommand. Once mona.py is present in the PyCommands folder and Python 2.7 is available, you can simply start Immunity Debugger and run:
!mona
If C:\Python27 is not in your system PATH, start Immunity through a small launcher batch file that temporarily adds the Python 2.7 folder to PATH before launching immunitydebugger.exe.
To get usage information for a specific command, either:
- run the command with
-h - run
!mona help <command>
Most search-style commands in mona are affected by global options. In other words: when you ask mona to search for pointers, gadgets, modules, or related results, the output is filtered not only by the command itself, but also by any global filters you provide.
Many commands already have default filters built in: by default, mona will only search in non-rebased, non-aslr modules.
Additionally, when looking for p/p/r gadgets in relation with an exception handling overwrite, mona seh will also exclude safseh-protected modules.
Within the memory ranges linked to the remaining modules (i.e. after applying the default filter explained above), mona will search in executable pages only.
That said, if the process is not protected by DEP, you may be able to use pointers from “readable” memory as well. You’d have to use -x R,X to include those in the searches. The fact that mona does not search in read-only pages, is per design, and not a mistake. After all, the goal is to present actionable output, not theoretical output based on assumptions or fabricated cases.
There are 3 commands that don’t follow the default module filter. Commands findwild, getiat and geteat will search across all modules, regardless of their behaviour and active mitigations.
Global options let you override or refine those defaults.
There are two main types of global options:
These options control which modules or memory regions are searched.
-
-m <modules>: only search the specified modules. This overrides other module criteria. -
-cm <criteria>: apply module-selection criteria such asaslr,rebase,safeseh,nx, andos. -
-o: exclude operating system modules from search operations. -
-n: skip modules whose addresses start with a null byte.
Examples:
-m "essfunc.dll"
-m "essfunc.dll,libspp.dll"
-m *
-cm aslr=false,rebase=false,safeseh=false
-cm os=false
Use module filters when you want to constrain the search to likely useful modules, or when you want to override the default module-selection behavior of a command.
These options control what kind of pointers or results are returned after the search is performed.
-
-cp <criteria>: require returned pointers to match specific byte properties. -
-cpb <badchars>: exclude pointers that contain specific bad characters. -
-x <level>: limit results by page access level such asX,RX,RWX,R, or*. -
-p <number>: limit the number of results returned.
Examples:
-cp nonull
-cp asciiprint
-cpb "\x00\x0a\x0d"
-x X
-x RWX
-p 5
These filters are especially useful during exploit development, where the “right” pointer is often not just a valid pointer, but one that also avoids bad characters, lands in executable memory, or matches a printable/alphanumeric constraint.
When a command says it searches for pointers or gadgets, the actual result set is shaped by:
- the command's own default behavior
- any module filters you provide
- any pointer/result filters you provide
So if a command appears to “miss” a result, the explanation is often that a default filter or a global option excluded it.
For more background on default filters and global-option behavior, see: