uEmu: emulating a bare metal function inside IDA with Unicorn
Tiny cute emulator plugin for IDA based on unicorn.
At a glance
- What is it?
- uEmu is a small Python plugin that turns a loaded IDA database into a live Unicorn emulator, so a single function or a bootloader can be executed and inspected without leaving the disassembler. It is built for firmware and standalone code analysis and openly refuses to be an operating system emulator.
- Who is it for?
- Analysts working on bootloaders, embedded firmware and isolated functions should try uEmu, because it reuses the segments and breakpoints already present in the IDA database instead of requiring a separate emulation harness. It is the wrong tool for full operating system code, heavy syscall workloads, or any pipeline that needs batch, unattended runs.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 65 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
uEmu is a bridge from the IDA database into a Unicorn instance
uEmu answers a narrow question: how do you actually run a piece of code you are looking at in IDA, without rebuilding a whole harness first? The project describes itself as a tiny cute emulator plugin for IDA based on the Unicorn engine, and the plugin ships as a single file, uEmu.py, at the top level of a repository that also holds an Extensions directory, a Resources directory and the documentation images.
The data flow is straightforward once you know the shape of it. You point the plugin at a position in the database, it maps every segment from the IDA database into the emulator, and it copies initialized data across as well. From that point the Unicorn instance is the execution environment, while IDA stays the source of truth for what the bytes are. Registers, stack and memory are read back out of the emulator into IDA views.
Architectures supported out of the box are x86, x64, ARM, ARM64, MIPS and MIPS64. The project is written in Python and drives IDAPython, so the plugin runs inside IDA's own interpreter rather than as a separate process.
The project states plainly what it is bad for
Plenty of emulator tooling tries to promise everything, and the documentation here does the opposite. It lists two good uses: emulating bare metal code such as bootloaders and embedded firmware, and emulating standalone functions. Then it lists two bad uses: emulating complex operating system code involving dynamic libraries and processes, and emulating code with many syscalls.
That is a useful statement of scope rather than a hedge. Code with heavy syscall use needs an environment to service those calls, and a plugin that runs one bare interpreter has none. The same applies to operating system code that depends on loaded libraries. If your target is a Windows or Linux userland binary, uEmu will hit walls it was never designed to cross, and the README says so in advance.
The project also lists what it thinks could be improved, including a way to emulate vendor specific register access, with the ARM64 instruction `MSR S3_x, X0` given as the example, and adding more registers to track. Knowing that vendor system registers are an open problem is useful when you plan an analysis that touches them.
Installing uEmu needs Unicorn in two forms and a manual script load
The installation path is short but has a prerequisite that catches people out. IDAPython has to be configured first, and the project points at the idapyswitch instructions for that. Unicorn itself is needed twice, once as native binaries and once as Python bindings, so the machine ends up with a native library and the Python package on the same interpreter that IDA uses.
The commands the project gives are:
brew install unicorn
pip install unicornThe first line installs the Unicorn binaries, the second installs the Python bindings. Both are given as-is, with the caveat that they are the macOS Homebrew and pip forms, so a Linux or Windows setup has to translate them.
Loading the plugin is a manual action in the first case. Inside IDA you use the File / Script file... command, or the `ALT+F7` shortcut, and pick uEmu.py. If you would rather have it appear as a regular plugin, the project says to place it in the [IDA]/Plugins folder and change `USE_AS_SCRIPT` to `False` inside uEmu.py.
That single flag is the difference between a tool you open on demand and a tool that loads with every database you open.
Start maps the database, Run goes until something stops it
The command set is small enough to learn in one sitting, and each command has a distinct job. Start initializes the emulator by mapping all segments and setting up Unicorn, and it needs an initial CPU context first, which you supply through the Update CPU Context mechanism. After Start, all segments from the IDA database are mapped and initialized data is copied in.
Run emulates instructions until a breakpoint is reached or an error occurs. Step emulates one instruction, or N instructions if you hold `ALT`/`OPTION` to specify the count. Stop interrupts emulation while it is running. Reset resets the emulator instance and unmaps all memory regions, which is the clean way back to a known state. Jump To PC moves the view to the current PC, and Set PC moves PC to the cursor, so you can reposition execution by hand.
Breakpoints are the main way to steer a run. The project says IDA breakpoints, both code and memory breakpoints, indicate where emulation should be interrupted, and they are usually combined with Run. That means the breakpoint model you already use for static analysis is reused for dynamic analysis, with no separate debugger UI to learn.
One detail matters for reproducibility: only registers defined in the plugin are saved when a project state is saved, so a saved context is a partial snapshot by design.
Unmapped memory and unknown instructions surface as dialogs, not crashes
Emulation that stops for any reason is a dead end, and uEmu handles the two common reasons with a dialog and a choice. When the emulator touches memory that has not been mapped, a dialog appears with three responses. YES loads a supplied memory dump into that region, NO maps a single empty page of size 0x1000 filled with zeroes, and Cancel stops emulation entirely.
That NO option is a pragmatic escape hatch. A page of zeroes lets execution continue past a missing table, which is often enough to reach the code you actually care about, and the alternative of cancelling forces you to hunt for the right dump first.
The second case is an unknown instruction, where the emulator cannot decode what it found. The documented handling is to skip the instruction and restore the CPU context manually, so the register state at the point of failure is preserved rather than lost.
The settings panel adds four behaviours worth knowing. Follow PC scrolls the IDA view to the current PC during emulation. Convert to Code automatically turns data under the cursor into code. Trace instructions prints every instruction the emulator executes. Lazy mapping adds pages on demand instead of mapping all existing regions at Start, which is useful when a binary has a large memory image you never touch. All four are toggles, not configuration files.
The views are where you actually read the result
Three windows carry the observation side of the plugin. The Controls window is a plain panel with Start, Run, Step and Stop buttons, which is what you use during long sessions rather than the popup menu. The CPU Context window shows the available registers, and the CPU Extended Context window shows the extended FP and SIMD registers. In both register views, changed registers are highlighted every time emulation stops, and the layout can be switched to one, two or three columns from the popup menu. That highlight is the main feedback channel, since it tells you at a glance which registers the executed code actually wrote.
The Memory view takes an address and a size, and puts the comment in the window title for convenience. Changed memory blocks are highlighted each time emulation stops, so a data write is visible without a memory diff against a snapshot.
Register values can be changed one at a time or wholesale from a JSON file through the popup menu, and the current context can also be saved to a JSON file for reuse later. This is the mechanism for setting up a specific scenario, such as a function that expects a particular argument in a particular register, and it is also how a state is carried between sessions.
Save, load and the extension system for building on top
Two main menu commands handle state. Save Project writes the uEmu state to a file and Load Project reads it back, with the stated caveat that only registers defined in the plugin are saved. Fetch Segments does something different and quite useful: it tries to sync IDA segments with mapped memory by creating new mappings or merging with existing ones where possible, which lets you add segments to a running emulator without restarting it.
The main plugin menu also adds Show Mapped Memory, which lists all mapped regions and, through the popup menu, displays memory for a particular region or dumps it to a file.
For anything beyond single functions, the project points to an extension system, documented in Extensions/README.md, for adding new functionality or building on top of uEmu. One extension is named as an example: crauEmu, described as an extension for developing and analyzing payloads for code reuse attacks. That is the clearest signal of intended direction, and it also marks where the tool's users are: security researchers who want to run fragments of a binary in a controlled interpreter.
One caveat on maintenance: the repository has no GitHub releases, so there is no published version history to track, and the last push was on 2026-08-19. The repository is not archived, and the licence is not stated in the repository metadata, so treat reuse in a commercial setting as unresolved until you confirm it directly.
Editorial conclusion
Analysts working on bootloaders, embedded firmware and isolated functions should try uEmu, because it reuses the segments and breakpoints already present in the IDA database instead of requiring a separate emulation harness. It is the wrong tool for full operating system code, heavy syscall workloads, or any pipeline that needs batch, unattended runs. Before adopting it, verify that the Unicorn install on the machine matches the IDA Python environment, confirm the licence situation for the repository itself, and check whether the missing pieces the project lists as improvable, such as vendor specific register access, affect the code you need to run.
Frequently asked questions
What is uEmu used for in IDA?
uEmu maps the segments from your IDA database into a Unicorn emulator so that bare metal code such as bootloaders and embedded firmware, and standalone functions, can be executed and inspected inside IDA.
How do I install uEmu?
Configure IDAPython with idapyswitch, install Unicorn both as binaries with `brew install unicorn` and as Python bindings with `pip install unicorn`, then load uEmu.py from IDA through File / Script file... or `ALT+F7`.
Can uEmu emulate code that makes many syscalls?
No. The project lists code with many syscalls, and complex operating system code with dynamic libraries and processes, as cases uEmu is bad for.
What happens when the emulator hits unmapped memory?
A dialog appears. YES loads a memory dump into the region, NO maps one empty page of 0x1000 bytes filled with zeroes, and Cancel stops the emulation.
Which CPU architectures does uEmu support?
x86, x64, ARM, ARM64, MIPS and MIPS64 are supported out of the box.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/alexhude-uemu)Was this useful?