diff --git a/tests/fixtures.py b/tests/fixtures.py index 6d35485e..2bf81e67 100644 --- a/tests/fixtures.py +++ b/tests/fixtures.py @@ -363,8 +363,18 @@ def get_data_path_by_name(name) -> Path: / "data" / "dynamic" / "cape" + / "v2.2" / "0000a65749f5902c4d82ffa701198038f0b4870b00a27cfca109f8f933476d82.json.gz" ) + elif name.startswith("d46900"): + return ( + CD + / "data" + / "dynamic" + / "cape" + / "v2.2" + / "d46900384c78863420fb3e297d0a2f743cd2b6b3f7f82bf64059a168e07aceb7.json.gz" + ) elif name.startswith("ea2876"): return CD / "data" / "ea2876e9175410b6f6719f80ee44b9553960758c7d0f7bed73c0fe9a78d8e669.dll_" else: diff --git a/tests/test_main.py b/tests/test_main.py index da592dc4..d09f3397 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -6,8 +6,10 @@ # Unless required by applicable law or agreed to in writing, software distributed under the License # is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and limitations under the License. +import gzip import json import textwrap +from pathlib import Path import pytest import fixtures @@ -582,3 +584,59 @@ def test_main_rd(): assert capa.main.main([path, "-j"]) == 0 assert capa.main.main([path, "-q"]) == 0 assert capa.main.main([path]) == 0 + + +def extract_cape_report(tmp_path: Path, gz: Path) -> Path: + report = tmp_path / "report.json" + report.write_bytes(gzip.decompress(gz.read_bytes())) + return report + + +def test_main_cape1(tmp_path): + path = extract_cape_report(tmp_path, fixtures.get_data_path_by_name("0000a657")) + + # TODO(williballenthin): use default rules set + # https://github.com/mandiant/capa/pull/1696 + rules = tmp_path / "rules" + rules.mkdir() + (rules / "create-or-open-registry-key.yml").write_text( + textwrap.dedent( + """ + rule: + meta: + name: create or open registry key + authors: + - testing + scopes: + static: instruction + dynamic: call + features: + - or: + - api: advapi32.RegOpenKey + - api: advapi32.RegOpenKeyEx + - api: advapi32.RegCreateKey + - api: advapi32.RegCreateKeyEx + - api: advapi32.RegOpenCurrentUser + - api: advapi32.RegOpenKeyTransacted + - api: advapi32.RegOpenUserClassesRoot + - api: advapi32.RegCreateKeyTransacted + - api: ZwOpenKey + - api: ZwOpenKeyEx + - api: ZwCreateKey + - api: ZwOpenKeyTransacted + - api: ZwOpenKeyTransactedEx + - api: ZwCreateKeyTransacted + - api: NtOpenKey + - api: NtCreateKey + - api: SHRegOpenUSKey + - api: SHRegCreateUSKey + - api: RtlCreateRegistryKey + """ + ) + ) + + assert capa.main.main([str(path), "-r", str(rules)]) == 0 + assert capa.main.main([str(path), "-q", "-r", str(rules)]) == 0 + assert capa.main.main([str(path), "-j", "-r", str(rules)]) == 0 + assert capa.main.main([str(path), "-v", "-r", str(rules)]) == 0 + assert capa.main.main([str(path), "-vv", "-r", str(rules)]) == 0