- π οΈ Setting up Mona
βΆοΈ Running Mona- π§ AI integration
- π More information
- π Thank you
- π Found a bug?
- π€ Want to contribute?
- π Posts and resources about Mona v3
This repository contains the necessary Python files to run Mona v3 under WinDBG(X) and Immunity Debugger.
- Python 3 Support: Compatible with Python 3 (and tested with versions up to 3.14.4.) You'll need a recent version of the PyKD Python Library and the PyKD-ext bootstrapper. We recommend using pykd-ext bootstrapper version 2.0.0.25 or later.
- Backwards Compatible: Still runs on Python 2.7.18 (via PyKD and PyKD-ext)
- Multi-Architecture: Supports both x86 and x64 debugging sessions (note: not all
monacommands are available in 64-bit) - Tested on: Windows 7, Windows 10, and Windows 11
For Windows 10 and later, we recommend using the CorelanPyKDInstall.ps1 PowerShell script from the CorelanTraining repo.
The script will automatically:
- Install Python 3.9.13 (both 32-bit and 64-bit)
- Install PyKD Python library
- Install Keystone-engine Python library
- Install PyKD-ext bootstrapper WinDBG extension
- Install Visual Studio runtime and register required DLLs
If you prefer to install those components yourself, after installation, verify that Python 3 and PyKD work as expected:
Open an Administrator Command Prompt.
Run py -3.9-32
You should get a Python interactive shell running Python 3.9.13 32bit:
C:\>py -3.9-32
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:24:45) [MSC v.1929 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>Type the following commands and verify there are no warnings or errors:
import pykd
import keystone
quit()Next, run py -3.9-64
That should provide you with a Python interactive shell running Python 3.9.13 64bit
C:\>py -3.9-64
Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>Type the following commands and verify there are no warnings or errors:
import pykd
import keystone
quit()If you are still using Windows 7:
Begin by installing Python 2.7.18.
Next, download a copy of the CorelanWin7VMinstall.py python script from the CorelanTraining repo and run it from an Administrator Command Prompt.
(let's say you have stored the file on your C: drive)
C:\>cd Python27
C:\Python27>python c:\CorelanWin7VMinstall.pyThis will install all required components to run mona on Windows 7.
The 64-bit versions of WinDBG(X) do not support assembling 64-bit mnemonics into opcodes.
Mona includes a small assembly cache in windbglib.py... but that's not really good enough to meet all needs.
If keystone-engine is installed, windbglib.py will use it when needed.
If not, support for 64-bit assembly will be very limited (to the items in the assembly cache), and some commands that take arbitrary assembly statements might fail.
Yes, of course. The CorelanPyKDInstall.ps1 script mentioned earlier will install Python 3.14.4 and all required dependencies automatically. Ff you prefer to do things by hand, this is the step by step:
1.4.1. Install Python 3.14.4 (both 32bit and 64bit)
Download installers from the URLs below and run each installer
- x86: https://www.python.org/ftp/python/3.14.4/python-3.14.4.exe
- x64: https://www.python.org/ftp/python/3.14.4/python-3.14.4-amd64.exe
1.4.2. Upgrade pip:
py -3.14-32 -m pip install --upgrade pip
py -3.14 -m pip install --upgrade pip1.4.3. Install keystone engine:
py -3.14-32 -m pip install keystone-engine
py -3.14 -m pip install keystone-engine1.4.4. Download the pykd library:
- x86: https://github.com/corelan/CorelanTraining/raw/refs/heads/master/pykd/pykd-python3.14-package-x86.zip
- x64: https://github.com/corelan/CorelanTraining/raw/refs/heads/master/pykd/pykd-python3.14-package-x64.zip
Extract the files, you'll get 2 .whl files (and some other files). Install the Python wheels (the .whl files) via pip.
From the folder that contains the extracted .whl files (verify the actual filenames):
py -3.14-32 -m pip install pykd-0.3.4.15+g19ddf62-cp314-win32.whl
py -3.14 -m pip install pykd-0.3.4.15+g19ddf62-cp314-win-amd64.whl1.4.5. Verify that you are running pykd-ext version 2.0.0.25
Open WinDBG. Run !load pykd and then type !pykd.info to see the pykd-ext version.
If you're using an older version:
-
Remove the existing pykd.dll files from
%LOCALAPPDATA%\DBG\EngineExtensionsand%LOCALAPPDATA%\DBG\EngineExtensions32 -
Download the v2.0.0.25 version here:
-
Put pykd.dll from the x86.zip file inside
%LOCALAPPDATA%\DBG\EngineExtensions32 -
Put pykd.dll from the x64.zip file inside
%LOCALAPPDATA%\DBG\EngineExtensions
All set! That should do the trick.
After loading pykd, you can now invoke !py -3.14 to run mona.py.
Adjust the instructions in the procedure below accordingly.
You have two installation approaches:
- Distributed installation: multiple copies
- Centralized installation: recommended, single copy
This setup involves installing separate copies of mona.py and windbglib.py for each debugger application.
For the record, we do recommend and prefer using a centralized location, but in case your interested in how to make things work using individual copies of mona.py and windbglib.py for each debugger, you can follow the steps below.
First of all, download mona.py and windbglib.py from this repository and store them somewhere.
β οΈ Important: Verify the downloaded files contain actual Python code, not HTML
For WinDBG Classic:
- 32-bit: put the 2 files under
C:\Program Files (x86)\Windows Kits\10\Debuggers\x86 - 64-bit: put the 2 files under
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
This technically allows you to reference mona.py without having to provide the absolute path, as it should be relative to the WinDBG Classic application.
For Immunity Debugger:
- Place
mona.pyin:C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands - Note: You do not need
windbglib.pyfor Immunity
For WinDBGX:
- Reference
mona.pyfrom any location of your choice. You will very likely have to reference one of the files in the WinDBG Classic program folders yourself.
Advantages: Maintain a single copy on your system. Each mona up update applies to all debuggers immediately.
We will put the files in a central location. That means we'll have to refer to the files using their absolute path.
Don't worry, we're going to use WinDBG(X) aliases to avoid having to type the full path. In fact, the goal is to simply run
!mona
Create a central folder, for instance C:\Tools\mona3.
(If you decide to make another folder, please update the commands below accordingly)
Download mona.py and windbglib.py from this repository and store them in the central folder: C:\Tools\mona3
β οΈ Important: Verify the downloaded files contain actual Python code, not HTML
Reference the files directly from C:\Tools\mona3 using aliases (see Section B below for auto-loading setup).
Recommendation: Use Python 3.9 when running mona in WinDBG(X).
If not using Immunity Debugger or Python2 scripts, feel free to safely remove Python 2 from your system.
Option A: Create a symbolic link (recommended)
From an Administrator Command Prompt:
mklink "C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands\mona.py" "C:\Tools\mona3\mona.py"Option B: Copy the file directly
- Copy
mona.pyto:C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands
Python 2 Setup (required for Immunity):
- Install Python 2.7.18 (32-bit version only)
- Ensure the 32-bit
C:\Python27folder is in your system PATH environment variable- Verify by opening Command Prompt and typing
pythonβ it should launch Python 2.7.18 (32-bit) - Alternative: See Section E below for a launcher
.batfile to temporarily set the PATH
- Verify by opening Command Prompt and typing
Note: We recommend launching WinDBG Classic or WinDBGX from an Administrator Command Prompt. This ensures the debugger runs with administrator privileges and lets you pass command-line arguments more easily.
Step 1: Open WinDBG Classic
Run windbg.exe from the correct WinDBG Program Folder. The base path typically begins with C:\Program Files (x86)\Windows Kits\10\Debuggers, and inside that folder, you should find a x86 and a x64 folder, amongst others.
Make sure to run windbg.exe from the x64 folder if you're going to attach to a 64bit process, and to run windbg.exe from the x86 folder to open a 32bit debugging session.
Next, attach WinDBG Classic to your target process.
Step 2: At the WinDBG Classic Command Line, load the PyKD bootstrapper extension:
!load pykdStep 3: Run Mona using Python 3.9:
!py -3.9 C:\Tools\mona3\mona.pyConvenience: Create an alias to avoid typing the full path every time:
!as !mona !py -3.9 C:\Tools\mona3\mona.pyNow you can simply type !mona at the WinDBG Command Line.
Section B below shows how to automate this alias at startup.
Step 1: Open WinDBGX by running windbgx and attach it to your target process. WinDBGX will automatically select the right architecture based on the process you're attaching to.
Step 2: At the WinDBGX Command Line, load the PyKD bootstrapper extension:
!load pykdStep 3: Run Mona using Python 3.9:
!py -3.9 C:\Tools\mona3\mona.py(You can run the same command on 32bit and 64bit debugging sessions, WinDBGX will select the appropriate Python 3.9.13 version)
Convenience: Create an alias to avoid typing the full path every time:
!as !mona !py -3.9 C:\Tools\mona3\mona.pyNow you can simply type !mona at the WinDBG(X) Command Line as well.
For WinDBG Classic:
Launch windbg.exe from its program folder, and use the -c command-line flag to auto-load PyKD and create the mona alias.
To make things even easier, you could consider creating a small batch file inside the WinDBG Program folders (both x86 and x64) that has all the required command line arguments:
For example, create w.bat in the x86 folder with the following contents:
set "WINDBG_CMD=windbg.exe -hd -c '!load pykd; as !mona !py -3.9 C:\Tools\mona3\mona.py' "
%WINDBG_CMD% %*Or, to launch a 64bit version of Python in WinDBG Classic 64bit:
set "WINDBG_CMD=windbg.exe -hd -c '!load pykd; as !mona !py -3.9-64 C:\Tools\mona3\mona.py' "
%WINDBG_CMD% %*For WinDBGX:
In WinDBGX, use Startup Settings to run these commands at the start of each session.
Configure the Startup settings to auto-load on every session:
- Navigate to: File > Settings > Debugging settings > Startup
- Paste the following commands:
!load pykd
as !mona !py -3.9 C:\Tools\mona3\mona.pyNote: You only need to configure this once. WinDBGX will automatically adapt to 32-bit or 64-bit depending on your debugging target.
For Windows 7, we recommend using a small launcher script that sets a few Python related environment variables.
To run mona with Python3, you could create this wpy3.bat file and save it inside the WinDBG Program folder
@echo off
set ORIGPATH=%PATH%
set PYTHONHOME=%LOCALAPPDATA%\Programs\Python\Python38-32
set PATH=%PYTHONHOME%;%PATH%
set PYTHONPATH=%PYTHONHOME%\Lib
set WINDBG_CMD=windbg.exe -hd -c '!load pykd;as !mona !py -3 C:\Tools\mona3\mona.py'
%WINDBG_CMD% %*
set PATH=%ORIGPATH%
set PYTHONHOME=
set PYTHONPATH=For Python2, the corresponding wpy2.bat file would look like this:
@echo off
set ORIGPATH=%PATH%
set PYTHONHOME=C:\Python27
set PATH=%PYTHONHOME%;%PATH%
set PYTHONPATH=%PYTHONHOME%\Lib
set WINDBG_CMD=windbg.exe -hd -c '!load pykd;as !mona !py -2 C:\Tools\mona3\mona.py'
%WINDBG_CMD% %*
set PATH=%ORIGPATH%
SET PYTHONHOME=
SET PYTHONPATH=You can use similar batch files in Windows 11 as well.
This may be helpful in case you have various different Python versions installed on your system.
Although WinDBG(X) may be able to find a certain Python version, it still may fail to locate/load basic libraries (such as socket etc)
This is what the problem looks like:
0:000> !pykd.info
pykd bootstrapper version: 2.0.0.24
Installed python:
Version: Status: Image:
------------------------------------------------------------------------------
2.7 x86-64 Unloaded C:\Windows\SYSTEM32\python27.dll
3.9 x86-64 Unloaded C:\Users\corelan\AppData\Local\Programs\Python\Python39\python39.dll
* 3.14 x86-64 Unloaded C:\Users\corelan\AppData\Local\Programs\Python\Python314\python314.dll
0:000> !py -2.7
Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:25:05) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import socket
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "C:\Python27\Lib\socket.py", line 47, in <module>
import _socket
ImportError: DLL load failed: %1 is not a valid Win32 application.
>>>As you can see, although WinDBG loaded the correct Python version and architecture (Python 2.7.18, 64-bit), it still references libraries from the 32-bit Python installation in C:\Python27\Lib instead of C:\Python27-64\Lib.
The fix is relatively easy. Set the PYTHONHOME and PYTHONPATH environment variables, and insert the correct folder into the PATH.
For example: Open WinDBG Classic and use Python 2.7.18 64bit (installed under C:\Python27-64):
@echo off
set ORIGPATH=%PATH%
set PYTHONHOME=C:\Python27-64
set PATH=%PYTHONHOME%;%PATH%
set PYTHONPATH=%PYTHONHOME%\Lib
set WINDBG_CMD=windbg.exe -hd -c '!load pykd;as !mona !py -2.7 C:\Tools\mona3\mona.py'
%WINDBG_CMD% %*
set PATH=%ORIGPATH%
SET PYTHONHOME=
SET PYTHONPATH=If Python 2.7 is in your system PATH:
Simply launch Immunity Debugger and type !mona at the command prompt.
If you do not want to keep C:\\Python27 in your system PATH:
Create a launcher batch file (runimmunity.bat) that temporarily sets the PATH variable:
@echo off
c:
cd "C:\Program Files (x86)\Immunity Inc\Immunity Debugger"
set ORIGPATH=%PATH%
set PATH=C:\Python27;%PATH%
immunitydebugger.exe
set PATH=%ORIGPATH%Run runimmunity.bat from an administrator prompt to launch Immunity Debugger with the correct Python path automatically configured.
Or create a shortcut on your desktop to the runimmunity.bat file, and configure it to run as administrator right away:
- Right click on the shortcut
- Choose Properties
- Open the General tab and change the name to something like
Immunity Debugger Py2 - Open the Shortcut tab
- Click Advanced
- Enable Run as administrator
- Click OK to save the changes
If you'd like, you can also change the icon. From the same Shortcut tab sheet:
- Click Change Icon. You'll probably get a warning because the script does not have icons. Click OK
- Use the Browse button and select the
immunitydebugger.exefile insideC:\Program Files (x86)\Immunity Inc\Immunity Debugger - Select the first icon in the list and click OK
- Click OK to save the changes
Mona includes AI-assisted analysis through the tellme command. It can inspect the current WinDBG context, build a structured prompt from that context, and either save that prompt for manual use or submit it directly to a configured AI engine.
There are two supported ways to use it:
- Manual workflow:
monabuilds the request and saves it to disk. You paste that request into ChatGPT, Claude, Grok, or another AI tool yourself. - Automated workflow:
monabuilds the request and sends it directly to a configured provider or local endpoint.
This makes tellme useful even if you do not want to install SDKs, configure API keys, or make live requests from inside the debugger host.
If you use -offline, tellme will collect debugger context, build the full request, and save it to a file without contacting any provider.
That is the simplest setup and the safest default when you want full control over where the prompt is submitted.
Example:
!mona tellme -q 1 -offlineTypical use cases:
- You want to inspect the generated request before sending it anywhere
- You prefer browser-based AI tools over API access
- You do not want to configure keys, SDKs, or billing
- You want a workflow that still works when no engine is configured
If you want mona to submit requests directly, configure a default engine and the settings that engine needs, such as API key, model, URL, timeout, and optional response parsing fields.
When you omit -e, engine selection works like this:
mona.ai.engineMONA_AI_ENGINE- if neither is set,
tellmeswitches to offline mode by default
That fallback is intentional so you do not accidentally consume tokens.
Configuration can live in mona.ini or in environment variables. If both are present, values from mona.ini take precedence.
Example using mona config:
!mona config -set mona.ai.engine openai
!mona config -set openai.key <your OpenAI API key>
!mona config -set openai.model gpt-5-mini
!mona config -set openai.timeout 60
!mona config -set openai.max_tokens 4096
!mona config -set mona.ai.engine anthropic
!mona config -set anthropic.key <your Anthropic API key>
!mona config -set anthropic.model claude-sonnet-4-6
!mona config -set anthropic.timeout 60
!mona config -set anthropic.max_tokens 4096Example using environment variables:
set MONA_AI_ENGINE=openai
set OPENAI_API_KEY=<your OpenAI API key>
set OPENAI_MODEL=gpt-5-mini
set OPENAI_TIMEOUT=60
set OPENAI_MAX_TOKENS=4096
set ANTHROPIC_API_KEY=<your Anthropic API key>
set ANTHROPIC_MODEL=claude-sonnet-4-6
set ANTHROPIC_TIMEOUT=60
set ANTHROPIC_MAX_TOKENS=4096For openai direct integration, install the OpenAI Python library for every Python version you use with mona. For example, if you run Mona under both Python 3.9 and Python 3.14, install the library into both environments.
py -3.9-32 -m pip install openai
py -3.9 -m pip install openai
py -3.14-32 -m pip install openai
py -3.14 -m pip install openaiFor openaiagents, the dependency is different. That engine starts a separate Python bridge outside the debugger and that bridge must be able to import both the OpenAI Agents SDK and the OpenAI Python library.
Install those dependencies into the Python environment that will be used by openaiagents.bridge.python.
For example, if your bridge is configured to use Python 3.14:
py -3.14 -m pip install openai-agents openaiIf you want Mona to launch the bridge with that interpreter, configure it like this:
!mona config -set mona.ai.engine openaiagents
!mona config -set openaiagents.bridge.python py -3.14If you use a different Python version for the bridge, run the same pip install command against that interpreter instead.
At runtime, Mona validates that the configured openaiagents.bridge.python environment can import:
agentsAgent,Runner,ModelSettings, andRunConfigfrom the Agents SDKopenai.types.shared.Reasoningfrom the OpenAI Python library
Make sure you install those libraries into the Python environment used by openaiagents.bridge.python, not just the Python environment used inside WinDBG.
When tellme is using a live provider, it checks the selected model where supported. If you run tellme without -q while a provider-backed engine is configured, Mona will list the available model IDs it can see for that configuration instead of sending a request.
In Mona, an engine is the backend that receives the generated AI request. Some engines are cloud APIs, some are local/self-hosted endpoints, and one is a bridge for the OpenAI Agents SDK.
Currently supported engines are:
offline: save the request only; do not submit itopenai: direct OpenAI API integrationopenaiagents: local bridge that uses the OpenAI Agents SDK and OpenAI Python library outside the debuggeranthropic: direct Anthropic API integrationollama: local or remote Ollama endpointcustomai: generic POST JSON endpoint for other compatible backends
Use -e <engine> to select one explicitly for a single request, or set mona.ai.engine to make one the default.
The tellme command has three common usage patterns:
-q 1: analyze the current crash context-q 2: analyze the current function or code location-q 9 -f <file>: use a saved request template
Basic examples:
!mona tellme -q 1
!mona tellme -e openai -q 1
!mona tellme -e anthropic -q 2
!mona tellme -e ollama -q 1
!mona tellme -e openai -q 2 -a kernel32!CreateFileW
!mona tellme -e openai -q 1 -timeout 120
!mona tellme -e openai -q 1 -submit
!mona tellme -e openai -q 1 -offlineUseful options:
-e <engine>: choose the engine explicitly for this request-q 1: use for crash triage-q 2: use for function/code analysis-a <address|register|module!symbol>: use an explicit target address-l <file1,file2>: add extra context files-p <file>: attach a PoC or trigger file-model <id>: override the configured model for one request-timeout <seconds>: override the configured timeout for one request-submit: skip the confirmation prompt and submit the AI request immediately-offline: build and save the request without calling the API
If you omit -q while a provider-backed engine is selected, tellme will list the available models for that engine instead of building a request.
How to choose a mode:
- Use
!mona tellme -q 1when you want help triaging the current crash. - Use
!mona tellme -q 2when execution is at a useful code location and you want help understanding the current function. - Use
-awith-q 2when the current instruction pointer is no longer trustworthy and you want to analyze a known-good symbol or address instead. - Use
-offlinewhen you want to manually submit the generated request to a browser-based AI session. - For automated submission,
tellmeasks for confirmation before sending the request unless you pass-submit.
Template usage:
!mona tellme -e openai -q 9 -f ai.q1
!mona tellme -e openai -q 9 -f ai.q2 -a kernel32!CreateFileWIf ai.q1 or ai.q2 do not exist yet, running -q 1 or -q 2 will create them in the configured workingfolder, or next to mona.ini when no working folder is set.
With -q 9, mona collects live debugger context at runtime and replaces recognized placeholders such as [registers] and [pc_disasm] inline before submitting the prompt. Unrecognized placeholders are reported and left unchanged.
For engine-specific setup, model recommendations, local/self-hosted examples, bridge configuration, advanced options, and troubleshooting, see the Mona wiki.
For additional documentation, examples, and background information, check the Mona wiki.
Mona v3 would not have been possible without the hard work and dedication of @apl3b. Thank you! π
If you discover a bug, please open an issue and provide detailed steps to reproduce the problem.
See CONTRIBUTING.md for contribution guidelines.
If you are changing or debugging a specific !mona command, be aware that the repo also includes testing/runmonatests.cmd to exercise that command across multiple test scenarios. See CONTRIBUTING.md for setup and usage details, including the requirement to run it from an elevated Administrator Command Prompt.
