EMUX (formerly ARMX) Firmware Emulation Framework

by Saumil Shah @therealsaumil

April 2022 ARMX-EMUX

Welcome, MIPS!

With the addition of MIPS, ARMX has changed its name to EMUX! Try out the Damn Vulnerable MIPS Router exercises included with the new EMUX Docker image.

EMUX Docker EMUX Launcher

A brand new Docker container running EMUX. Going ahead, all official EMUX releases shall be released as Docker images. Lightweight, Compact, Easy.

Shut up and give me the g00diez

Github: https://github.com/therealsaumil/emux

A brand new EMUX Docker image is ready for use! The old "Preview VM" is now discontinued in favour of the Docker image.


Step 0 - Ensure that Docker is installed and running!

Test if Docker is working by running hello-world

docker run hello-world

Note: Ubuntu (and other Linux distros) users, ensure that your current user has privileges to run Docker as an administrator:

sudo groupadd docker
sudo gpasswd -a $USER docker
sudo usermod -aG docker $USER

Step 1 - Clone the EMUX repository

git clone --depth 1 --single-branch  https://github.com/therealsaumil/emux.git

Step 2 - Build the EMUX docker volume and image

cd emux

Note: If build-emux-docker fails, try and run it again by disabling DOCKER_BUILDKIT

                                 -f Dockerfile-emux .
                                 -f Dockerfile-emux .

Step 3 - Run EMUX!

Open a terminal, and start the emux-docker container:


You will be greeted with a purple shell prompt [EMUX-DOCKER 🐳:~$]. After a while, it is common to have many terminals attached to the container. Coloured shell prompts makes it easy to remember where you are.

Next, start the EMUX launcher:

[EMUX-DOCKER 🐳:~$] launcher

and select any emulated device that you wish to run.

Step 4 - Launch the emulated device's userland processes.

Next, open a new terminal and attach to the running emux-docker container:


All attached container shells have a blue shell prompt. Invoke the userspace command to bring up the userland processes of the emulated target:

[emux-docker shell 🐚:~$] userspace

Read the documentation for more details.



The EMUX Firmware Emulation Framework is a collection of scripts, kernels and filesystems to be used with QEMU to emulate ARM and MIPS Linux IoT devices. EMUX is aimed to facilitate IoT research by virtualising as much of the physical device as possible. It is the closest we can get to an actual IoT VM.

Devices successfully emulated with EMUX so far:

The following devices are not included with the public release, however they have been successfully emulated and used in training:

Precursors of EMUX have been used in Saumil Shah's popular ARM IoT Exploit Laboratory training classes where students have found four several 0-day vulnerabilities in various ARM/Linux IoT devices.

EMUX Architecture

EMUX is a collection of scripts, kernels and filesystems residing in the /emux directory. It uses qemu-system-arm, qemu-system-mips and qemu-system-mipsel to boot up virtual ARM and MIPS Linux environments. The /emux directory is exported over NFS to also make the contents available within the QEMU guest.

The host system running qemu-system-arm|mips|mipsel is assigned the IP address and the QEMU guest is assigned via tap0 interface.


EMUX is packaged as a Docker image. The diagram below shows how the docker container is organised:

Docker Architecture

The docker image consists of:

The /emux directory

The /emux directory is organised as follows:

Directory Structure

The run/ directory also contains a few commands that can be used from the host to interact with processes running within an EMUX emulated device.

emuxps, emuxmaps and emuxgdb are explained in detail in the Debugging With EMUX tutorial.

Contents of an emulated device

Each emulated device contains the following files/directories:

Running an emulated device in EMUX

The diagram below describes each stage of EMUX:

EMUX Operations

There are five steps in running an emulated device:

  1. Launcher - choose from a list of available emulated devices
  2. Select a device and boot its kernel and its hostfs
  3. Userspace - choose from a list of available userspace actions
  4. Start the devices' userspace processes
  5. Optionally drop into the hostfs shell

Step 1: The Launcher

Invoke launcher.

EMUX Launcher Command

This will display a menu as shown below. In this example, we select the Trivision TRI227WF Wireless IP Camera.

EMUX Launcher

Step 2: Start a device

Selecting one of the devices will launch it under QEMU. The kernel which is included in the kernel/ directory of the Trivision IP Camera's device configuration, is booted in qemu-system-arm and uses a pre-built Buildroot filesystem, which is referred to as hostfs.ext2. Host and guest IP addresses are assigned to and respectively.

EMUX Kernel Boot Up

hostfs-arm.ext2, hostfs-mips.ext2 and hostfs-mipsel.ext2 contain several scripts and tools useful for running and dynamic analysis of the emulated device. The init scripts in hostfs mount the /emux directory over NFS. Thus, the contents of /emux are shared by both the host and the QEMU guest.

