# Scripting

Malcat features powerful python bindings which gives users access to most of the analysis result in a pythonic way. The bindings described below are available for the anomalies (cf. Anomaly scanner), for the summary templates (`data/templates`) and for user scripts (`data/scripts`) unless specified differently. Malcat python bindings also allow you to edit the file, add comments, define functions … basically everything you can do using the GUI.

## How to script

### Run a script from the user interface

Using Malcat’s built-in Script editor, you can edit and run python scripts against the currently analyzed file. If you open the Script editor using `F8`, it will display by default a toy script which will show you some basic usage of the bindings. The editor is based on Scintilla (like Notepad++).

The script editor window

Running a python script within the editor makes your life a bit easier, since your scripts will have directly access to a global varible named `analysis`. This variable contains the analysis result for the currently displayed file. So you won’t have to open a file and analyse it, it’s already done! Additionally, running a script from the editor offers two more advantages:

- it has access to Additional GUI bindings which offer additional ways to interact with the GUI (like progress report, or opening new files in the GUI)

- the script output window can display formated text with colors and clickable addresses (cf. `malcat.UI.print()`)

### Run Malcat from your python interpreter

With version 0.9.3 we have bundled Malcat’s binary analysis into a python module. The module is available in Full & Pro versions. Using the module you can use all Malcat’s analyses without having to run the GUI (aka headless scripting). That’s the way to go if you want to process large amount of files. Note that there are Legal restrictions when using the python module.

Using the python module

#### Setup

Malcat python module is located inside the `<malcat install dir>/bin` directory. In order to use the module from one of your python scripts, you have to make sure that it can be seen and imported by the python interpreter. There are three ways to achieve this:

- Put your script inside `<malcat install dir>/bin`

- Add `<malcat install dir>/bin` to `sys.path` before importing the Malcat module

- Install the module into your (virtual) environment using the script `<malcat install dir>/install_api.py` [PREFERRED]

The later option is the preferred way, as it makes Malcat available to your scripts from everywhere. The script `<malcat install dir>/install_api.py` let you install the API in either your root python environment, your user environment or the current virtual environment.

    $ python install_api.py --help
     Usage: install_api.py

     Install Malcat's module to your python (virtual) environment. This needs to be
     done only once (per environment). The script also allows you to
     activate/register Malcat on this computer if needed.

     Options:
       -h, --help            show this help message and exit
       -s, --silent          Non-interactive, use this option when running from
                             scripts
       -u, --uninstall       Uninstall Malcat
       -r, --install-on-root
                             Target is the system python environment
       -e, --install-on-pyenv
                             Target is the current python virtual environment
       -c LICENSE_KEY_OR_ACTIVATION_CODE, --code=LICENSE_KEY_OR_ACTIVATION_CODE
                             License key OR activation code to use for Malcat
                             activation (if needed). If not specified, will be
                             prompted from command line.
       -a, --activate-only   Don't install the API, only activate an already
                             installed Malcat
       -n, --no-activate     Don't check if malcat is activated or not, only
                             install

Note

The script will only add the directory `<malcat install dir>/bin` to the python’s environment, Malcat’s python module will not be copied over.

The script `install_api.py` also offers you to activate Malcat for you on this computer using either:

- A license key (will perform an online activation)

- An activation code (if the server is offline, see Activate the software)

The code can be given on the command line using the `-c` option. If not specified, the activation code / license will be asked interactively at run time.

Warning

In headless mode, Malcat’s data directories, bindings directories and your user data directory are not accessible by default (they are if you run scripts from within Malcat’s GUI). If you want to access python code there from your script (e.g. calling Malcat’s transforms), you will need to call the function `setup()` just after importing malcat:

    import malcat
    malcat.setup()  # Add Malcat's bindings + data directories to sys.path when called in headless mode
    from transforms.block import AesDecrypt  # <-- this is now valid

#### Usage

Using malcat as a python module, you will have to start the analysis yourself using one of the following prototypes of the `malcat.analyse()` method (which are is available when you Run a script from the user interface):

malcat.analyse(path_to_file, options={}, use_file_mapping=False)

  open a new file on disk and run all analyses. The set of analyses that will be computed can be modified using the options dictionnary. Return a `malcat.Analysis` instance on success, throws an exception on failure.

  Parameters:

    - path_to_file (str) – path to the file to be analyzed

    - options (dict) – options to customize the analysis (see below)

    - use_file_mapping (bool) – if True, will mmap() the file instead of opening it (cf. Big file mode)

  Return type:

    malcat.Analysis

malcat.analyse(buffer, options={}, nice_name='<user buffer>')

  open a new file from a memory buffer and run all analyses. The set of analyses that will be computed can be modified using the options dictionnary. Return a `malcat.Analysis` instance on success, throws an exception on failure.

  Parameters:

    - buffer (bytes) – the file data

    - options (dict) – options to customize the analysis (see below)

    - nice_name (str) – the (arbitrary) `malcat.File.name` that will be given to the file

  Return type:

    malcat.Analysis

malcat.analyse(malcat_file, options={})

  open a file and run all analyses. The set of analyses that will be computed can be modified using the options dictionnary. Return a `malcat.Analysis` instance on success, throws an exception on failure.

  Parameters:

    - malcat_file (malcat.File) – the file

    - options (dict) – options to customize the analysis (see below)

  Return type:

    malcat.Analysis

