add scripts showing conversion to/from protobuf format

This commit is contained in:
Willi Ballenthin 2023-03-23 10:58:22 +01:00
parent 49ff9d5a7c
commit 80112bac64
2 changed files with 160 additions and 0 deletions

View file

@ -0,0 +1,75 @@
#!/usr/bin/env python
"""
Copyright (C) 2023 Mandiant, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at: [package root]/LICENSE.txt
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.
proto-from-results-json.py
Convert a JSON result document into the protobuf format.
Example:
$ capa --json foo.exe > foo.json
$ python proto-from-results.py foo.json | hexyl | head
00000000 0a d4 05 0a 1a 32 30 32 33 2d 30 32 2d 31 30 20 _._2023-02-10
00000010 31 31 3a 34 39 3a 35 32 2e 36 39 33 34 30 30 12 11:49:52.693400
00000020 05 35 2e 30 2e 30 1a 34 74 65 73 74 73 2f 64 61 5.0.04tests/da
00000030 74 61 2f 50 72 61 63 74 69 63 61 6c 20 4d 61 6c ta/Practical Mal
00000040 77 61 72 65 20 41 6e 61 6c 79 73 69 73 20 4c 61 ware Analysis La
00000050 62 20 30 31 2d 30 31 2e 64 6c 6c 5f 1a 02 2d 6a b 01-01.dll_-j
00000060 22 c4 01 0a 20 32 39 30 39 33 34 63 36 31 64 65 ".•_ 290┊934c61de│
00000070 39 31 37 36 61 64 36 38 32 66 66 64 64 36 35 66 9176ad682ffdd65f
00000080 30 61 36 36 39 12 28 61 34 62 33 35 64 65 37 31 0a669(a4b35de71
"""
import sys
import logging
import argparse
import capa.render.proto
import capa.render.result_document
logger = logging.getLogger("capa.proto-from-results-json")
def main(argv=None):
if argv is None:
argv = sys.argv[1:]
parser = argparse.ArgumentParser(description="Convert a capa JSON result document into the protobuf format")
parser.add_argument("json", type=str, help="path to JSON result document file, produced by `capa --json`")
logging_group = parser.add_argument_group("logging arguments")
logging_group.add_argument("-d", "--debug", action="store_true", help="enable debugging output on STDERR")
logging_group.add_argument(
"-q", "--quiet", action="store_true", help="disable all status output except fatal errors"
)
args = parser.parse_args(args=argv)
if args.quiet:
logging.basicConfig(level=logging.WARNING)
logging.getLogger().setLevel(logging.WARNING)
elif args.debug:
logging.basicConfig(level=logging.DEBUG)
logging.getLogger().setLevel(logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
logging.getLogger().setLevel(logging.INFO)
rd = capa.render.result_document.ResultDocument.parse_file(args.json)
pb = capa.render.proto.doc_to_pb2(rd)
sys.stdout.buffer.write(pb.SerializeToString(deterministic=True))
sys.stdout.flush()
if __name__ == "__main__":
sys.exit(main())

View file

@ -0,0 +1,85 @@
#!/usr/bin/env python
"""
Copyright (C) 2023 Mandiant, Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at: [package root]/LICENSE.txt
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.
proto-to-results-json.py
Convert a protobuf result document into the JSON format.
Example:
$ capa --json foo.exe > foo.json
$ python proto-from-results.py foo.json > foo.pb
$ python proto-to-results.py foo.pb | jq . | head
1 {
2 "meta": {
3 "analysis": {
4 "arch": "i386",
5 "base_address": {
6 "type": "absolute",
7 "value": 268435456
8 },
9 "extractor": "VivisectFeatureExtractor",
10 "feature_counts": {
"""
import sys
import logging
import argparse
import capa.render.json
import capa.render.proto
import capa.render.proto.capa_pb2
import capa.render.result_document
logger = logging.getLogger("capa.proto-to-results-json")
def main(argv=None):
if argv is None:
argv = sys.argv[1:]
parser = argparse.ArgumentParser(description="Convert a capa protobuf result document into the JSON format")
parser.add_argument(
"pb", type=str, help="path to protobuf result document file, produced by `proto-from-results.py`"
)
logging_group = parser.add_argument_group("logging arguments")
logging_group.add_argument("-d", "--debug", action="store_true", help="enable debugging output on STDERR")
logging_group.add_argument(
"-q", "--quiet", action="store_true", help="disable all status output except fatal errors"
)
args = parser.parse_args(args=argv)
if args.quiet:
logging.basicConfig(level=logging.WARNING)
logging.getLogger().setLevel(logging.WARNING)
elif args.debug:
logging.basicConfig(level=logging.DEBUG)
logging.getLogger().setLevel(logging.DEBUG)
else:
logging.basicConfig(level=logging.INFO)
logging.getLogger().setLevel(logging.INFO)
with open(args.pb, "rb") as f:
pb = f.read()
rdpb = capa.render.proto.capa_pb2.ResultDocument()
rdpb.ParseFromString(pb)
rd = capa.render.proto.doc_from_pb2(rdpb)
print(rd.json(exclude_none=True, indent=2, sort_keys=True))
if __name__ == "__main__":
sys.exit(main())