- π οΈ 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 and send that context to a supported AI provider to help explain what is happening, summarize findings, or assist with next-step analysis.
At the moment, mona supports these AI engines:
openaianthropic
To use OpenAI integration, install the OpenAI Python library for every Python version you plan to use with mona.
Anthropic requests use direct HTTP in the current implementation, so no Anthropic Python SDK is required.
For example, if you run mona with both Python 3.9 and Python 3.14, then you should install the provider library into both Python environments.
Example OpenAI installs:
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 openaiOnce the provider is configured, you can set a default engine, default model, timeout, and output token budget via environment variables or mona config.
Engine selection works like this when you omit -e:
mona.ai.engineMONA_AI_ENGINE- if neither is set,
tellmeannounces that fact and switches to offline mode by default
As an extra safety measure, if you do not specify -e and there is no default engine configured in either mona.ai.engine or MONA_AI_ENGINE, tellme will announce that at the start of the run and switch to -offline behavior by default so you do not accidentally consume API tokens.
The default request timeout is 60 seconds. You only need to set an engine-specific timeout when you want a different default for that provider, or override a single request with -timeout. For Anthropic responses, you can also increase the output budget with anthropic.max_tokens or ANTHROPIC_MAX_TOKENS if replies get truncated.
Examples 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 4096Examples 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=4096If both are present, values from mona.ini take precedence over environment variables. You can also override the model or timeout for a single request with -model and -timeout.
When tellme is using a live provider, it first queries that provider's models API and checks whether the configured model is available to the current API key. If you run tellme without -q while a provider engine is configured, mona will print the available model IDs it can see for that API key instead of submitting a request.
tellme can still build and save a request even if you do not have the provider libraries installed and/or you have not configured any API keys. That manual-request flow is fully supported.
If you use -offline, tellme will build the full request and save it to a file without calling the API. You can then take that saved request and submit it manually to a browser-based AI session such as ChatGPT, Claude, Grok, or another free or paid engine of your choice.
If you just want the analysis and do not care about direct API integration, -offline is often the simplest option:
!mona tellme -q 1 -offlineThat gives you a ready-to-submit request file while avoiding SDK installation, API keys, billing setup, or provider-specific runtime issues inside the debugger host.
If you want mona to call the providers directly through their APIs, make sure your account can access the provider and model you configured.
These are the same links referenced in the mona.py source:
Depending on the provider account, model, and risk controls, verification may be required before you can reliably use exploit-development or crash-triage prompts through the API.
Recent model examples at the time of writing:
- OpenAI:
gpt-5.5,gpt-5.1,gpt-5-mini,gpt-5-nano - Anthropic:
claude-opus-4-7,claude-sonnet-4-6,claude-haiku-4-5
Official model docs:
- OpenAI: https://developers.openai.com/api/docs/models
- Anthropic: https://platform.claude.com/docs/en/about-claude/models/overview
The tellme command has three main 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 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 <openai|anthropic>: choose the provider 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 API key.
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 direct API use,
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 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.
