Fandom

CHDK Wiki

Capdis Disassembly Tool

598pages on
this wiki
Add New Page
Talk0 Share

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.

IntroductionEdit

capdis (short for CAPstone DISassembler) is 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

BuildingEdit

A patched version of capstone 3.0.4 is required. The patch and pre-built win32 library are available from https://app.box.com/s/sshu7dv0mebvnee6gvpsex46y2m18w51

NOTE: The bug is fixed in later versions of capstone, but other source adjustments are required to use them.

To build the CHDK capstone tools, the following should be set in your localbuildconf.inc

# Define this to enable building of tools using the capstone library (http://www.capstone-engine.org/)
# Required to rebuild stubs for thumb2 / digic 6 firmware
OPT_CAPSTONE_TOOLS=1
 
# Set the following if capstone includes are not in the default search path
CAPSTONE_TOOLS_INC=-I/path/to/capstone/include
 
# 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

Replace /path/to/capstone with the location where the capstone library is installed.

To build capdis, make extras or capdis (capdis.exe on windows) in the tools directory.

UsageEdit

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 -s 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 -s=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 / stubs2disv7.pl. 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>/makefile.inc, with at least the following values

THUMB_FW=1
PLATFORMOS=dryos
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 ../../../makefile_sub.inc

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

Generate stubsEdit

Run

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

discam.sh:

#!/bin/bash
cam=$1
shift
sub=$1
shift
capdis platform/$cam/sub/$sub/PRIMARY.BIN 0xfc000000 -stubs=platform/$cam/sub/$sub $*

Also on Fandom

Random Wiki