(Some documentation for capdis) Tag: sourceedit |
(Move capstone documentation to main Digic 6 page) |
||
(13 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
=Introduction= |
=Introduction= |
||
− | capdis (short for CAPstone DISassembler) is disassembly tool based on the [http://www.capstone-engine.org/ 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. |
+ | capdis (short for CAPstone DISassembler) is a disassembly tool based on the [http://www.capstone-engine.org/ 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. |
The latest version is available in the CHDK tools directory. |
||
Line 7: | Line 7: | ||
=Building= |
=Building= |
||
+ | See the CHDK capstone tools section of [[Digic 6 Porting]]. |
||
− | 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 |
||
− | |||
− | <source lang="make"> |
||
− | # 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 |
||
− | </source> |
||
− | |||
− | 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. |
||
=Usage= |
=Usage= |
||
Line 36: | Line 14: | ||
Options are specified like -x=value with no spaces. |
Options are specified like -x=value with no spaces. |
||
− | To disassemble, you must specify |
+ | To disassemble, you must specify |
* A start address, with -s=<numeric address or known function name> or -o=<byte offset from file start> |
* 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 |
** 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 |
||
Line 45: | Line 23: | ||
Other useful options |
Other useful options |
||
− | * The - |
+ | * 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. |
+ | ** 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 / [[User:Srsa 4c/GPL:stubs2disv7.pl|stubs2disv7.pl]]. If neither is specified, the default is similar to capstone standard disassembly. |
* 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 / [[User:Srsa 4c/GPL:stubs2disv7.pl|stubs2disv7.pl]]. If neither is specified, the default is similar to capstone standard disassembly. |
||
Line 63: | Line 41: | ||
THUMB_FW=1 |
THUMB_FW=1 |
||
PLATFORMOS=dryos |
PLATFORMOS=dryos |
||
− | PLATFORMOSVER=<DRYOS version number, |
+ | PLATFORMOSVER=<DRYOS version number, does not need to be correct> |
ROMBASEADDR=<your ROM base address, 0xFC000000 on known Digic 6> |
ROMBASEADDR=<your ROM base address, 0xFC000000 on known Digic 6> |
||
</source> |
</source> |
||
Line 78: | Line 56: | ||
make PLATFORM=<camera> PLATFORMSUB=<firmware> rebuild-stubs |
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. |
+ | 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 |
Rename stubs_entry.S.err to stubs_entry.S |
||
Line 93: | Line 71: | ||
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 |
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''': |
+ | '''Note''': Disassembling a full ROM can take several minutes on a reasonably modern system, and the resulting file can be larger than 100MB |
=Disassembling code for CHDK source= |
=Disassembling code for CHDK source= |
Latest revision as of 20:24, 25 May 2019
Introduction
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.
Building
See the CHDK capstone tools section of Digic 6 Porting.
Usage
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 / stubs2disv7.pl. If neither is specified, the default is similar to capstone standard disassembly.
Disassembling a full firmware dump
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 stubs
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 stubs
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 regions
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 several minutes on a reasonably modern system, and the resulting file can be larger than 100MB
Disassembling code for CHDK source
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 $*