Step 3: Userspace

You will need to attach to the running emux-docker container and invoke the userspace command at the shell prompt.

EMUX Userspace Command

Internally the userspace command simply connects to the QEMU guest using SSH ssh root@ This brings up a menu as shown below:

EMUX Trivision Init

Step 4: Start the userspace processes

Selecting the option to launch the userspace processes of the device results in run-init being invoked from the corresponding device configuration directory within /emux. First, the contents of nvram.ini are loaded into the kernel's emulated nvram driver. Next, a chroot jail is created using the rootfs of the device. Lastly, the registered initialisation commands are invoked in the newly chrooted rootfs, bringing up the device's services and init scripts.

EMUX Trivision Started

Step 5: Device booted up and ready

Once the device has fully "booted up" in EMUX, it is available for testing and analysis. The image below shows the administration interface of the IP Camera loaded in a browser. Note, to access the internal ports on we will rely on port forwarding performed by socat. By default, the following ports are forwarded:

localhost:20080 ->
localhost:20443 ->
localhost:28080 ->

To access the web administration interface for the booted up device, open a browser and navigate to localhost:28000. This in turn will forward your request to inside the emux-docker container.

EMUX Admin Interface

Overriding the forwarded ports

EMUX port forwarding is controlled by the PORTFWD environment variable. It is a comma separated list containing FORWARDED_PORT:INTERNAL_PORT pairs. To override the default port forwarding, simply set the contents of PORTFWD before invoking run-emux-docker:

export PORTFWD="28000:8000,25800:5800"

Creating your own emulated IoT Device

Before you begin to emulate an IoT device, you will need the following:

The following diagram outlines the overall process of IoT device emulation.

Adding a new device

Steps involved:

  1. Copy the template directory to make a new device configuration.
  2. Compile a matching kernel from source, and place it in the kernel/ directory. You may also symlink an existing kernel if you wish to.
  3. Copy the extracted rootfs from the device's firmware into the rootfs/ directory. Typically these would be SquashFS or CramFS filesystems, uncompressed using binwalk or unsquashfs or cramfsck. Optionally you may also create a compressed tar.bz2 archive of the root file system.
  4. Place the contents of extracted nvram in nvram.ini
  5. If you wish to emulate MTD flash, dump the contents of your device's flash memory and create two 64MB files named flash0.bin and flash1.bin and place them in the flashmem/ directory. Optionally you may also compress them in a tar.bz2 archive. You will then need to define the MTD partition layout to be passed to the kernel in the mtdparts file.
  6. Place any shared libraries that you wish to inject using LD_PRELOAD in the preload/ directory. Usually these shared libraries contain hooked functions necessary for certain emulated binaries to work properly.
  7. Edit the config file with the newly populated device firmware contents.
  8. Create a new device record in the devices-extra file. Pay close attention to QEMU command line options.

The following sample kernels are provided with the template.

However, it is encouraged to build a compatible kernel from source.

The EMUX Activity Log File

The June 2021 release of EMUX comes with a feature to enable activity logs. This comes in very handy in troubleshooting errors when adding a new device to EMUX. To enable logging, edit the /emux/debuglogs file:

# Uncomment logpath= to enable EMUX and QEMU console output logging.
# Only one logpath= should be uncommented.

It is recommended to use /home/r0/workspace/logs since the workspace directory is shared between the container and the host.

EMUX (ARMX) In The Public

Presentation at Countermeasure 2019 on 7 November 2019. 👇

INSIDE EMUX - Countermeasure 2019 from Saumil Shah

Release presentation at HITB+Cyberweek on 16 October 2019. 👇

Introducing EMUX from Saumil Shah

Announcing EMUX Docker on 15 June 2021. 👇

Announcing EMUX Docker - DC11332 from Saumil Shah

The ARM IoT Firmware Laboratory - NEW TRAINING

An all new class where the ARM IoT EXPLOIT LABORATORY leaves off. The ARM IoT Firmware Laboratory dives into analysis, extraction and emulation of IoT device firmware, using a variety of techniques. Students shall be given ample hands on practice in emulating a variety of IoT devices. Lab exercises feature firmware extraction directly from the hardware, building a custom kernel and buildroot environment, extracting contents of nvram and emulating the device under EMUX. The class also goes on to fuzzing and exploit development exercises for the emulated devices.

Upcoming classes:

Ringzer0 #VirtualVegas August 2021, Online Remote Training: (4 day class) https://ringzer0.training/arm-iot-exploitlab.html


The pre-built EMUX PREVIEW VM is now discontinued. You are encouraged to use EMUX on Docker


Github: https://github.com/therealsaumil/emux/

EMUX Documentation


EMUX is licensed under the Mozilla Public License v2.0 (MPLv2).