Capdis Disassembly Tool

600pages on
this wiki
Add New Page
Talk0 Share


capdis (short for CAPstone DISassembler) is a disassembly tool based on the capstone library, with features specifically supporting CHDK development. It is primarily intended for thumb2 / Digic 6 firmware, but can also be used on earlier ARM firmware or arbitrary ARM or thumb2 code.

The latest version is available in the CHDK tools directory.

Development thread


A patched version of capstone 3.0.4 is required. The official version contains a bug related to blx instruction alignment that has been fixed in later versions of capstone. However, other source adjustments are required to use the newer releases.

The patch & pre-built win32 library are available here :

For Linux, download source from the capstone download link , and then patch the source file ARMInstPrinter.c using the capstone-blx-align.patch file from the capstone-mingw-chdk download package (above). Follow the instructions in the capstone COMPILE.TXT file to build the source (essentially ./ and then sudo ./ install ). 

To build the CHDK capstone tools, the following should be set in your  Replace /path/to/capstone with the location where the capstone library is installed.

# Define this to enable building of tools using the capstone library (
# Required to rebuild stubs for thumb2 / digic 6 firmware
# Set the following if capstone includes are not in the default search path
# Set the following to the options required to link to the capstone library.
# At a minimum, -lcapstone or similar is required. If the library is not
# on the default search path, -L/path/to/capstone is also required
CAPSTONE_TOOLS_LINK=-L/path/to/capstone -lcapstone


  1. To manually build capdis support into the CHDK build, use make extras or make capdis (capdis.exe on windows) in the CHDK build tree tools directory.  If you have added OPT_CAPSTONE_TOOLS=1 to your this step is not necessary for simply building against the trunk.
  1. The current CHDK build process will produce a warning message ( WARNING! Incorrect dissassembly is likely ) if the blx instruction alignment bug has not been correctly patched. It is very easy to not notice this warning as it will be buried deep the build output log.
  2. Some Linux distros may include pre-compiled capstone packages. If it's the 3.0.4 version it will have the blx instruction alignment bug . If it's a later version then other source adjustments may be required. Building from source rather than relying on the distro's package is highly recommended.


capdis is a command line tool which disassembles a specified address range, with output in formats suitable for general reverse engineering or use in CHDK code. If invoked without any options, it prints a brief summary.

Options are specified like -x=value with no spaces.

To disassemble, you must specify

  • A start address, with -s=<numeric address or known function name> or -o=<byte offset from file start>
    • The lowest bit of the start address controls whether code is disassembled as ARM (LSB=0) or thumb (LSB=1). So to disassemble thumb2 code starting at 0xfc020000, you would use -s=0xfc020001
    • If RAM code regions are recognized (see stubs_entry.S generated by finsig_thumb2) you can disassemble code in those regions by passing addresses directly, e.g. -s=0x010e1001 to disassemble the start of RAM kernel code.
  • An end address or instruction count, with -e=<address> or -c=<count>
  • A file to dissemble, typically the PRIMARY.BIN for the camera you are working on.
  • The firmware start address (CHDK ROMBASEADDR)

Other useful options

  • The -stubs option allows CHDK "stubs" to be used to annotate known functions from stubs_entry.S, funcs_by_name.csv and stubs_entry_2.s. Running capdis from the root of your CHDK source, you would use something like -stubs=platform/g7x/sub/100d
    • Note that if stubs generation fails, the CHDK build process renames the stubs_entry.S file to stubs_entry.S.err. To allow it to be seen by capdis, you must rename it back to stubs_entry.S.
  • The -f option can is used to control the output format. Use -f=chdk to generate code suitable for inline assembly in CHDK. Use -f=objdump to output something roughly similar to GNU objdump / If neither is specified, the default is similar to capstone standard disassembly.

Disassembling a full firmware dumpEdit

To generate files suitable for reverse engineering, you can use the following procedure.

In the text below <camera> below refers to your platform name, e.g. g7x. <firmware> refers to your firmware version, e.g. 100d

Create an initial tree to generate stubsEdit

If you started your port by copying an existing port, you can skip this step, but you may need to adjust some of the values in your copied tree.

Set up a minimal platform tree, with platform/<camera> platform/<camera>/sub/<firmware>

Create platform/<camera>/, with at least the following values

PLATFORMOSVER=<DRYOS version number, does not need to be correct>
ROMBASEADDR=<your ROM base address, 0xFC000000 on known Digic 6>

Create platform/<camera>/sub/<firmware>/Makefile containing at least

include ../../../

Create platform/<camera>/sub/<firmware>/ (can be empty)

Generate stubsEdit


make PLATFORM=<camera> PLATFORMSUB=<firmware> rebuild-stubs

For a new port, this will fail because various functions are not found, but stubs_entry.S.err, funcs_by_name.csv etc should be created.

Rename stubs_entry.S.err to stubs_entry.S

Disassemble code regionsEdit

Known digic 6 firmwares have several code regions: The bootloader, the main ROM code and one or two regions which are copied to RAM (or ITCM) on startup. If your firmware is similar to known firmwares, these (except the bootloader) will be detected by finsig_thumb2, and noted in comments.

To disassemble RAM code, look in the "Detected address ranges section" for items listed as RAM code, and use the address range for start and end, like

tools/capdis platform/g9x/sub/101a/PRIMARY.BIN 0xfc000000 -stubs=platform/g9x/sub/101a -s=0x010e1001 -e=0x010fbd18 -f=objdump -d-const -d-addr -d-bin > platform/g9x/sub/101a/RAMCODE.DIS

To dissemble main ROM code, use the "Main firmware start" address as the start (with the thumb it set) and the address from the DEF(ctypes,...) line as the end, like

tools/capdis platform/g9x/sub/101a/PRIMARY.BIN 0xfc000000 -stubs=platform/g9x/sub/101a -s=0xfc020001 -e=0xfc6572ac -f=objdump -d-const -d-addr -d-bin > platform/g9x/sub/101a/ROMCODE.DIS

Note: disassembling a full ROM can take a long time, (up to a few hours on reasonably modern system), and the resulting file can be larger than 100MB

Disassembling code for CHDK sourceEdit

In CHDK, code for startup and various task hooks uses inline assembly generated from firmware code.

To generate this code, you can use capdis like

tools/capdis ../dumps/g7x/sub/100d/PRIMARY.BIN 0xFC000000 -stubs=platform/g7x/sub/100d -f=chdk -s=0xfc064301 -c=60

Wrapping this in a shell script can be more convenient, something like

capdis platform/$cam/sub/$sub/PRIMARY.BIN 0xfc000000 -stubs=platform/$cam/sub/$sub $*

Ad blocker interference detected!

Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.