-
Notifications
You must be signed in to change notification settings - Fork 615
Description
Summary
I want to be able to statically use the api
feature for dynamically resolved function pointers, via GetProcAddress
or dlsym
.
Motivation
While working on mandiant/capa-rules#1046, I ran into a limitation where I couldn't precisly examine calls to NtFsControlFile
because that function is commonly dynamically resolved at runtime via GetProcAddress
(examples from 7d333c9b11b06ef0982b61bfc062631bb6cf9d12d0d4f2cf1b807a25ddf62fbc)
IDA has special handling for auto-renaming pointers in .data when they are set via GetProcAddress. It would be very useful to be able to have a similar capability in capa so we can precisely inspect calls through static capa executions to dynamically resolved functions.
Additionally, it would be an added bonus to have a way to explicitly look for (or not for) dynamically resolved functions. Maybe something like:
# only match on NtFsControlFile calls going to .data
- api: NtFsControlFile
- runtime_resolved: true
# only match on calls to CreateProcessA going to .idata
- api: CreateProcessA
- runtime_resolved: false
# if not specified, do both
- api: CloseHandle
This feature could be supported on Linux as well by looking at dlsym
calls
Describe alternatives you've considered
The workaround I did in mandiant/capa-rules#1046 was to just inspect how the arguments are set up for the NtFsControlFile calls we are interested in, and then look for a call. I'm not sure how accurate/precise this will be in practice though:
features:
- and:
- os: windows
- or:
- number: 0x11003c
- number: 0x110038
- number: 0x119ff8
- instruction:
- mnemonic: xor
- instruction:
- mnemonic: call
- not:
- characteristic: nzxor
Additional context
n/a