Skip to content

Commit d55bb10

Browse files
committed
vt scan experiment
1 parent 7408bfa commit d55bb10

File tree

5 files changed

+86
-4
lines changed

5 files changed

+86
-4
lines changed

.github/workflows/build.yml

+13-3
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ jobs:
4040
# set to false to clear any cache in case of build errors
4141
cache: false
4242

43+
- name: Setup Python
44+
uses: actions/setup-python@v4
45+
with:
46+
python-version: '3.11'
47+
48+
- name: Install Python dependencies
49+
run: pip install -r requirements.txt
50+
working-directory: scripts
51+
4352
- name: ⚙️ configure
4453
run: >
4554
cmake -B build -S .
@@ -60,9 +69,9 @@ jobs:
6069
run: cpack -C ${{ env.BUILD_TYPE }}
6170
working-directory: build
6271

63-
- name: debug
64-
run: ls -R
65-
working-directory: build
72+
# - name: debug
73+
# run: ls -R
74+
# working-directory: build
6675

6776
# creates "atf" subdir and put the following:
6877
# 1. msi installer, renamed after version number
@@ -74,6 +83,7 @@ jobs:
7483
cp build/bt.msi atf/${{ env.MSI_FILE_NAME }}
7584
Compress-Archive -Path build/bt/Release/bt.exe -DestinationPath atf/${{ env.ZIP_FILE_NAME }} -CompressionLevel Optimal
7685
Compress-Archive -Path build/bt/Release/bt.pdb -DestinationPath atf/${{ env.PDB_FILE_NAME }} -CompressionLevel Optimal
86+
python scripts/vt_scan.py --files atf/${{ env.ZIP_FILE_NAME }} atf/${{ env.MSI_FILE_NAME }} --md-output atf/vt.md
7787
"${{ env.VERSION }}" | Out-File atf/version.txt -NoNewline
7888
(Get-FileHash -Algorithm SHA256 -Path atf/${{ env.ZIP_FILE_NAME }}).Hash | Out-File atf/${{ env.ZIP_FILE_NAME }}.sha256.txt
7989
(Get-FileHash -Algorithm SHA256 -Path atf/${{ env.MSI_FILE_NAME }}).Hash | Out-File atf/${{ env.MSI_FILE_NAME }}.sha256.txt

.github/workflows/release.yml

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ jobs:
4444
bin/*.sha256.txt
4545
body_path: final_notes.md
4646

47+
# update_release_body does not actually work, i'll revisit how to do it automatically later
4748
- name: VirusTotal Scan
4849
uses: crazy-max/ghaction-virustotal@v4
4950
with:

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ build/
55
bin/
66
obj/
77
vcpkg_installed/
8-
btcheck-cppcheck-build-dir/
8+
btcheck-cppcheck-build-dir/
9+
*.iml

scripts/requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
vt-py==0.17.5
2+
rich==13.5.3

scripts/vt_scan.py

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import rich.progress
2+
import os
3+
import argparse
4+
import glob
5+
import hashlib
6+
from rich.progress import Progress
7+
from vt.client import Client
8+
from vt.error import APIError
9+
from dataclasses import dataclass
10+
11+
@dataclass
12+
class ScanResult:
13+
file_path: str
14+
file_name: str
15+
sha256: str
16+
web_url: str
17+
18+
def scan_file(vt: Client, path: str, progress: rich.progress.Progress) -> ScanResult:
19+
with open(path, "rb", buffering=0) as f:
20+
sha256 = hashlib.file_digest(f, "sha256").hexdigest()
21+
progress.console.print(sha256)
22+
23+
# get info or scan
24+
try:
25+
vt.get_object(f"/files/{sha256}")
26+
except APIError:
27+
vt.scan_file(f)
28+
29+
return ScanResult(path,
30+
os.path.split(path)[1],
31+
sha256,
32+
f"https://www.virustotal.com/gui/file/{sha256}?nocache=1")
33+
34+
35+
if __name__ == "__main__":
36+
# parse input args
37+
parser = argparse.ArgumentParser("VT Scanner")
38+
parser.add_argument("--files", nargs="*")
39+
parser.add_argument("--md-output")
40+
args, _ = parser.parse_known_args()
41+
input_file_globs = args.files
42+
input_files = []
43+
for ifg in input_file_globs:
44+
for input_file in glob.glob(ifg):
45+
input_files.append(input_file)
46+
47+
print(f"files to scan: {input_files}")
48+
49+
api_key = os.getenv("VT_API_KEY")
50+
client = Client(api_key)
51+
results = []
52+
53+
with Progress() as progress:
54+
file_task = progress.add_task("Processing files...", total=len(input_files))
55+
for input_file in input_files:
56+
results.append(scan_file(client, input_file, progress))
57+
progress.update(file_task, advance=1)
58+
59+
# generate markdown
60+
if args.md_output:
61+
smd = ["## 🛡️ VirusTotal Analysis", "" ]
62+
for result in results:
63+
smd.append(f"\n - [{result.file_name}]({result.web_url})")
64+
65+
with open(args.md_output, "w", encoding="utf-8") as f:
66+
f.writelines(smd)
67+
68+
client.close()

0 commit comments

Comments
 (0)