Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update rule format documentation with dynamic details #851

Merged
merged 15 commits into from
Nov 29, 2023
13 changes: 6 additions & 7 deletions doc/format.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ rule:
See how `create mutex` can be reasoned about both by inspecting the disassembly features (static analysis) as well as the runtime API trace (dynamic analysis)?

On the other hand, some behaviors are best described by rules that work in only one scope.
(Remember, its paramount that rules be human-readable, so avoid complicating logic for the sake of merging rules.)
Remember, its paramount that rules be human-readable, so avoid complicating logic for the sake of merging rules.
In this case, mark the excluded scope with `unsupported`, like in the following rule:

```yml
Expand All @@ -319,11 +319,11 @@ rule:
- match: contain loop
```

"check for software breakpoints" works great during disassembly analysis, such as mnemonic and operand matching, but doesn't work in dynamic scopes because these features aren't available. So, we mark the rule `scopes.dynamic: unsupported` so the rule won't be considered when processing sandbox traces.
`check for software breakpoints` works great during disassembly analysis, where low-level instruction features can be matched, but doesn't work in dynamic scopes because these features aren't available. Hence, we mark the rule `scopes.dynamic: unsupported` so the rule won't be considered when processing sandbox traces.

As you'll see in the [extracted features](#extracted-features) section, capa matches features at various scopes, starting small (e.g., instruction) and growing large (e.g., file). In static analysis, scopes grow from instruction, to basic block, function, and then file. In dynamic analysis, scopes from call, to thread, process, and then to file.
As you'll see in the [extracted features](#extracted-features) section, capa matches features at various scopes, starting small (e.g., `instruction`) and growing large (e.g., `file`). In static analysis, scopes grow from `instruction`, to `basic block`, `function`, and then `file`. In dynamic analysis, scopes grow from `call`, to `thread`, `process`, and then to `file`.

When matching a sequence of API calls, the static scope is often "function" and the dynamic scope is "thread". When matching a single API call with arguments, the static scope is usually "basic block" and the dynamic scope is "call". One day we hope to support "call" scope directly in the static analysis flavor.
When matching a sequence of API calls, the static scope is often `function` and the dynamic scope is `thread`. When matching a single API call with arguments, the static scope is usually `basic block` and the dynamic scope is `call`. One day we hope to support `call` scope directly in the static analysis flavor.


## features block
Expand Down Expand Up @@ -362,7 +362,7 @@ If only one of these features is found in a function, the rule will not match.

# extracted features

capa matches features at multiple scopes, starting small (e.g., instruction) and growing large (e.g., file). In static analysis, scopes grow from instruction, to basic block, function, and then file. In dynamic analysis, scopes from call, to thread, process, and then to file:
capa matches features at multiple scopes, starting small (e.g., `instruction`) and growing large (e.g., `file`). In static analysis, scopes grow from `instruction`, to `basic block`, `function`, and then `file`. In dynamic analysis, scopes grow from `call`, to `thread`, `process`, and then to `file`:

| scope | best for... |
|-------------|------------------------------------------------------------------------------------------|
Expand All @@ -376,7 +376,7 @@ capa matches features at multiple scopes, starting small (e.g., instruction) and
| process | combinations of other capabilities found within a (potentially multi-threaded) program |
| (common) | --- |
| file | high level conclusions, like encryptor, backdoor, or statically linked with some library |
| global | the features available at every scope, like arch or OS |
| global | the features available at every scope, like architechture or OS |
williballenthin marked this conversation as resolved.
Show resolved Hide resolved

In general, capa collects and merges the features from lower scopes into higher scopes;
for example, features extracted from individual instructions are merged into the function scope that contains the instructions.
Expand Down Expand Up @@ -758,7 +758,6 @@ Examples:
mnemonic: xor
mnemonic: shl


Example rule: [check for trap flag exception](../anti-analysis/anti-debugging/debugger-detection/check-for-trap-flag-exception.yml)

### operand
Expand Down