Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion analyzer/windows/lib/api/process.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import urllib.error
import urllib.parse
import urllib.request
from ctypes import byref, c_buffer, c_int, c_ulong, create_string_buffer, sizeof, windll, ArgumentError
from ctypes import byref, c_buffer, c_int, c_ulong, create_string_buffer, sizeof, ArgumentError
from pathlib import Path
from shutil import copy

Expand All @@ -38,6 +38,7 @@
)

if sys.platform == "win32":
from ctypes import windll
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried to run some of these windows tests under linux, which isn't really a thing, but this helped (a bit)

from lib.common.constants import (
CAPEMON32_NAME,
CAPEMON64_NAME,
Expand Down
6 changes: 5 additions & 1 deletion analyzer/windows/lib/core/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ def choose_package(file_type, file_name, exports, target):
return "rar"
elif "Macromedia Flash" in file_type or file_name.endswith((".swf", ".fws")):
return "swf"
elif file_name.endswith((".py", ".pyc")) or "Python script" in file_type or b"import" in file_content:
elif (
file_name.endswith((".py", ".pyc"))
or "Python script" in file_type
or (file_content.startswith(b"#!/") and b"python" in file_content.split(b"\n", 1)[0])
):
return "python"
elif file_name.endswith(".ps1"):
return "ps1"
Expand Down
34 changes: 34 additions & 0 deletions analyzer/windows/tests/test_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ def test_prepare(self, set_lock, init_logging, config, pipeserver):


class TestAnalyzerChoosePackage(unittest.TestCase):
def setUp(self):
patch_process = patch("analyzer.Process")
self.mock_process = patch_process.start()
self.mock_process.return_value = MagicMock()
self.addCleanup(patch_process.stop)

def test_choose_package_shellcode(self):
test = analyzer.Analyzer()
test.config = MagicMock()
Expand Down Expand Up @@ -621,6 +627,34 @@ def test_choose_package_zip_compound(self):
self.assertEqual("modules.packages.zip_compound", pkg_name)
self.assertEqual(pkg_class.__class__.__name__, "ZipCompound")

def _assert_autodetected_package(self, file_name, expected_pkg_module, expected_pkg_class_name, file_type="ASCII text"):
"""Helper: auto-detect a package from a file in test_data and assert the result."""
file_path = os.path.join(os.path.dirname(__file__), "test_data", file_name)
test = analyzer.Analyzer()
test.config = MagicMock()
test.options = MagicMock()
test.config.package = ""
test.config.category = "file"
test.config.file_name = file_name
test.config.file_type = file_type
test.config.exports = ""
test.target = file_path
pkg_name, pkg_class = test.choose_package()
self.assertEqual(f"modules.packages.{expected_pkg_module}", pkg_name)
self.assertEqual(expected_pkg_class_name, pkg_class.__class__.__name__)

def test_choose_package_from_eml_file(self):
"""Auto-detect eml package by reading test_email.eml from test_data."""
self._assert_autodetected_package("test_email.eml", "eml", "EML")

def test_choose_package_from_python_py_file(self):
"""Auto-detect python package from test_python_file1.py via file extension."""
self._assert_autodetected_package("test_python_file1.py", "python", "Python")

def test_choose_package_from_python_data_file(self):
"""Auto-detect python package from test_python_file2.data via #!/usr/bin/env python in content."""
self._assert_autodetected_package("test_python_file2.data", "python", "Python")


class TestAnalyzerMonitoring(unittest.TestCase):
def setUp(self):
Expand Down
21 changes: 21 additions & 0 deletions analyzer/windows/tests/test_data/test_email.eml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Received: from bogus.com
Authentication-Results: spf=pass (sender IP is 1.2.3.4)
Received-SPF: Pass (protection.outlook.com: domain of bogus.com
Received: from bogus.bogus.com
Authentication-Results-Original: mx-bogus.com;
Date: Wed, 18 Mar 2026 09:59:38 +0000
From: "Alice Bogus" <alice@bogus.com>
Reply-To: "Alice Bogus" <alice@bogus.com>
To: <bob@bogus.com>
Message-ID: <12345@bogus.com>
Subject: Hi Bob

Hi Bob,

How's it going?

Did you import that file I sent you last week?
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made sure to include the word "import" in this email


Please let me know. Thanks.

Alice
10 changes: 10 additions & 0 deletions analyzer/windows/tests/test_data/test_python_file1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# sample file to test if python detection is working
import sys


def greet(name):
return f"Hello, {name}!"


if __name__ == "__main__":
print(greet(sys.argv[1] if len(sys.argv) > 1 else "world"))
9 changes: 9 additions & 0 deletions analyzer/windows/tests/test_data/test_python_file2.data
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python3
# sample file to test if python detection, based on first line of file
import hashlib

def compute_hash(data):
return hashlib.sha256(data.encode()).hexdigest()

if __name__ == "__main__":
print(compute_hash("cape"))
Loading