-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
ZarKyo
committed
Aug 18, 2024
1 parent
ee8ac12
commit 05a7879
Showing
1 changed file
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import logging | ||
import json | ||
|
||
from regipy.exceptions import RegistryKeyNotFoundException | ||
from regipy.hive_types import NTUSER_HIVE_TYPE | ||
from regipy.plugins.plugin import Plugin | ||
from regipy.utils import convert_wintime | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
# Ressources : https://patrickwu.space/2020/07/19/wsl-related-registry/ | ||
|
||
WSL_PATH = r'\Software\Microsoft\Windows\CurrentVersion\Lxss' | ||
|
||
class WSLPlugin(Plugin): | ||
NAME = "wsl_plugin" | ||
DESCRIPTION = "Get WSL information" | ||
COMPATIBLE_HIVE = NTUSER_HIVE_TYPE | ||
|
||
def get_wls_info(self, subkey, distribs=None): | ||
if distribs is None: | ||
distribs = [] | ||
|
||
try: | ||
flags = subkey.get_value("Flags") | ||
state = subkey.get_value("State") | ||
version = subkey.get_value("Version") | ||
|
||
# Initialize the entry for a distribution with its GUID as the key | ||
distribution_entry = { | ||
"GUID": subkey.name, | ||
"last_modified": convert_wintime(subkey.header.last_modified, as_json=self.as_json), | ||
"wsl_distribution_source_location": subkey.get_value("BasePath"), | ||
"default_uid": subkey.get_value("DefaultUid"), | ||
"distribution_name": subkey.get_value("DistributionName"), | ||
"default_environment": subkey.get_value("DefaultEnvironment"), # REG_MULTI_SZ | ||
"flags": flags, | ||
"kernel_command_line": subkey.get_value("KernelCommandLine"), | ||
"package_family_name": subkey.get_value("PackageFamilyName"), | ||
"state": state, | ||
"filesystem": "lxfs" if version == 1 | ||
else "wslfs" if version == 2 | ||
else "Unknown", | ||
} | ||
|
||
# Decode flags for additional information | ||
if flags is not None: | ||
distribution_entry["enable_interop"] = bool(flags & 0x1) | ||
distribution_entry["append_nt_path"] = bool(flags & 0x2) | ||
distribution_entry["enable_drive_mounting"] = bool(flags & 0x4) | ||
|
||
# Decode the state of the distribution | ||
if state is not None: | ||
if state == 0x1: | ||
distribution_entry["state"] = "Normal" | ||
elif state == 0x3: | ||
distribution_entry["state"] = "Installing" | ||
elif state == 0x4: | ||
distribution_entry["state"] = "Uninstalling" | ||
else: | ||
distribution_entry["state"] = "Unknown" | ||
|
||
# Add the distribution entry with its GUID to the list of distributions | ||
distribs.append(distribution_entry) | ||
|
||
except Exception as e: | ||
logger.error(f"Error processing subkey {subkey.name}: {e}") | ||
raise | ||
|
||
return distribs | ||
|
||
def run(self): | ||
try: | ||
# Attempt to get the WSL registry key | ||
wsl_key = self.registry_hive.get_key(WSL_PATH) | ||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f"Registry key not found at path {WSL_PATH}: {ex}") | ||
return | ||
|
||
# Prepare the main JSON structure with the WSL path as the key | ||
self.entries = { | ||
WSL_PATH: { | ||
"last_modified": convert_wintime(wsl_key.header.last_modified, as_json=self.as_json), | ||
"number_of_distrib": wsl_key.header.subkey_count, | ||
"default_distrib_GUID": wsl_key.get_value("DefaultDistribution"), | ||
"wsl_version": "WSL1" if wsl_key.get_value("DefaultVersion") == 1 | ||
else "WSL2" if wsl_key.get_value("DefaultVersion") == 2 | ||
else "Unknown", | ||
"nat_ip_address": wsl_key.get_value("NatIpAddress"), | ||
"distributions": [] | ||
} | ||
} | ||
|
||
for distrib in wsl_key.iter_subkeys(): | ||
try: | ||
distribs = self.get_wls_info(distrib) | ||
self.entries[WSL_PATH]["distributions"] = distribs | ||
|
||
# Convert entries to JSON | ||
try: | ||
self.entries = json.dumps(self.entries, indent=3) # Convert to JSON with formatting | ||
except (TypeError, ValueError) as e: | ||
logger.error(f"Error serializing entries to JSON: {e}") | ||
raise # Re-raise the exception if serialization fails | ||
|
||
except RegistryKeyNotFoundException as ex: | ||
logger.error(f"Could not find registry key for distribution: {ex}") |