{0 cwe_checker} {1 Contents} - {!section:Basics} - {!section:CmdLineOptions} - {!section:ToolIntegration} - {!section:HackingHowto} {1:Basics Basic usage} {i cwe_checker} is implemented as a plugin for the {{: https://github.com/BinaryAnalysisPlatform/bap} Binary Analysis Platform} (BAP). To use it, just run BAP with {i cwe_checker} as a pass: {[bap [BINARY_FILE] --pass=cwe-checker]} This runs all static analysis based checks. You can find more documentation on these checks at their {{: ../cwe_checker_core/Cwe_checker_core/index.html} module documentation pages}. The behaviour of these checks can be modified through an optional configuration file. Just edit the [src/config.json] file and then add [--cwe-checker-config=src/config.json] as a command line option. You can find more on the available command line options {{!section:CmdLineOptions} here}. Alternatively, you can run the {i cwe_checker} through the command {[cwe_checker [BINARY_FILE] ]} Internally, this also calls BAP as above, but enables shorter {{!section:CmdLineOptions} command line options}. The symbolic execution based checks can be run with the emulation recipe in the recipes folder. {[bap PATH_TO_BINARY --recipe=recipes/emulation]} Note that these checks are rather slow at the moment and should only be applied to small binaries. {2 How to use the docker image} The docker image, which is based on the current master branch of the repository, can be installed with {[docker pull fkiecad/cwe_checker]} To use it, mount the target binary inside the docker container and call {i bap} with {i cwe_checker} as a pass as usual: {[docker run --rm -v [BINARY]:/tmp/input fkiecad/cwe_checker bap /tmp/input --pass=cwe-checker]} If you are using a customized [config.json] file, don't forget to mount it inside your container as well! If you want to print the output to a file with [--cwe-checker-out], you also need to mount the output file to the docker container, or else the file will be lost once the container gets destroyed. {1:CmdLineOptions Command line options} If you run the {i cwe_checker} as a BAP plugin, all command line options have to be prefixed with [--cwe-checker] (so that BAP knows to forward them to the {i cwe_checker} plugin). If you run the {i cwe_checker} directly, do not prefix the command line options. The available command line options are: - [-check-path] Find paths between input functions (configurable in the configuration file) and CWE hits. Should be used together with the [-partial] command line option if you are only interested in paths to specific CWEs. - [-config=[FILE]] Use [[FILE]] as the configuration file. If you omit this option, {i cwe_checker} uses a standard configuration file located at [src/config.json]. - [-module-versions] Prints the version numbers of each check. - [-json] Format the CWE-warnings as JSON. If you print to {i stdout}, note that debug, info and error messages are not formatted as JSON and may pollute the output. Use [-no-logging] to suppress these messages. - [-no-logging] Suppress printing of debug, info and error messages. This is useful if you want to print to {i stdout} with the [-json] flag to prevent these messages polluting the JSON output. - [-out=[FILE]] Print the CWE-warnings to the file located at [[FILE]]. Note that debug, info and error messages are still printed to stdout and not to the file. - [-partial=[MODULE_LIST]] Only run the checks given in [[MODULE_LIST]], where [[MODULE_LIST]] is a comma separated list of module names. E.g. [-partial=CWE190,CWE476] would only run the checks for CWE-190 and CWE-476. The names of all available modules can be printed with the [-module-versions] command line option. {1:ToolIntegration Integration with IDA Pro and Ghidra} To annotate CWE-hits in IDA Pro or Ghidra, first run {i cwe_checker} and save the JSON-formatted output to a file. {[bap [BINARY] --pass=cwe-checker --cwe-checker-json --cwe-checker-out=cwe_hits.json]} - For IDA Pro run the [cwe_checker_to_ida.py] script located in the [cwe_checker_to_ida] folder. {[python3 cwe_checker_to_ida.py -i cwe_hits.json -o cwe_hits.py]} Now open the binary file in IDA Pro and execute the generated [cwe_hits.py] script from within IDA Pro (Alt+F7). - For Ghidra copy the [cwe_checker_ghidra_plugin.py] script located in the [ghidra_plugin] folder into the script folder of Ghidra. Now open the binary in Ghidra and run the [cwe_checker_ghidra_plugin.py] script through the script manager and select the generated [cwe_hits.json] file when prompted. {1:HackingHowto How to write your own check} {2 Step 1: Get acquainted with BAP} {i cwe_checker} interfaces via OCaml with the {{: https://github.com/BinaryAnalysisPlatform/bap} Binary Analysis Platform} as a backend and you should read its documentation. All information about a binary file is gathered through BAP. {2 Step 2: Write the check} You need a [your_check.ml] and a [your_check.mli] file that should be located in the [src/checkers] folder. The [your_check.mli] file should look like this: {[ (** This module implements your_check. Some more documentation about your_check. *) val name : string (* The name of your check *) val version : string (* The version of your check (e.g. "0.1"). *) val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> string list -> unit ]} A corresponding example [your_check.ml] file, which just prints a "hello world" message, would look like this: {[ open Core_kernel open Bap.Std (* To interface with BAP *) let name = "your_check" let version = "0.1" let check_cwe program project tid_map symbol_pairs parameters = Log_utils.info "Hello world!" ]} In practice you would use the parameters of {i check_cwe}-function to gather the necessary information for the computation of your check. These parameters are: - [program: Bap.Std.program Bap.Std.term] The program term of the binary - [project: Bap.Std.project] The BAP-project term of the binary - [Tid_map: Bap.Std.word Bap.Std.Tid.Map.t] A map from the Tids of basic blocks to concrete addresses in the binary file - [symbols_pairs: string list list] Symbols read from the {i config.json} file - [parameters: string list] Parameters read from the config.json file The results of your check should be reported back to the user via the functions in the {{: ../cwe_checker_core/Cwe_checker_core/Log_utils/index.html} Log_utils}-module. See its module-level documentation for more details. {2 Step 3: Add your check to the {i cwe_checker} plugin} The main file of the {i cwe_checker} plugin is located at [plugins/cwe_checker/cwe_checker.ml]. In there you have to add your check to the list of {i known_modules}. Here the {i requires_pairs} flag controls whether the symbols in the [config.json] file are a string list or a list of string lists. The {i has_parameters} flag controls whether the [config.json] file contains parameters to control the behaviour of the check. Now just recompile {i cwe_checker} via [make all] and your check will be available for use.