oinkie 0.7.0

Detects software theft by comparing birthmarks extracted from binaries
Documentation
# oinkie-cli

This directory contains the CLI interface of `oinkie` for extracting and comparing birthmarks and calculating similarities.

## 🏃 Usage

```sh
Detects software theft by comparing birthmarks extracted from binaries

Usage: oinkie [OPTIONS] <COMMAND>

Commands:
  info         Display information about the application
  lift         Lift binary files to JSON files of an intermediate representation, using a specified lifter
  extract      Extract birthmarks from a lifted binary file (JSON format)
  compare      Compare birthmarks and output the similarity score
  reaggregate  Reaggregate the element-wise similarity scores and recalculate the birthmark-wise similarity score
  stats        Summarise a set of birthmarks: how many of each type, how many functions each holds, and how long each function's birthmark is
  run          Extract birthmarks and compare them in one command
  mcp          Serve oinkie over the Model Context Protocol, on stdin and stdout
  help         Print this message or the help of the given subcommand(s)

Options:
  -l, --level <LEVEL>  Log level for the application [default: warn] [possible values: error, warn, info, debug, trace, off]
  -h, --help           Print help
  -V, --version        Print version
```

### `lift` command

This command lifts binary files into Oinkie-IR files (P-code JSON format), which are used as inputs for the `extract` command.

```sh
Lift binary files to JSON files of an intermediate representation, using a specified lifter

Usage: oinkie lift [OPTIONS] [FILES]...

Arguments:
  [FILES]...  Path to the binary or intermediate files to lift

Options:
  -d, --dest <DIRECTORY>           Specify the directory for putting the resultant JSON files of the lifted programs (default: './pcodes' directory) [default: pcodes]
  -r, --ir <IR>                    Intermediate representation to produce. This also picks the tool, since a representation is only produced by one of them; several representations can come from the same tool. [default: ghidra-pcode] [possible values: ghidra-pcode, ida-microcode, binary-ninja-llil, binary-ninja-mlil, binary-ninja-hlil]
  -H, --home <HOME>                Path to the installation directory of the tool behind --ir. If not specified, that tool's own environment variable (GHIDRA_HOME for Ghidra) is read, then the usual install locations are searched. The error names which variable to set.
  -i, --intermediate <DIRECTORY>   Directory for the lifter to work in, kept rather than discarded. Every lifter runs in one, since that is where its script writes; Ghidra also keeps its project there. If not specified, a temporary directory is used and deleted.
      --script <SCRIPT>            Path to a custom lifting script, replacing the built-in one. The language is that of the tool behind --ir: Java for Ghidra. It must write {input file name}.json into its working directory.
  -j, --jobs <N>                   Lift up to N files at a time (default: 1, one after another). Lifting runs a whole decompiler process per file, and several of them against a Ghidra installation whose language cache has not been built yet can corrupt it, so parallelism is opt-in. [default: 1]
  -S, --skip                       Skip if the resultant JSON file already exists
  -h, --help                       Print help
```

### `extract` command

