{"id":50853828,"url":"https://github.com/MCUSec/uEmu","last_synced_at":"2026-07-02T04:00:29.201Z","repository":{"id":46336559,"uuid":"334809136","full_name":"MCUSec/uEmu","owner":"MCUSec","description":"A Universal MCU Firmware Emulator for Dynamic Analysis without Any Hardware Dependence.","archived":false,"fork":false,"pushed_at":"2023-05-11T04:29:21.000Z","size":129,"stargazers_count":101,"open_issues_count":2,"forks_count":20,"subscribers_count":5,"default_branch":"main","last_synced_at":"2023-08-10T09:08:33.159Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MCUSec.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-02-01T02:34:36.000Z","updated_at":"2023-10-20T11:41:09.499Z","dependencies_parsed_at":"2022-08-12T12:50:45.309Z","dependency_job_id":"c0f1cee2-caa4-4291-ae5d-0834842adc54","html_url":"https://github.com/MCUSec/uEmu","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/MCUSec/uEmu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MCUSec%2FuEmu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MCUSec%2FuEmu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MCUSec%2FuEmu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MCUSec%2FuEmu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MCUSec","download_url":"https://codeload.github.com/MCUSec/uEmu/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MCUSec%2FuEmu/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35032145,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-14T17:00:21.881Z","updated_at":"2026-07-02T04:00:29.189Z","avatar_url":"https://github.com/MCUSec.png","language":"Python","funding_links":[],"categories":["Software Tools"],"sub_categories":["MCU Firmware Fuzzing"],"readme":"# μEmu\n\nA Universal MCU Firmware Emulator for Dynamic Analysis without Any Hardware Dependence\n\n## General Idea\n\nUnlike existing MCU firmware dynamic analysis tools that forwards the interactions with unsupported peripherals to the real hardware, μEmu takes the firmware image as input and symbolically executes it by representing unknown peripheral registers as symbols.\nDuring symbolic execution, it infers the rules to respond to unknown peripheral accesses. These rules are stored in a knowledge base (KB), which is referred to firmware during dynamic analysis **without any hardware dependence**. The detail of μEmu design and implementation, please refer to our paper.\n\n## Citing our paper\n\n```bibtex\n@inproceedings {uEmu,\nauthor = {Wei Zhou and Le Guan and Peng Liu and Yuqing Zhang},\ntitle = {Automatic Firmware Emulation through Invalidity-guided Knowledge Inference},\nbooktitle = {30th {USENIX} Security Symposium ({USENIX} Security 21)},\nyear = {2021},\nurl = {https://www.usenix.org/conference/usenixsecurity21/presentation/zhou},\npublisher = {{USENIX} Association},\n}\n```\n\n\n## Directory structure of the repo\n\n```\n.\n├── LICENSE\n├── README.md\n├── docs                     # more documentation about implementation and configuration\n├── uEmu-helper.py           # helper scripts to configurate μEmu based on configration file (e.g., μEmu.cfg)\n├── launch-uEmu-template.sh  # template scripts to launch μEmu\n├── launch-AFL-template.sh   # template scripts to launch AFL fuzzer\n├── uEmu-config-template.lua # template config file of μEmu and S2E plugins\n├── library.lua              # contains convenience functions for the uEmu-config.lua file.\n├── uEmu-unit_tests          # uEmu unit test samples and config files\n├── uEmu-fuzzing_tests       # uEmu fuzzing test samples (real-world MCU firmware) and config files\n├── ptracearm.h\n├── totalbbrange.py          # IDA plugin for basic block range calculation\n├── vagrant-bootstrap.sh     # bootstrap file for vagrant box\n└── Vagrantfile              # configuration file for vagrant box\n```\n\n## Vagrant Installation (Recommended)\n\nFor easy setup, a vagrant file for a virtual machine with a ready-to-use build of uEmu is provided.\nAfter installing vagrant, the following steps are required:\n```bash\ngit clone https://github.com/MCUSec/uEmu.git\ncd uEmu\nvagrant up  # this will take a while, please be patient\nvagrant ssh # connect to the virtual machine\n```\n\nNow, from inside the virtual machine, you have the contents of this repository available at `/vagrant/`.\n\n**Note**: The VM is configured to use 4 cores and 4096 MB of RAM. You can change this by modifying the Vagrant file.\n\n## Source Code Installation\n\n**Note**:\n1. uEmu builds and runs on Ubuntu 18.04 or 20.04 LTS (64-bit). Earlier versions may still work, but we do not support them anymore.\n\n2. Since the qemu in arm kvm mode will use ptrace.h which is from the host arm linux kernel, however the real host μEmu is X86, so you have to add ptracearm.h from [linux source code](https://elixir.bootlin.com/linux/latest/source/arch/arm/include/asm/ptrace.h) (you can directly download it from this repo) to the your local path: ``/usr/include/x86_64-linux-gnu/asm``.\n\n### Required packages\n\nYou must install a few packages in order to build μEmu manually.\nThe required packages of μEmu is same as the current S2E 2.0,\nYou can check out all [required packages](https://github.com/MCUSec/uEmu/blob/main/vagrant-bootstrap.sh#L8) from line 8 to 21 in the Vagrant script.\n\n\n### Checking out source code\n\nThe μEmu source code can be obtained from the my git repository using the following commands.\n\n```console\n export uEmuDIR=/home/user/uEmu  # uEmuDIR must be in your home folder (e.g., /home/user/uEmu)\n sudo apt-get install git-repo   # or follow instructions at https://gerrit.googlesource.com/git-repo/\n cd $uEmuDIR\n repo init -u https://github.com/MCUSec/manifest.git -b uEmu\n repo sync\n```\nThis will set up the μEmu repositories in ``$uEmuDIR``.\n\n\n### Building μEmu\n\nThe μEmu Makefile can be run as follows:\n\n```console\n    $ sudo mkdir $uEmuDIR/build\n    $ cd $uEmuDIR/build\n    $ make -f $uEmuDIR/Makefile \u0026\u0026 make -f $uEmuDIR/Makefile install\n    # Go make some coffee or do whatever you want, this will take some time (approx. 60 mins on a 4-core machine)\n```\n\nBy default, the ``make`` command compiles and installs μEmu in release mode to ``$uEmuDIR/build/opt``. To change this\nlocation, set the ``S2E_PREFIX`` environment variable when running ``make``.\n\nTo compile μEmu in debug mode, use ``make install-debug``.\n\n\n\n### Building and Preparing AFL\n\n```console\ncd $uEmuDIR/AFL\nmake\nsudo make install\n```\n\n### Updating\n\nYou can use the same Makefile to recompile μEmu either when changing it yourself or when pulling new versions through\n``repo sync``. Note that the Makefile will not automatically reconfigure the packages; for deep changes you might need\nto either start from scratch by issuing ``make clean`` or to force the reconfiguration of specific modules by deleting\nthe corresponding files from the ``stamps`` subdirectory.\n\n## Usage\n\nAll  μEmu plugins are enabled and configured with Lua-based configuration file `uEmu-config.lua`.\nTo provide user a more user-friendly configuration file, we provide python script named `uEmu-helper.py` to quickly generate Lua-base configure files based on template file `uEmu-config-template.lua`  based on a sample user-defined CFG file.\n\nIt will also generate launch scripts to run μEmu and AFL fuzzer based on `launch-uEmu-template.sh` and `launch-AFL-template.sh` files. \n\nPlease make sure the `launch-uEmu-template.sh`, `launch-AFL-template.sh`, `uEmu-config-template.lua` and `library.lua` exist and place in the same path e.g., \u003cproj_dir\u003e  with `uEmu-helper.py`.\n\n\n\n### Preparing the user configuration file\nYou can use the configuration files provided in our [unit-tests](https://github.com/MCUSec/uEmu-unit_tests) and [real-world-firwmare](https://github.com/MCUSec/uEmu-real_world_firmware) repos to our unit test samples or real-world samples in the μEmu paper.\nIf you want to test your own firmware, please refer to this [instruction](docs/Configuration.md) and our paper to edit the user configuration file. \n\nNote that incorrect configurations will lead to unexpected  behaviors of μEmu like stall or finishing with inaccurate KB.\n\n\n### μEmu workflow\nHere, we take `WYCNINWYC.elf` firmware as a example to show how to run the μEmu with `uEmu-helper.py` and some attention points in each phase.\n\n#### KB Extraction Phase:\n\n\n\n```bash\nUsage: python3 \u003crepo_path\u003e/uEmu-helper.py \u003cfirmware_name\u003e \u003cconfig_file_name\u003e  [-h] [--debug]\n```\n\n- arguments:\n  * firmware           Tested Firmware. e.g., drone.elf\n  * config             User Configuration File. e.g., firmware.cfg\n  * -h, --help (optional)            Show this help message and exit\n  * --debug (optional)              Run μEmu in debug mode. Note that μEmu will output huge log information in a short time and slow down in debug mode, please ensure you have enough space (e.g., more than 100M). Thus, we recommend only run μEmu with debug mode under KB extraction phase.\n\n**Example**:\n```console\npython3 \u003crepo_path\u003e/uEmu-helper.py \u003cproj_dir\u003e/WYCINWYC.elf \u003cproj_dir\u003e/WYCNINWYC.cfg\n```\n\nAfter the above command successfully finishes,  you could find the `launch-uEmu.sh` and `uEmu-config.lua` in your \u003cproj_dir\u003e. Then, you can launch the first-round KB extraction via **carrying out the `launch-uEmu.sh` script** and you can verify `uEmu-config.lua` to know whether you configurations are actually as your excepted . \n\nAfter finishing (typically a few minutes), you can find log files and knowledge base (KB) file named as `firmwarename-roundnumber-finalstatenumber-unqiuebbnumber_KB.dat` (e.g., `WYCINWYC.elf-round1-state53-bbnum1069_KB.dat`) in `s2e-last` (referring to the `s2e-out-\u003cmax\u003e`) folder. Detail logs will be printed to `s2e-last/debug.txt` and important log information will be printed to`s2e-last/warnings.txt` . More detail about log files please refer to [S2E documents](http://s2e.systems/docs/index.html) .\n\n**NOTE**:\n\n1. If you find μEmu cannot be finished KB extraction with a quiet long time (e.g., more than ten minutes), typically the reason is μEmu has been stuck. You should manually abort the execution, then check the configuration file, firmware and log files to find the reason and re-configure and re-run the firmware with μEmu. Thus,  we recommend user to enable debug level log information (add `--debug` in above command)  when he first time runs the firmware.\n\n\n#### Dynamic Analysis and Fuzzing Phase:\n\nNext, you can run the firmware with learned KB for dynamic analysis.  About more detail about KB entries format please refer to [kb.md](docs/KB.md).\n\n\n```bash\nUsage: python3 \u003crepo_path\u003e/uEmu-helper.py \u003cfirmware_name\u003e \u003cconfig_file_name\u003e  -kb KBFILENAME [-s SEEDFILENAME]\n```\n- arguments:\n  * -kb KBFILENAME,       Configure the Knowledge Base filename used for μEmu fuzzing phase and μEmu will run under fuzzing phase. If KB file is not present, μEmu will run KB extraction phase by default.\n  * -s SEEDFILENAME(optional),      Configure the seed filename to bootstrap fuzzing, if absent, μEmu will use random number(32 bit) for fuzzing.\n\n**Example**:\n\nThe below command is to configure μEmu for running `WYCINWYC.elf` firmware in dynamic phase with `WYCINWYC.elf-round1-state53-tbnum1069_KB` KB file and fuzzing seed file `small_document.xml`.\n\n\n```console\npython3 uEmu-helper.py WYCINWYC.elf WYCNINWYC.cfg -kb WYCINWYC.elf-round1-state53-tbnum1069_KB.dat -s small_document.xml\n```\nSince μEmu relies on AFL for fuzzing input. Thus, you first need to launch AFL fuzzur via `./launch-AFL.sh` in **one terminal** to input test-cases and then launch μEmu via `./launch-uEmu.sh` in **another terminal** to consume the test-cases.\nThe fuzzing results is stored in \u003cproj_dir\u003e/\u003cfirmware\u003e folder. The log and KB files of addition round KB extraction phase are record in \u003cs2e-last\u003e folder.\n\n**NOTE**:\n1. Please abort fuzzing from AFL terminal, and then μEmu will automatically terminate.\n1. We recommend enable `auto_mode_switch`  in configuration file during fuzzing to automatically switch two phase , since complex firmware often use new peripherals on demand.\n2. If no seed file given, μEmu will use 4 bytes random number as initial seed to bootstrap fuzzing.\n3. We enable fuzzing test during dynamic analysis phase by default, but user can disable it (`enable_fuzz = false`) in configuration file. Then data registers will only used values from KB.\n4. For more advanced configurations during fuzzing phase, please refer to `Fuzzer_Config` section in [instruction](docs/config.md).\n\n### Testcase analysis\nIf you only want to further analysis the firmware with single testcase input (e.g., crashing/hanging input), plese refer the below command to run μEmu helper script at first. Then launching μEmu via `./launch-uEmu.sh` only and **No** need to launch AFL.\n\n```bash\nUsage: python3 \u003crepo_path\u003e/uEmu-helper.py \u003cfirmware_name\u003e \u003cconfig_file_name\u003e  -kb KBFILENAME -t TESTCASENAME\n```\n- arguments:\n  * -t --testcasefilename,  Configure the testcase filename used for analysis and μEmu will exit when whole testcase has been consumed. If testcase filename is not present, μEmu will run fuzzing phase by default.\n\n\n**Example**:\n\nThe below command is to configure μEmu for running `WYCINWYC.elf` firmware for single testcase analysis using `WYCINWYC.elf-round1-state53-tbnum1069_KB` KB file and testcase file `testcase.txt.`.\n\n\n```console\npython3 uEmu-helper.py WYCINWYC.elf WYCNINWYC.cfg -kb WYCINWYC.elf-round1-state53-tbnum1069_KB.dat -t testcase.txt\n```\n### BB Coverage calcuation\nWhen user manully terminates the fuzzing process, μEmu will automatically terminate and record all reached QEMU translate block start addresses and the execution frequency of each translation block in file `fuzz_tb_map.txt`.\nWe provide in this repo a IDA plugin named `idapy_dump_valid_basic_block_range.py` to output each basic block range in file `valid_basic_block_range.txt` and total number of basic blocks.\nThen you can use `calculate.py` to get basic block coverage.\n```bash\nUsage: python3 calculate.py fuzz_tb_map.txt valid_basic_block_range.txt \n```\nCoverage in publication paper = # of visited QEMU translation blocks / total # of basic blocks.\n\n## Debugging with gdb\nFirst, μEmu should be complied with both symbols and all debug information in order to use it with gdb:\n```console\nsudo make -f $uEmuDIR/Makefile all-debug\n```\nThen, you can start μEmu in GDB with `./launch-uEmu.sh debug`. The gdb configuration script `gdb.ini` will be automatically generated in your current folder.\nMore information about debugging, please refer to [DebuggingS2E](http://s2e.systems/docs/DebuggingS2E.html).\n\n## More documentation\nPlease see [docs/](docs/) for more documentation.\n\n\n## Issues\nIf you encounter any problems while using our tool, please open an issue. \n\nFor other communications, you can email weizhou[at]hust.edu.cn.\n\n\n## Help Wanted\n### DMA Support\n### Architectures beyond ARM Cortex-M\n### Firmware Analysis beyond Fuzzing\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMCUSec%2FuEmu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FMCUSec%2FuEmu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FMCUSec%2FuEmu/lists"}