Exeprotector/machine_code.py
2025-09-05 11:52:34 +08:00

281 lines
9.8 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
作者:太一
微信taiyi1224
邮箱shoubo1224@qq.com
"""
import hashlib
import platform
import subprocess
import sys
import uuid
def get_windows_machine_code():
"""获取Windows系统的机器码"""
try:
# 尝试获取主板序列号
try:
wmic_output = subprocess.check_output(
'wmic baseboard get serialnumber',
shell=True,
stderr=subprocess.STDOUT,
timeout=10
).decode().strip()
if "SerialNumber" in wmic_output:
lines = [line.strip() for line in wmic_output.split("\n") if line.strip()]
if len(lines) > 1:
serial = lines[1]
if serial and serial not in ["To Be Filled By O.E.M.", "Default string", "N/A", ""]:
return hashlib.md5(serial.encode()).hexdigest()[:16].upper()
except:
pass
# 尝试获取硬盘序列号
try:
wmic_output = subprocess.check_output(
'wmic diskdrive get serialnumber',
shell=True,
stderr=subprocess.STDOUT,
timeout=10
).decode().strip()
if "SerialNumber" in wmic_output:
lines = [line.strip() for line in wmic_output.split("\n") if line.strip()]
for line in lines[1:]: # 跳过标题行
if line and line not in ["", "N/A"]:
return hashlib.md5(line.encode()).hexdigest()[:16].upper()
except:
pass
# 尝试获取CPU序列号
try:
wmic_output = subprocess.check_output(
'wmic cpu get processorid',
shell=True,
stderr=subprocess.STDOUT,
timeout=10
).decode().strip()
if "ProcessorId" in wmic_output:
lines = [line.strip() for line in wmic_output.split("\n") if line.strip()]
if len(lines) > 1:
cpu_id = lines[1]
if cpu_id and cpu_id != "":
return hashlib.md5(cpu_id.encode()).hexdigest()[:16].upper()
except:
pass
# 尝试获取BIOS序列号
try:
wmic_output = subprocess.check_output(
'wmic bios get serialnumber',
shell=True,
stderr=subprocess.STDOUT,
timeout=10
).decode().strip()
if "SerialNumber" in wmic_output:
lines = [line.strip() for line in wmic_output.split("\n") if line.strip()]
if len(lines) > 1:
bios_serial = lines[1]
if bios_serial and bios_serial not in ["To Be Filled By O.E.M.", "Default string", "N/A", ""]:
return hashlib.md5(bios_serial.encode()).hexdigest()[:16].upper()
except:
pass
# 组合多个系统信息生成唯一标识
try:
# 获取网卡MAC地址
mac = uuid.getnode()
mac_str = ':'.join(['{:02x}'.format((mac >> elements) & 0xff) for elements in range(0, 2 * 6, 2)][::-1])
# 获取计算机名
computer_name = platform.node()
# 获取系统信息
system_info = f"{platform.system()}-{platform.release()}-{platform.version()}"
# 组合信息
combined_info = f"{mac_str}-{computer_name}-{system_info}"
return hashlib.md5(combined_info.encode()).hexdigest()[:16].upper()
except Exception as e:
# 最后的备用方案
fallback = f"{platform.uname()}-{uuid.getnode()}"
return hashlib.md5(fallback.encode()).hexdigest()[:16].upper()
except Exception as e:
print(f"获取Windows机器码错误: {e}")
# 生成一个基于系统信息的备用哈希
try:
fallback = f"{platform.node()}-{uuid.getnode()}-{platform.processor()}"
return hashlib.md5(fallback.encode()).hexdigest()[:16].upper()
except:
# 终极备用方案
import time
fallback = f"FALLBACK-{int(time.time())}-{platform.system()}"
return hashlib.md5(fallback.encode()).hexdigest()[:16].upper()
def get_linux_machine_code():
"""获取Linux系统的机器码"""
try:
# 尝试读取machine-id
try:
with open('/etc/machine-id', 'r') as f:
machine_id = f.read().strip()
if machine_id and len(machine_id) > 10:
return machine_id[:16].upper()
except:
pass
# 尝试读取/var/lib/dbus/machine-id
try:
with open('/var/lib/dbus/machine-id', 'r') as f:
machine_id = f.read().strip()
if machine_id and len(machine_id) > 10:
return machine_id[:16].upper()
except:
pass
# 尝试获取主板信息
try:
with open('/sys/class/dmi/id/board_serial', 'r') as f:
board_serial = f.read().strip()
if board_serial and board_serial not in ["", "N/A", "To be filled by O.E.M."]:
return hashlib.md5(board_serial.encode()).hexdigest()[:16].upper()
except:
pass
# 尝试获取产品UUID
try:
with open('/sys/class/dmi/id/product_uuid', 'r') as f:
product_uuid = f.read().strip()
if product_uuid and product_uuid != "":
return hashlib.md5(product_uuid.encode()).hexdigest()[:16].upper()
except:
pass
# 获取MAC地址和主机名组合
mac = uuid.getnode()
mac_str = ':'.join(['{:02x}'.format((mac >> elements) & 0xff) for elements in range(0, 2 * 6, 2)][::-1])
hostname = platform.node()
combined = f"{mac_str}-{hostname}"
return hashlib.md5(combined.encode()).hexdigest()[:16].upper()
except Exception as e:
print(f"获取Linux机器码错误: {e}")
# 备用方案
system_info = f"{platform.node()}-{uuid.getnode()}-{platform.machine()}"
return hashlib.md5(system_info.encode()).hexdigest()[:16].upper()
def get_mac_machine_code():
"""获取macOS系统的机器码"""
try:
# 尝试获取硬件UUID
try:
result = subprocess.check_output(
['system_profiler', 'SPHardwareDataType'],
stderr=subprocess.STDOUT,
timeout=10
).decode().strip()
for line in result.split('\n'):
if 'Hardware UUID' in line:
uuid_part = line.split(':')[1].strip()
return hashlib.md5(uuid_part.encode()).hexdigest()[:16].upper()
except:
pass
# 尝试获取序列号
try:
serial = subprocess.check_output(
['system_profiler', 'SPHardwareDataType', '|', 'grep', 'Serial'],
shell=True,
stderr=subprocess.STDOUT,
timeout=10
).decode().strip()
if serial:
serial_number = serial.split(':')[1].strip()
return hashlib.md5(serial_number.encode()).hexdigest()[:16].upper()
except:
pass
# 备用方案
mac = uuid.getnode()
hostname = platform.node()
combined = f"{mac}-{hostname}-{platform.machine()}"
return hashlib.md5(combined.encode()).hexdigest()[:16].upper()
except Exception as e:
print(f"获取macOS机器码错误: {e}")
# 备用方案
system_info = f"{platform.node()}-{uuid.getnode()}-{platform.machine()}"
return hashlib.md5(system_info.encode()).hexdigest()[:16].upper()
def get_machine_code():
"""获取当前系统的机器码"""
try:
system = platform.system()
if system == "Windows":
return get_windows_machine_code()
elif system == "Linux":
return get_linux_machine_code()
elif system == "Darwin": # macOS
return get_mac_machine_code()
else:
# 未知系统,使用通用方法
system_info = f"{platform.node()}-{uuid.getnode()}-{platform.processor()}-{platform.machine()}"
return hashlib.md5(system_info.encode()).hexdigest()[:16].upper()
except Exception as e:
print(f"获取机器码失败: {e}")
# 终极备用方案
try:
fallback = f"{platform.system()}-{uuid.getnode()}-{platform.node()}"
return hashlib.md5(fallback.encode()).hexdigest()[:16].upper()
except:
import time
ultimate_fallback = f"MACHINE-{int(time.time())}"
return hashlib.md5(ultimate_fallback.encode()).hexdigest()[:16].upper()
def format_machine_code(machine_code):
"""格式化机器码为更易读的格式"""
if len(machine_code) >= 16:
# 将16位机器码格式化为 XXXX-XXXX-XXXX-XXXX
return f"{machine_code[:4]}-{machine_code[4:8]}-{machine_code[8:12]}-{machine_code[12:16]}"
else:
return machine_code
def verify_machine_code(stored_code, current_code):
"""验证机器码是否匹配"""
# 移除格式化字符进行比较
stored_clean = stored_code.replace('-', '').upper()
current_clean = current_code.replace('-', '').upper()
return stored_clean == current_clean
if __name__ == "__main__":
print("机器码生成器测试")
print("-" * 30)
machine_code = get_machine_code()
formatted_code = format_machine_code(machine_code)
print(f"系统: {platform.system()} {platform.release()}")
print(f"原始机器码: {machine_code}")
print(f"格式化机器码: {formatted_code}")
print(f"机器码长度: {len(machine_code)}")
# 测试验证功能
print(f"\n验证测试: {verify_machine_code(formatted_code, machine_code)}")
input("\n按回车键退出...")