This command extracts birthmarks from the given lifted binary files.
The lifted binary files are obtained by [`lift` command](#lift-command)

```sh
Extract birthmarks from a lifted binary file (JSON format)

Usage: oinkie extract [OPTIONS] [JSON_FILES]...

Arguments:
  [JSON_FILES]...  Path to the JSON files to extract birthmarks from

Options:
  -d, --dest <DIRECTORY>
          Specify the directory for putting the resultant JSON files for the extracted birthmarks (default: './birthmarks' directory) [default: birthmarks]
  -b, --birthmark-type <BIRTHMARK_TYPE>
          Type of birthmark to extract.
          fc (Function Calls) and op (Opcode) with set, seq, and freq variants are supported.
          For example, 'op-seq' extracts the sequence of operations as a birthmark,
          while 'fc-freq' extracts the frequency of function calls.
          k-grams are written with the k in the name: 'op-3gram-set'. Any k parses, not
          only the ones 'oinkie info' lists.
          The full birthmark types can be found by running 'oinkie info'. [default: op-seq]
  -S, --skip
          Skip the resultant birthmark file is already exists
  -h, --help
          Print help
```

### `compare` command

```sh
Compare birthmarks and output the similarity score

Usage: oinkie compare [OPTIONS] [JSON_FILES]...

Arguments:
  [JSON_FILES]...
          Path to the birthmark JSON files to compare

Options:
  -a, --algorithm <ALGORITHM>
          Specify the similarity calculation algorithm.

          Possible values:
          - cosine:           Cosine similarity based on term frequency vectors. Available: seq and freq
          - dice:             Dice coefficient. Available: seq, set and freq
          - euclidean:        Euclidean distance between term frequency vectors. Available: seq and freq
          - jaccard:          Jaccard index. Available: seq, set and freq
          - levenshtein:      Levenshtein distance. Available: seq
          - lcs:              Longest Common Subsequence (LCS). Available: seq
          - simpson:          Simpson's coefficient. Available: seq, set and freq
          - weighted-jaccard: Weighted Jaccard index based on term frequency vectors. Available: seq and freq
          
          [default: jaccard]

  -A, --aggregator <METHOD>
          Specify the aggregator for combining element-wise similarity scores into a birthmark-wise similarity score.
          Available:
          - hungarian  Use the Hungarian algorithm to find the optimal matching between elements of two birthmarks,
                       maximizing the total similarity score.
          - topn:N     For each element in the first birthmark, consider only the top N most similar elements in the
                       second birthmark when calculating the overall similarity score. This can reduce noise from less
                       relevant matches and focus on the most significant similarities.
          
          [default: hungarian]

  -s, --strategy <STRATEGY>
          Specify the pairing strategy for comparing files.

          Possible values:
          - all-and-self:    All possible combinations including self-comparisons ($_nC_2 + n$). Used for full matrix visualization or comprehensive heatmaps
          - all:             Compares all possible combinations ($_nC_2$). Used for comprehensive validation of accuracy (False Positive / True Positive)
          - self-coverage:   Compares each file with itself ($n$). Used for sanity checks to ensure identical files yield a similarity score of 1.0
          - adjacent:        Compares only adjacent pairs in the list ($n-1$). Useful for comparing sequential versions (e.g., v1.0 vs v1.1, v1.1 vs v1.2)
          - first-vs-others: Compares a specific reference file against all other files ($n-1$). Compares first item and all other items. Useful for comparing a baseline version against multiple variants
          - last-vs-others:  Compares a specific reference file against all other files ($n-1$). Compares the last item and all other items. Useful for comparing a baseline version against multiple variants
          
          [default: all-and-self]

  -d, --dest <DIRECTORY>
          Specify the destination directory for the comparing results
          
          [default: similarities]

  -S, --skip
          Skip if the similarity file already exists for the pair of birthmarks

  -h, --help
          Print help (see a summary with '-h')
```

### `reaggregate` command

Reaggregate the element-wise similarity scores and recalculate the birthmark-wise similarity score.

```sh
Reaggregate the element-wise similarity scores and recalculate the birthmark-wise similarity score

Usage: oinkie reaggregate [OPTIONS] <SCORE_DIRECTORY>

Arguments:
  <SCORE_DIRECTORY>  Path to the directory containing the element-wise similarity scores

Options:
  -A, --aggregator <METHOD>     Specify the aggregator for combining element-wise similarity scores into a birthmark-wise similarity score.
                                Available:
                                - hungarian  Use the Hungarian algorithm to find the optimal matching between elements of two birthmarks,
                                             maximizing the total similarity score.
                                - topn:N     For each element in the first birthmark, consider only the top N most similar elements in the
                                             second birthmark when calculating the overall similarity score. This can reduce noise from less
                                             relevant matches and focus on the most significant similarities. [default: hungarian]
  -d, --dest-file <RESULT.CSV>  Specify the result CSV file of the comparing results to reaggregate.
                                The file contains the birthmark-wise similarity score list. [default: reaggregate.csv]
  -h, --help                    Print help
```

### `stats` command

Summarise a set of birthmarks. A birthmark file holds one entry per **function**, and each function's birthmark is made of **elements**; the command reports functions per file and elements per function (the birthmark length) for each group of birthmarks sharing an intermediate representation and a type.

```sh
Summarise a set of birthmarks: how many of each type, how many functions each holds, and how long each function's birthmark is

Usage: oinkie stats [OPTIONS] <PATHS>...

Arguments:
  <PATHS>...
          Birthmark files, or directories holding them. A directory contributes the *.json directly inside it;
          a file that does not read as a birthmark is skipped with a warning and counted.

Options:
  -f, --format <FORMAT>
          Output format

          Possible values:
          - json:     Every table at once: the summary, the per-file rows and the skipped files
          - csv:      One table: the summary, or the per-file rows with --per-file, or the most frequent elements with --top
          - markdown: Tables to read, or to paste into a paper
          
          [default: markdown]

  -o, --output <FILE>
          Write the statistics to FILE rather than to standard output

  -r, --recursive
          Descend into the subdirectories of the given directories

      --per-file
          Report each birthmark file as well as each group. With -f csv this replaces the summary table.

  -t, --top <N>
          Report the N most frequent elements of each group. With -f csv this replaces the summary table.

  -h, --help
          Print help (see a summary with '-h')
```

### `run` command

```sh
Extract birthmarks and compare them in one command

Usage: oinkie run [OPTIONS] [FILES]...

Arguments:
  [FILES]...
          Path to the JSON files

Options:
  -a, --analysis <ANALYSIS>
          Analysis to run, as '{birthmark}-{algorithm}' -- for example 'op-set-jaccard' or 'op-3gram-freq-cosine'.
          Run 'oinkie info' for the birthmarks and the algorithms they pair with. Any k
          parses in a k-gram name, not only the ones listed.
          
          [default: op-set-jaccard]

  -s, --strategy <STRATEGY>
          Pairing strategy for file comparisons

          Possible values:
          - all-and-self:    All possible combinations including self-comparisons ($_nC_2 + n$). Used for full matrix visualization or comprehensive heatmaps
          - all:             Compares all possible combinations ($_nC_2$). Used for comprehensive validation of accuracy (False Positive / True Positive)
          - self-coverage:   Compares each file with itself ($n$). Used for sanity checks to ensure identical files yield a similarity score of 1.0
          - adjacent:        Compares only adjacent pairs in the list ($n-1$). Useful for comparing sequential versions (e.g., v1.0 vs v1.1, v1.1 vs v1.2)
          - first-vs-others: Compares a specific reference file against all other files ($n-1$). Compares first item and all other items. Useful for comparing a baseline version against multiple variants
          - last-vs-others:  Compares a specific reference file against all other files ($n-1$). Compares the last item and all other items. Useful for comparing a baseline version against multiple variants
          
          [default: all-and-self]

  -d, --dest <DEST>
          Destination path for the output CSV file (default: 'similarities' directory
          
          [default: similarities]

  -A, --aggregator <METHOD>
          Specify the aggregator for combining element-wise similarity scores into a birthmark-wise similarity score.
          Available:
          - hungarian  Use the Hungarian algorithm to find the optimal matching between elements of two birthmarks,
                       maximizing the total similarity score.
          - topn:N     For each element in the first birthmark, consider only the top N most similar elements in the
                       second birthmark when calculating the overall similarity score. This can reduce noise from less
                       relevant matches and focus on the most significant similarities. available topn:N or topn:all (same as topn).
          
          [default: hungarian]

  -S, --skip
          Skip if the similarity file already exists for the pair of birthmarks

  -h, --help
          Print help (see a summary with '-h')
```

### `mcp` command

Serves the pipeline over the Model Context Protocol, on stdin and stdout, so an
agent can drive it. Behind the `mcp` cargo feature; the released binaries and
both container images are built with it.

```sh
Serve oinkie over the Model Context Protocol, on stdin and stdout

Usage: oinkie mcp [OPTIONS]

Options:
  -r, --root <DIRECTORY>  Directory the tools may read and write under. May be given more than once.
                          Every path a tool is handed, input and output alike, has to resolve inside one of
                          these; anything else is refused. Defaults to the working directory.
                          The paths the tools receive are written by a language model rather than by you,
                          which is the whole reason this exists.
  -h, --help              Print help
```

The tools it offers, how to configure a client, and why lifting is not among
them are in [`mcp/README.md`](mcp/README.md).