Skip to content

corelan/mona3

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

860 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

mona v3 banner

MONA v3

πŸ“‘ Table of Contents

This repository contains the necessary Python files to run Mona v3 under WinDBG(X) and Immunity Debugger.

Highlights

  • 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



πŸ› οΈ Setting up Mona


πŸ“¦ 1. Install dependencies

1.1. Windows 10 and later

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()

1.2. Windows 7

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.py

This will install all required components to run mona on Windows 7.


1.3. A note on 64bit

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.


1.4. Can you help me run mona under Python 3.14.4?

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

1.4.2. Upgrade pip:

py -3.14-32 -m pip install --upgrade pip
py -3.14 -m pip install --upgrade pip

1.4.3. Install keystone engine:

py -3.14-32 -m pip install keystone-engine
py -3.14 -m pip install keystone-engine

1.4.4. Download the pykd library:

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.whl

1.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:

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.




πŸ“₯ 2. Install mona & windbglib

You have two installation approaches:


2.1. Distributed installation

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.py in: C:\Program Files (x86)\Immunity Inc\Immunity Debugger\PyCommands
  • Note: You do not need windbglib.py for Immunity

For WinDBGX:

  • Reference mona.py from any location of your choice. You will very likely have to reference one of the files in the WinDBG Classic program folders yourself.

2.2. Centralized installation (recommended)

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


Step 1: Set up central location

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


Step 2: Configure for WinDBG Classic / WinDBGX

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.


Step 3: Configure for Immunity Debugger

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.py to: 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:\Python27 folder 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 .bat file to temporarily set the PATH



▢️ Running Mona


A. Running Mona in WinDBG Classic and WinDBGX

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.

WinDBG Classic

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 pykd

Step 3: Run Mona using Python 3.9:

!py -3.9 C:\Tools\mona3\mona.py

Convenience: Create an alias to avoid typing the full path every time:

!as !mona !py -3.9 C:\Tools\mona3\mona.py

Now you can simply type !mona at the WinDBG Command Line.

Section B below shows how to automate this alias at startup.

WinDBGX

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 pykd

Step 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.py

Now you can simply type !mona at the WinDBG(X) Command Line as well.


B. Auto loading pykd and creating an alias in WinDBG Classic and WinDBGX

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:

  1. Navigate to: File > Settings > Debugging settings > Startup
  2. Paste the following commands:
!load pykd
as !mona !py -3.9 C:\Tools\mona3\mona.py

Note: You only need to configure this once. WinDBGX will automatically adapt to 32-bit or 64-bit depending on your debugging target.


C. Running Mona in WinDBG Classic on Windows 7

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=

D. Helping Python find its libraries

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=

E. Running Mona in Immunity

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.exe file inside C:\Program Files (x86)\Immunity Inc\Immunity Debugger
  • Select the first icon in the list and click OK
  • Click OK to save the changes

🧠 AI integration

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: mona builds the request and saves it to disk. You paste that request into ChatGPT, Claude, Grok, or another AI tool yourself.
  • Automated workflow: mona builds 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.

Manual workflow

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 -offline

Typical 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

Automated workflow

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:

  1. mona.ai.engine
  2. MONA_AI_ENGINE
  3. if neither is set, tellme switches 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 4096

Example 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=4096

For 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 openai

For 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 openai

If 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.14

If 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:

  • agents
  • Agent, Runner, ModelSettings, and RunConfig from the Agents SDK
  • openai.types.shared.Reasoning from 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.

Engines

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 it
  • openai: direct OpenAI API integration
  • openaiagents: local bridge that uses the OpenAI Agents SDK and OpenAI Python library outside the debugger
  • anthropic: direct Anthropic API integration
  • ollama: local or remote Ollama endpoint
  • customai: 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.

Basic usage

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 -offline

Useful 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 1 when you want help triaging the current crash.
  • Use !mona tellme -q 2 when execution is at a useful code location and you want help understanding the current function.
  • Use -a with -q 2 when the current instruction pointer is no longer trustworthy and you want to analyze a known-good symbol or address instead.
  • Use -offline when you want to manually submit the generated request to a browser-based AI session.
  • For automated submission, tellme asks 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!CreateFileW

If 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.


πŸ“š More information

For additional documentation, examples, and background information, check the Mona wiki.




πŸ™ Thank you

Mona v3 would not have been possible without the hard work and dedication of @apl3b. Thank you! πŸ™



πŸ› Found a bug?

If you discover a bug, please open an issue and provide detailed steps to reproduce the problem.



🀝 Want to contribute?

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.



πŸ“š Posts and resources about Mona v3

About

Repository for mona v3 - Corelan's exploit dev tool for Windbg, WindbgX etc

Resources

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors