Loading a VXWorks image

Warning

Loading VXWorks images requires a license to Binary Ninja Ultimate. Because not all users may have this, by default it is disabled.

In this tutorial, you will be guided through loading a VXWorks file.

To enable Binary Ninja integration for VXWorks support, first place the Binary Ninja Ultimate zip file in the project root of the SmallWorld repository as binaryninja_linux_stable_ultimate.zip.

Since Nix flakes require files to be tracked in git to be included in the build, add the zip file to git (does not need to be committed): .. code-block:: bash

git add binaryninja_linux_stable_ultimate.zip

In the flake.nix, ensure the following lines are uncommented to include Binary Ninja: .. code-block:

binaryninja = {
  url = "github:jchv/nix-binary-ninja";
  inputs.nixpkgs.follows = "nixpkgs";
};

binjaZip = {
  url = "path:./binaryninja_linux_stable_ultimate.zip";
  flake = false;
};

Then, re-run the Nix flake build to include Binary Ninja Ultimate support.

It is important to know VXWorks files can differ based on VXWorks version and specific compiler options. For this example, we will use a VXWorks binary published in the vxhunter github repository. :ref: https://github.com/PAGalaxyLab/vxhunter/tree/master/example_firmware

In most cases, we will not have access to the source code of the VXWorks binary. This applies for this tutorial as well, but we will focus on the loading process.

In order to aid analysis of our VXWorks binary, we want to find the symbol table. Vector35 details the heuristics Binary Ninja uses to find the symbol table in their blog here: :ref: https://binary.ninja/2024/10/31/introducing-vxworks.html.

Using the VXWorks loader

SmallWorld includes a model of the basic features of a VXWorks loader. To exercise it, you will need to use Executable.from_vxworks(), described in Memory Objects.

Unlike other executable formats, VXWorks images do not have standardized metadata to specify base addresses or load addresses. However, Binary Ninja can attempt to infer the address. In some cases, this may be incorrect. If the user chooses to manually specify a load address, SmallWorld will prefer the user’s input over Binary Ninja’s heuristic.

filepath = "path/to/image_vx6_arm_little_endian.bin"
with open(filepath, "rb") as f:
    code = smallworld.state.memory.code.Executable.from_vxworks(f)
    machine.add(code)