mirror of
https://github.com/outbackdingo/Hardware-Sniffer.git
synced 2026-01-27 02:19:00 +00:00
253 lines
12 KiB
Python
Executable File
253 lines
12 KiB
Python
Executable File
# -*- coding: utf-8 -*-
|
|
|
|
from Scripts import github
|
|
from Scripts import resource_fetcher
|
|
from Scripts import run
|
|
from Scripts import utils
|
|
import os
|
|
import platform
|
|
import tempfile
|
|
import shutil
|
|
import traceback
|
|
import sys
|
|
|
|
os_name = platform.system()
|
|
|
|
class HardwareSniffer:
|
|
def __init__(self, result_dir="SysReport", rich_format=True):
|
|
self.github = github.Github()
|
|
self.fetcher = resource_fetcher.ResourceFetcher()
|
|
self.run = run.Run().run
|
|
self.u = utils.Utils(rich_format=rich_format)
|
|
self.temporary_dir = tempfile.mkdtemp()
|
|
self.result_dir = result_dir
|
|
|
|
if os_name == "Windows":
|
|
from Scripts.platforms.windows import WindowsHardwareInfo
|
|
self.hardware_info = WindowsHardwareInfo(rich_format=rich_format)
|
|
else:
|
|
raise NotImplementedError(f"Unsupported operating system: {os_name}")
|
|
|
|
def generate_summary_view(self):
|
|
data = self.hardware_info.result.copy()
|
|
summary = [""]
|
|
|
|
if "Motherboard" in data and data["Motherboard"]:
|
|
mobo_name = data["Motherboard"].get("Name", "N/A")
|
|
chipset = data["Motherboard"].get("Chipset", "N/A")
|
|
summary.append("Motherboard: {} ({})".format(mobo_name, chipset))
|
|
|
|
if "BIOS" in data and data["BIOS"]:
|
|
bios_version = data["BIOS"].get("Version", "N/A")
|
|
bios_release_date = data["BIOS"].get("Release Date", "N/A")
|
|
system_type = data["BIOS"].get("System Type", "N/A")
|
|
firmware_type = data["BIOS"].get("Firmware Type", "N/A")
|
|
secure_boot = data["BIOS"].get("Secure Boot", "N/A")
|
|
summary.append("BIOS: {} ({}), {}, {}, {} Secure Boot".format(bios_version, bios_release_date, system_type, firmware_type, secure_boot.lower()))
|
|
|
|
if "CPU" in data and data["CPU"]:
|
|
cpu_name = data["CPU"].get("Processor Name", "N/A")
|
|
cpu_name = cpu_name[:36] + "..." if len(cpu_name) > 36 else cpu_name
|
|
codename = data["CPU"].get("Codename", "N/A")
|
|
summary.append("CPU: {} ({})".format(cpu_name, codename))
|
|
|
|
if "GPU" in data and data["GPU"]:
|
|
for index, (gpu_name, gpu_data) in enumerate(data["GPU"].items(), start=1):
|
|
codename = gpu_data.get("Codename", "N/A")
|
|
gpu_name = gpu_name[:36] + "..." if len(gpu_name) > 36 else gpu_name
|
|
summary.append("GPU {}: {} ({})".format(index, gpu_name, codename))
|
|
if "Monitor" in data and data["Monitor"]:
|
|
monitors = {monitor_name: monitor_data for monitor_name, monitor_data in data["Monitor"].items() if monitor_data.get("Connected GPU") == gpu_name}
|
|
if monitors:
|
|
summary.append(" Monitors: {}".format(", ".join(
|
|
[
|
|
"{} ({}, {})".format(monitor_name, monitor_data.get("Connector Type", "N/A"), monitor_data.get("Resolution", "N/A"))
|
|
for monitor_name, monitor_data in monitors.items()
|
|
]
|
|
)))
|
|
|
|
if "Network" in data and data["Network"]:
|
|
for index, (network_name, network_data) in enumerate(data["Network"].items(), start=1):
|
|
bus_type = network_data.get("Bus Type", "N/A")
|
|
device_id = network_data.get("Device ID", "N/A")
|
|
network_name = network_name[:36] + "..." if len(network_name) > 36 else network_name
|
|
summary.append("Network {}: {} ({}, {})".format(index, network_name, bus_type, device_id))
|
|
|
|
if "Sound" in data and data["Sound"]:
|
|
for index, (sound_name, sound_data) in enumerate(data["Sound"].items(), start=1):
|
|
bus_type = sound_data.get("Bus Type", "N/A")
|
|
device_id = sound_data.get("Device ID", "N/A")
|
|
audio_endpoints = sound_data.get("Audio Endpoints", [])
|
|
summary.append("Sound {}: {} ({}, {})".format(index, sound_name, bus_type, device_id))
|
|
if audio_endpoints:
|
|
summary.append(" Audio Endpoints: {}".format(", ".join(audio_endpoints)))
|
|
|
|
if "USB Controllers" in data and data["USB Controllers"]:
|
|
for index, (usb_controller_name, usb_controller_data) in enumerate(data["USB Controllers"].items(), start=1):
|
|
bus_type = usb_controller_data.get("Bus Type", "N/A")
|
|
device_id = usb_controller_data.get("Device ID", "N/A")
|
|
usb_controller_name = usb_controller_name[:36] + "..." if len(usb_controller_name) > 36 else usb_controller_name
|
|
summary.append("USB Controller {}: {} ({}, {})".format(index, usb_controller_name, bus_type, device_id))
|
|
|
|
if "Input" in data and data["Input"]:
|
|
for index, (input_name, input_data) in enumerate(data["Input"].items(), start=1):
|
|
bus_type = input_data.get("Bus Type", "N/A")
|
|
device_id = input_data.get("Device ID", "N/A")
|
|
input_name = input_name[:36] + "..." if len(input_name) > 36 else input_name
|
|
summary.append("Input {}: {} ({}, {})".format(index, input_name, bus_type, device_id))
|
|
|
|
if "Storage Controllers" in data and data["Storage Controllers"]:
|
|
for index, (storage_controller_name, storage_controller_data) in enumerate(data["Storage Controllers"].items(), start=1):
|
|
bus_type = storage_controller_data.get("Bus Type", "N/A")
|
|
device_id = storage_controller_data.get("Device ID", "N/A")
|
|
disk_drives = storage_controller_data.get("Disk Drives", [])
|
|
storage_controller_name = storage_controller_name[:36] + "..." if len(storage_controller_name) > 36 else storage_controller_name
|
|
summary.append("Storage Controller {}: {} ({}, {})".format(index, storage_controller_name, bus_type, device_id))
|
|
if disk_drives:
|
|
summary.append(" Disk Drives: {}".format(", ".join(disk_drives)))
|
|
|
|
if "Biometric" in data and data["Biometric"]:
|
|
for index, (biometric_name, biometric_data) in enumerate(data["Biometric"].items(), start=1):
|
|
device_id = biometric_data.get("Device ID", "N/A")
|
|
biometric_name = biometric_name[:36] + "..." if len(biometric_name) > 36 else biometric_name
|
|
summary.append("Biometric {}: {} ({})".format(index, biometric_name, device_id))
|
|
|
|
if "Bluetooth" in data and data["Bluetooth"]:
|
|
for index, (bluetooth_name, bluetooth_data) in enumerate(data["Bluetooth"].items(), start=1):
|
|
bus_type = bluetooth_data.get("Bus Type", "N/A")
|
|
device_id = bluetooth_data.get("Device ID", "N/A")
|
|
bluetooth_name = bluetooth_name[:36] + "..." if len(bluetooth_name) > 36 else bluetooth_name
|
|
summary.append("Bluetooth {}: {} ({}, {})".format(index, bluetooth_name, bus_type, device_id))
|
|
|
|
if "SD Controller" in data and data["SD Controller"]:
|
|
for index, (sd_controller_name, sd_controller_data) in enumerate(data["SD Controller"].items(), start=1):
|
|
bus_type = sd_controller_data.get("Bus Type", "N/A")
|
|
device_id = sd_controller_data.get("Device ID", "N/A")
|
|
sd_controller_name = sd_controller_name[:36] + "..." if len(sd_controller_name) > 36 else sd_controller_name
|
|
summary.append("SD Controller {}: {} ({}, {})".format(index, sd_controller_name, bus_type, device_id))
|
|
|
|
return "\n".join(summary)
|
|
|
|
def export_hardware_report(self):
|
|
self.u.head("Exporting Hardware Report")
|
|
print("")
|
|
|
|
try:
|
|
self.u.create_folder(self.result_dir)
|
|
|
|
self.report_path = os.path.join(self.result_dir, "Report.json")
|
|
|
|
self.u.write_file(self.report_path, self.hardware_info.result)
|
|
print("Report saved to `{}`".format(self.report_path))
|
|
except Exception as e:
|
|
print(f"Error exporting report: {e}", file=sys.stderr)
|
|
traceback.print_exc()
|
|
|
|
print("")
|
|
|
|
def get_latest_acpidump(self):
|
|
return "https://github.com/acpica/acpica/releases/download/R2024_12_12/acpidump.exe"
|
|
|
|
latest_release = self.github.get_latest_release("acpica", "acpica") or {}
|
|
|
|
for asset in latest_release.get("assets"):
|
|
if asset.get("product_name") == "acpidump":
|
|
return asset.get("url")
|
|
|
|
return None
|
|
|
|
def check_acpidump(self):
|
|
acpidump_path = os.path.join(os.getcwd(), "acpidump.exe")
|
|
|
|
if os.path.exists(acpidump_path):
|
|
return acpidump_path
|
|
|
|
self.u.head("Gathering Files")
|
|
print("")
|
|
print("Please wait for download acpidump...")
|
|
|
|
acpidump_download_link = self.get_latest_acpidump()
|
|
if not acpidump_download_link:
|
|
raise Exception("Could not find download URL for acpidump.exe.")
|
|
|
|
try:
|
|
self.fetcher.download_and_save_file(acpidump_download_link, acpidump_path)
|
|
|
|
if not os.path.exists(acpidump_path):
|
|
raise Exception("Failed to download acpidump.exe.")
|
|
except:
|
|
raise Exception("Could not locate or download acpidump.exe!\n\nPlease manually download acpidump.exe from:\n - {}\n\nAnd place in:\n - {}\n".format(
|
|
"https://github.com/acpica/acpica/releases",
|
|
os.path.dirname(os.path.realpath(__file__))
|
|
))
|
|
|
|
shutil.rmtree(self.temporary_dir, ignore_errors=True)
|
|
|
|
return acpidump_path
|
|
|
|
def dump_acpi_tables(self):
|
|
if os_name == "Windows":
|
|
acpidump_path = self.check_acpidump()
|
|
|
|
acpi_dir = os.path.join(self.result_dir, "ACPI")
|
|
self.u.create_folder(acpi_dir, remove_content=True)
|
|
|
|
self.u.head("Dumping ACPI Tables")
|
|
print("")
|
|
|
|
if os_name == "Windows":
|
|
print("Dumping tables to {}...".format(acpi_dir))
|
|
|
|
cwd = os.getcwd()
|
|
os.chdir(acpi_dir)
|
|
out = self.run({
|
|
"args":[acpidump_path, "-b"]
|
|
})
|
|
os.chdir(cwd)
|
|
if out[2] != 0:
|
|
print(" - {}".format(out[1]))
|
|
return
|
|
print("Updating names...")
|
|
|
|
table_paths = self.u.find_matching_paths(acpi_dir, extension_filter=".dat")
|
|
for path, type in table_paths:
|
|
try:
|
|
os.rename(os.path.join(acpi_dir, path), os.path.join(acpi_dir, path[:-4] + ".aml"))
|
|
except Exception as e:
|
|
print(" - {} -> {} failed: {}".format(os.path.basename(path), os.path.basename(path)[:-4] + ".aml", e))
|
|
|
|
print("")
|
|
print("ACPI tables dumped successfully.")
|
|
print("")
|
|
|
|
def main(self):
|
|
self.hardware_info.hardware_collector()
|
|
|
|
while True:
|
|
contents = []
|
|
contents.append("")
|
|
contents.append("Your hardware details:")
|
|
contents.append(self.generate_summary_view())
|
|
contents.append("")
|
|
contents.append("H. Export hardware report")
|
|
contents.append("A. Dump ACPI Tables")
|
|
contents.append("")
|
|
contents.append("Q. Quit")
|
|
contents.append("")
|
|
content = "\n".join(contents)
|
|
|
|
self.u.adjust_window_size(content)
|
|
self.u.head("Hardware Sniffer", resize=False)
|
|
print(content)
|
|
option = self.u.request_input("Please make a selection: ")
|
|
if option.lower() == "q":
|
|
self.u.exit_program()
|
|
elif option.lower() == "h":
|
|
self.export_hardware_report()
|
|
self.u.request_input()
|
|
elif option.lower() == "a":
|
|
self.dump_acpi_tables()
|
|
self.u.request_input()
|
|
|
|
if __name__ == '__main__':
|
|
HardwareSniffer().main() |