113 lines
3.2 KiB
Python
113 lines
3.2 KiB
Python
# -*- coding: utf-8 -*-#
|
|
# -------------------------------------------------------------------------------
|
|
# Name: utils.py
|
|
# Description:
|
|
# Author: xaoyaoo
|
|
# Date: 2023/12/25
|
|
# -------------------------------------------------------------------------------
|
|
import os
|
|
import re
|
|
import hmac
|
|
import sys
|
|
import traceback
|
|
import hashlib
|
|
if sys.platform == "win32":
|
|
from win32com.client import Dispatch
|
|
else:
|
|
Dispatch = None
|
|
|
|
def info_error(func):
|
|
"""
|
|
错误处理装饰器
|
|
:param func:
|
|
:return:
|
|
"""
|
|
def wrapper(*args, **kwargs):
|
|
try:
|
|
return func(*args, **kwargs)
|
|
except Exception as e:
|
|
traceback_data = traceback.format_exc()
|
|
rdata = f"{traceback_data}"
|
|
print(f"info_error: \n{rdata}")
|
|
return "None"
|
|
return wrapper
|
|
|
|
|
|
def verify_key(key, wx_db_path):
|
|
"""
|
|
验证key是否正确
|
|
"""
|
|
KEY_SIZE = 32
|
|
DEFAULT_PAGESIZE = 4096
|
|
DEFAULT_ITER = 64000
|
|
with open(wx_db_path, "rb") as file:
|
|
blist = file.read(5000)
|
|
salt = blist[:16]
|
|
pk = hashlib.pbkdf2_hmac("sha1", key, salt, DEFAULT_ITER, KEY_SIZE)
|
|
first = blist[16:DEFAULT_PAGESIZE]
|
|
mac_salt = bytes([(salt[i] ^ 58) for i in range(16)])
|
|
pk = hashlib.pbkdf2_hmac("sha1", pk, mac_salt, 2, KEY_SIZE)
|
|
hash_mac = hmac.new(pk, first[:-32], hashlib.sha1)
|
|
hash_mac.update(b'\x01\x00\x00\x00')
|
|
if hash_mac.digest() != first[-32:-12]:
|
|
return False
|
|
return True
|
|
|
|
@info_error
|
|
def get_exe_version(file_path):
|
|
"""
|
|
获取 PE 文件的版本号
|
|
:param file_path: PE 文件路径(可执行文件)
|
|
:return: 如果遇到错误则返回
|
|
"""
|
|
if not os.path.exists(file_path):
|
|
return "None"
|
|
file_version = Dispatch("Scripting.FileSystemObject").GetFileVersion(file_path)
|
|
return file_version
|
|
|
|
|
|
def find_all(c: bytes, string: bytes, base_addr=0):
|
|
"""
|
|
查找字符串中所有子串的位置
|
|
:param c: 子串 b'123'
|
|
:param string: 字符串 b'123456789123'
|
|
:return:
|
|
"""
|
|
return [base_addr + m.start() for m in re.finditer(re.escape(c), string)]
|
|
|
|
|
|
def get_exe_bit(file_path):
|
|
"""
|
|
# 获取exe文件的位数
|
|
PE 文件的位数: 32 位或 64 位
|
|
:param file_path: PE 文件路径(可执行文件)
|
|
:return: 如果遇到错误则返回 64
|
|
"""
|
|
try:
|
|
with open(file_path, 'rb') as f:
|
|
dos_header = f.read(2)
|
|
if dos_header != b'MZ':
|
|
print('get exe bit error: Invalid PE file')
|
|
return 64
|
|
# Seek to the offset of the PE signature
|
|
f.seek(60)
|
|
pe_offset_bytes = f.read(4)
|
|
pe_offset = int.from_bytes(pe_offset_bytes, byteorder='little')
|
|
|
|
# Seek to the Machine field in the PE header
|
|
f.seek(pe_offset + 4)
|
|
machine_bytes = f.read(2)
|
|
machine = int.from_bytes(machine_bytes, byteorder='little')
|
|
|
|
if machine == 0x14c:
|
|
return 32
|
|
elif machine == 0x8664:
|
|
return 64
|
|
else:
|
|
print('get exe bit error: Unknown architecture: %s' % hex(machine))
|
|
return 64
|
|
except IOError:
|
|
print('get exe bit error: File not found or cannot be opened')
|
|
return 64
|
|
|