The returned `malcat.Analysis` object is the same object you get when you Run a script from the user interface. Analyses can be customized using the `options` dictionnary. The options that you can change there are the same that you can find in the option dialog: Edit‣Preferences‣Analysis Setup (cf. Changing options). Most of them revolve around disabling part of the analysis, in order to save CPU time and/or memory space:

##### Analysis options

Name | Type | Description
--- | --- | ---
invalidate_cache | bool | If set to False, Malcat won’t reload its internal DBs (kesakode, yara, constants, flirt, etc.) for subsequent analyses, saving lots of time
num_threads | int | Maximum number of threads to use for the analysis. If not specified, the default is to use the number of cores of your CPU.
filetype_force | str | You can force a given parser to be applied by setting this option to e.g. “PE” or “ZIP”. This should be the name attribute of the parser class (cf. Writing new parsers)
architecture_force | int | Force the given CPU architecture to be used. Use the integer value of the enum `malcat.Architecture`. Overrides wht the file parser suggests.
imagebase_force | int | Force the imagebase (i.e. the virutal address at which the file should be mapped in memory) to be the given address. Overrides wht the file parser suggests.
cons_disable | bool | Don’t run the Constant scanner (`malcat.Analysis.constants` will be empty)
flirt_disable | bool | Don’t apply FLIRT signatures
sign_disable | bool | Don’t scan for Yara signatures (`malcat.Analysis.sigs` will be empty)
anom_disable | bool | Don’t run the Anomaly scanner (`malcat.Analysis.anomalies` will be empty)
loop_disable | bool | Don’t run the Strongly Connected Components discovery (`malcat.Analysis.loops` will be empty)
stack_disable | bool | Don’t run the stack analysis for PYC/.NET files
cfg_disable | bool | Don’t perform any CFG / functions recovery (`malcat.Analysis.cfg` will be empty)
cfg_disable_markov | bool | Don’t use markov models to refine the CFG / functions recovery (`cfg_disable` must be set to False)
cfg_disable_linear_sweep | bool | Don’t try to scan for standard function prolog patterns during the CFG / functions recovery (`cfg_disable` must be set to False)
cfg_disable_coderef_sweep | bool | Don’t follow code references during the CFG / functions recovery (`cfg_disable` must be set to False)
cfg_disable_dataref_sweep | bool | Don’t follow data references during the CFG / functions recovery (`cfg_disable` must be set to False)
func_disable | bool | Don’t perform any /analysis/functions (`malcat.Analysis.fns` will be empty)
str_disable | bool | Don’t do any String analysis (`malcat.Analysis.strings` will be empty)
str_minsize | int | Minimal string size for the linear sweep string scanner
subf_disable | bool | Don’t perform any File carving (`malcat.Analysis.carved` will be empty)
dbg_disable | bool | Don’t extract debug metadata (it also includes python and .NET method detection)
xref_disable | bool | Don’t run the /analysis/xref (`malcat.Analysis.xref` will be empty)
etpy_disable | bool | Don’t run the Entropy computation (`malcat.Analysis.entropy` will be empty). Disabling this will also disable md5/sha1/sha256 computation
etpy_resolution | int | Grain (i.e. window size) for the Entropy computation (defaults to 512)

#### Legal restrictions when using the python module

If you own a named license, which is the case if you bought a Full & Pro versions, the license is bound to you and only you. As stipulated in the EULA, it means that you cannot rent or make the software available to other users. This includes the integration of the python module into any user-facing program and/or service. Here are some examples of what you may or may not do with your personal license:

- OK: You are a SOC analyst. You’ve made a script to assist you in your job which automatically updates your incident tickets with information coming from Malcat. This fits within the bounds of a named license.

- Not OK: You are a SOC analyst. You’ve made a script that automatically updates all incident tickets of your SOC with information coming from Malcat and integrated it in the SOC stack of your company. This is assimilated to sharing the software with other users.

- OK: You are a security/academical researcher and used Malcat’s python module and its CFG reconstruction to analyse large batch of files and do machine-learning detection. You have published the result of your research online. This all fits within the bounds of a named license.

- Not OK: You are a security/academical researcher and used Malcat’s python module and its CFG reconstruction to analyse large batch of files and do machine-learning detection. You have additionally made a online service where users can scan their files online using your technology. This also assimilated to sharing the software with other users.

No trick there, this is merely common sense. If you want to integrate Malcat in a multi-user software and/or online service, you can Contact us and we will work a OEM license out. Don’t worry, chances are it will be much cheaper than the concurrence.

## Available objects

### Base objects

- Analysis object (analysis)
- File object (analysis.file)
- Address mapping (analysis.map)

### Data analysis

- File structures (analysis.struct)
- File entropy (analysis.entropy)
- Strings (analysis.strings)
- Cross References (analysis.xrefs)

### Code analysis

- Disassembly (analysis.asm)
- Control Flow Graph (analysis.cfg)
- Strongly Connected Components (analysis.loops)
- Functions (analysis.fns)
- Symbols (analysis.syms)
- Cross References (analysis.xrefs)

### Sub-files

- Carved files (analysis.carved)
- Virtual files (analysis.vfiles)

### Scanners

- Known constants (analysis.constants)
- Yara signatures (analysis.sigs)
- Anomalies (analysis.anomalies)
- Kesakode

### User annotations

- User comments (analysis.comments)
- User highlighted regions (analysis.highlights)

### Index

- Index