mirror of
https://github.com/LC044/WeChatMsg
synced 2025-02-23 03:22:17 +08:00
新增手动获取基址
This commit is contained in:
parent
8f16ef5e60
commit
c7995ca776
@ -1,77 +1,9 @@
|
|||||||
import os
|
import os
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
|
||||||
from PyQt5.QtCore import QFile, QTextStream, QIODevice
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.append('.')
|
|
||||||
|
|
||||||
from app.DataBase import msg_db, MsgType
|
from app.DataBase import msg_db, MsgType
|
||||||
from pyecharts import options as opts
|
from pyecharts import options as opts
|
||||||
from pyecharts.charts import WordCloud, Calendar, Bar, Line
|
from pyecharts.charts import WordCloud, Calendar, Bar, Line
|
||||||
from app.resources import resource_rc
|
|
||||||
|
|
||||||
var = resource_rc.qt_resource_name
|
|
||||||
charts_width = 800
|
|
||||||
charts_height = 450
|
|
||||||
wordcloud_width = 780
|
|
||||||
wordcloud_height = 720
|
|
||||||
|
|
||||||
|
|
||||||
def wordcloud(wxid, is_Annual_report=False, year='2023', who='1'):
|
|
||||||
import jieba
|
|
||||||
txt_messages = msg_db.get_messages_by_type(wxid, MsgType.TEXT, year)
|
|
||||||
if not txt_messages:
|
|
||||||
return {
|
|
||||||
'chart_data': None,
|
|
||||||
'keyword': "没有聊天你想分析啥",
|
|
||||||
'max_num': "0",
|
|
||||||
'dialogs': []
|
|
||||||
}
|
|
||||||
# text = ''.join(map(lambda x: x[7], txt_messages))
|
|
||||||
text = ''.join(map(lambda x: x[7] if x[4] == int(who) else '', txt_messages)) # 1“我”说的话,0“Ta”说的话
|
|
||||||
|
|
||||||
total_msg_len = len(text)
|
|
||||||
# 使用jieba进行分词,并加入停用词
|
|
||||||
words = jieba.cut(text)
|
|
||||||
# 统计词频
|
|
||||||
word_count = Counter(words)
|
|
||||||
# 过滤停用词
|
|
||||||
stopwords_file = './app000/data/stopwords.txt'
|
|
||||||
try:
|
|
||||||
with open(stopwords_file, "r", encoding="utf-8") as stopword_file:
|
|
||||||
stopwords = set(stopword_file.read().splitlines())
|
|
||||||
except:
|
|
||||||
file = QFile(':/data/stopwords.txt')
|
|
||||||
if file.open(QIODevice.ReadOnly | QIODevice.Text):
|
|
||||||
stream = QTextStream(file)
|
|
||||||
stream.setCodec('utf-8')
|
|
||||||
content = stream.readAll()
|
|
||||||
file.close()
|
|
||||||
stopwords = set(content.splitlines())
|
|
||||||
filtered_word_count = {word: count for word, count in word_count.items() if len(word) > 1 and word not in stopwords}
|
|
||||||
|
|
||||||
# 转换为词云数据格式
|
|
||||||
data = [(word, count) for word, count in filtered_word_count.items()]
|
|
||||||
# text_data = data
|
|
||||||
data.sort(key=lambda x: x[1], reverse=True)
|
|
||||||
|
|
||||||
text_data = data[:100] if len(data) > 100 else data
|
|
||||||
# 创建词云图
|
|
||||||
keyword, max_num = text_data[0]
|
|
||||||
w = (
|
|
||||||
WordCloud(init_opts=opts.InitOpts(width=f"{wordcloud_width}px", height=f"{wordcloud_height}px"))
|
|
||||||
.add(series_name="聊天文字", data_pair=text_data, word_size_range=[5, 40])
|
|
||||||
)
|
|
||||||
# return w.render_embed()
|
|
||||||
return {
|
|
||||||
'chart_data': w.dump_options_with_quotes(),
|
|
||||||
'keyword': keyword,
|
|
||||||
'max_num': str(max_num),
|
|
||||||
'dialogs': msg_db.get_messages_by_keyword(wxid, keyword, num=5, max_len=12)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def wordcloud_(wxid, time_range=None):
|
def wordcloud_(wxid, time_range=None):
|
||||||
import jieba
|
import jieba
|
||||||
@ -115,7 +47,7 @@ def wordcloud_(wxid, time_range=None):
|
|||||||
# 创建词云图
|
# 创建词云图
|
||||||
keyword, max_num = text_data[0]
|
keyword, max_num = text_data[0]
|
||||||
w = (
|
w = (
|
||||||
WordCloud(init_opts=opts.InitOpts(width=f"{wordcloud_width}px", height=f"{wordcloud_height}px"))
|
WordCloud(init_opts=opts.InitOpts())
|
||||||
.add(series_name="聊天文字", data_pair=text_data, word_size_range=[5, 100])
|
.add(series_name="聊天文字", data_pair=text_data, word_size_range=[5, 100])
|
||||||
)
|
)
|
||||||
# return w.render_embed()
|
# return w.render_embed()
|
||||||
@ -267,7 +199,7 @@ def hour_count(wxid, is_Annual_report=False, year='2023'):
|
|||||||
y_data = list(map(lambda x: x[1], msg_data))
|
y_data = list(map(lambda x: x[1], msg_data))
|
||||||
x_axis = list(map(lambda x: x[0], msg_data))
|
x_axis = list(map(lambda x: x[0], msg_data))
|
||||||
h = (
|
h = (
|
||||||
Line(init_opts=opts.InitOpts(width=f"{charts_width}px", height=f"{charts_height}px"))
|
Line(init_opts=opts.InitOpts())
|
||||||
.add_xaxis(xaxis_data=x_axis)
|
.add_xaxis(xaxis_data=x_axis)
|
||||||
.add_yaxis(
|
.add_yaxis(
|
||||||
series_name="聊天频率",
|
series_name="聊天频率",
|
||||||
|
272
app/decrypt/get_bias_addr.py
Normal file
272
app/decrypt/get_bias_addr.py
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
# -*- coding: utf-8 -*-#
|
||||||
|
# -------------------------------------------------------------------------------
|
||||||
|
# Name: get_base_addr.py
|
||||||
|
# Description:
|
||||||
|
# Author: xaoyaoo
|
||||||
|
# Date: 2023/08/22
|
||||||
|
# -------------------------------------------------------------------------------
|
||||||
|
import argparse
|
||||||
|
import ctypes
|
||||||
|
import hashlib
|
||||||
|
import json
|
||||||
|
import multiprocessing
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import psutil
|
||||||
|
from win32com.client import Dispatch
|
||||||
|
from pymem import Pymem
|
||||||
|
import pymem
|
||||||
|
import hmac
|
||||||
|
|
||||||
|
ReadProcessMemory = ctypes.windll.kernel32.ReadProcessMemory
|
||||||
|
void_p = ctypes.c_void_p
|
||||||
|
KEY_SIZE = 32
|
||||||
|
DEFAULT_PAGESIZE = 4096
|
||||||
|
DEFAULT_ITER = 64000
|
||||||
|
|
||||||
|
|
||||||
|
def validate_key(key, salt, first, mac_salt):
|
||||||
|
byteKey = hashlib.pbkdf2_hmac("sha1", key, salt, DEFAULT_ITER, KEY_SIZE)
|
||||||
|
mac_key = hashlib.pbkdf2_hmac("sha1", byteKey, mac_salt, 2, KEY_SIZE)
|
||||||
|
hash_mac = hmac.new(mac_key, first[:-32], hashlib.sha1)
|
||||||
|
hash_mac.update(b'\x01\x00\x00\x00')
|
||||||
|
|
||||||
|
if hash_mac.digest() == first[-32:-12]:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_exe_bit(file_path):
|
||||||
|
"""
|
||||||
|
获取 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
|
||||||
|
|
||||||
|
|
||||||
|
def get_exe_version(file_path):
|
||||||
|
"""
|
||||||
|
获取 PE 文件的版本号
|
||||||
|
:param file_path: PE 文件路径(可执行文件)
|
||||||
|
:return: 如果遇到错误则返回
|
||||||
|
"""
|
||||||
|
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)]
|
||||||
|
|
||||||
|
|
||||||
|
class BiasAddr:
|
||||||
|
def __init__(self, account, mobile, name, key, db_path):
|
||||||
|
self.account = account.encode("utf-8")
|
||||||
|
self.mobile = mobile.encode("utf-8")
|
||||||
|
self.name = name.encode("utf-8")
|
||||||
|
self.key = bytes.fromhex(key) if key else b""
|
||||||
|
self.db_path = db_path if db_path and os.path.exists(db_path) else ""
|
||||||
|
|
||||||
|
self.process_name = "WeChat.exe"
|
||||||
|
self.module_name = "WeChatWin.dll"
|
||||||
|
|
||||||
|
self.pm = None # Pymem 对象
|
||||||
|
self.is_WoW64 = None # True: 32位进程运行在64位系统上 False: 64位进程运行在64位系统上
|
||||||
|
self.process_handle = None # 进程句柄
|
||||||
|
self.pid = None # 进程ID
|
||||||
|
self.version = None # 微信版本号
|
||||||
|
self.process = None # 进程对象
|
||||||
|
self.exe_path = None # 微信路径
|
||||||
|
self.address_len = None # 4 if self.bits == 32 else 8 # 4字节或8字节
|
||||||
|
self.bits = 64 if sys.maxsize > 2 ** 32 else 32 # 系统:32位或64位
|
||||||
|
|
||||||
|
def get_process_handle(self):
|
||||||
|
try:
|
||||||
|
self.pm = Pymem(self.process_name)
|
||||||
|
self.pm.check_wow64()
|
||||||
|
self.is_WoW64 = self.pm.is_WoW64
|
||||||
|
self.process_handle = self.pm.process_handle
|
||||||
|
self.pid = self.pm.process_id
|
||||||
|
self.process = psutil.Process(self.pid)
|
||||||
|
self.exe_path = self.process.exe()
|
||||||
|
self.version = get_exe_version(self.exe_path)
|
||||||
|
|
||||||
|
version_nums = list(map(int, self.version.split("."))) # 将版本号拆分为数字列表
|
||||||
|
if version_nums[0] <= 3 and version_nums[1] <= 9 and version_nums[2] <= 2:
|
||||||
|
self.address_len = 4
|
||||||
|
else:
|
||||||
|
self.address_len = 8
|
||||||
|
return True, ""
|
||||||
|
except pymem.exception.ProcessNotFound:
|
||||||
|
return False, "[-] WeChat No Run"
|
||||||
|
|
||||||
|
def search_memory_value(self, value: bytes, module_name="WeChatWin.dll"):
|
||||||
|
# 创建 Pymem 对象
|
||||||
|
module = pymem.process.module_from_name(self.pm.process_handle, module_name)
|
||||||
|
ret = self.pm.pattern_scan_module(value, module, return_multiple=True)
|
||||||
|
ret = ret[-1] - module.lpBaseOfDll if len(ret) > 0 else 0
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def get_key_bias1(self):
|
||||||
|
try:
|
||||||
|
byteLen = self.address_len # 4 if self.bits == 32 else 8 # 4字节或8字节
|
||||||
|
|
||||||
|
keyLenOffset = 0x8c if self.bits == 32 else 0xd0
|
||||||
|
keyWindllOffset = 0x90 if self.bits == 32 else 0xd8
|
||||||
|
|
||||||
|
module = pymem.process.module_from_name(self.process_handle, self.module_name)
|
||||||
|
keyBytes = b'-----BEGIN PUBLIC KEY-----\n...'
|
||||||
|
publicKeyList = pymem.pattern.pattern_scan_all(self.process_handle, keyBytes, return_multiple=True)
|
||||||
|
|
||||||
|
keyaddrs = []
|
||||||
|
for addr in publicKeyList:
|
||||||
|
keyBytes = addr.to_bytes(byteLen, byteorder="little", signed=True) # 低位在前
|
||||||
|
may_addrs = pymem.pattern.pattern_scan_module(self.process_handle, module, keyBytes,
|
||||||
|
return_multiple=True)
|
||||||
|
if may_addrs != 0 and len(may_addrs) > 0:
|
||||||
|
for addr in may_addrs:
|
||||||
|
keyLen = self.pm.read_uchar(addr - keyLenOffset)
|
||||||
|
if keyLen != 32:
|
||||||
|
continue
|
||||||
|
keyaddrs.append(addr - keyWindllOffset)
|
||||||
|
|
||||||
|
return keyaddrs[-1] - module.lpBaseOfDll if len(keyaddrs) > 0 else 0
|
||||||
|
except:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def search_key(self, key: bytes):
|
||||||
|
key = re.escape(key) # 转义特殊字符
|
||||||
|
key_addr = self.pm.pattern_scan_all(key, return_multiple=False)
|
||||||
|
key = key_addr.to_bytes(self.address_len, byteorder='little', signed=True)
|
||||||
|
result = self.search_memory_value(key, self.module_name)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def get_key_bias2(self, wx_db_path):
|
||||||
|
|
||||||
|
addr_len = get_exe_bit(self.exe_path) // 8
|
||||||
|
db_path = wx_db_path
|
||||||
|
|
||||||
|
def read_key_bytes(h_process, address, address_len=8):
|
||||||
|
array = ctypes.create_string_buffer(address_len)
|
||||||
|
if ReadProcessMemory(h_process, void_p(address), array, address_len, 0) == 0: return "None"
|
||||||
|
address = int.from_bytes(array, byteorder='little') # 逆序转换为int地址(key地址)
|
||||||
|
key = ctypes.create_string_buffer(32)
|
||||||
|
if ReadProcessMemory(h_process, void_p(address), key, 32, 0) == 0: return "None"
|
||||||
|
key_bytes = bytes(key)
|
||||||
|
return key_bytes
|
||||||
|
|
||||||
|
def verify_key(key, wx_db_path):
|
||||||
|
KEY_SIZE = 32
|
||||||
|
DEFAULT_PAGESIZE = 4096
|
||||||
|
DEFAULT_ITER = 64000
|
||||||
|
with open(wx_db_path, "rb") as file:
|
||||||
|
blist = file.read(5000)
|
||||||
|
salt = blist[:16]
|
||||||
|
byteKey = 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)])
|
||||||
|
mac_key = hashlib.pbkdf2_hmac("sha1", byteKey, mac_salt, 2, KEY_SIZE)
|
||||||
|
hash_mac = hmac.new(mac_key, first[:-32], hashlib.sha1)
|
||||||
|
hash_mac.update(b'\x01\x00\x00\x00')
|
||||||
|
|
||||||
|
if hash_mac.digest() != first[-32:-12]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
phone_type1 = "iphone\x00"
|
||||||
|
phone_type2 = "android\x00"
|
||||||
|
phone_type3 = "ipad\x00"
|
||||||
|
|
||||||
|
pm = pymem.Pymem("WeChat.exe")
|
||||||
|
module_name = "WeChatWin.dll"
|
||||||
|
|
||||||
|
MicroMsg_path = os.path.join(db_path, "MSG", "MicroMsg.db")
|
||||||
|
|
||||||
|
module = pymem.process.module_from_name(pm.process_handle, module_name)
|
||||||
|
|
||||||
|
type1_addrs = pm.pattern_scan_module(phone_type1.encode(), module, return_multiple=True)
|
||||||
|
type2_addrs = pm.pattern_scan_module(phone_type2.encode(), module, return_multiple=True)
|
||||||
|
type3_addrs = pm.pattern_scan_module(phone_type3.encode(), module, return_multiple=True)
|
||||||
|
type_addrs = type1_addrs if len(type1_addrs) >= 2 else type2_addrs if len(
|
||||||
|
type2_addrs) >= 2 else type3_addrs if len(type3_addrs) >= 2 else "None"
|
||||||
|
if type_addrs == "None":
|
||||||
|
return 0
|
||||||
|
for i in type_addrs[::-1]:
|
||||||
|
for j in range(i, i - 2000, -addr_len):
|
||||||
|
key_bytes = read_key_bytes(pm.process_handle, j, addr_len)
|
||||||
|
if key_bytes == "None":
|
||||||
|
continue
|
||||||
|
if verify_key(key_bytes, MicroMsg_path):
|
||||||
|
return j - module.lpBaseOfDll
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def run(self, logging_path=False, version_list_path=None):
|
||||||
|
if not self.get_process_handle()[0]:
|
||||||
|
return None
|
||||||
|
mobile_bias = self.search_memory_value(self.mobile, self.module_name)
|
||||||
|
name_bias = self.search_memory_value(self.name, self.module_name)
|
||||||
|
account_bias = self.search_memory_value(self.account, self.module_name)
|
||||||
|
key_bias = 0
|
||||||
|
key_bias = self.get_key_bias1()
|
||||||
|
key_bias = self.search_key(self.key) if key_bias <= 0 and self.key else key_bias
|
||||||
|
key_bias = self.get_key_bias2(self.db_path) if key_bias <= 0 and self.db_path else key_bias
|
||||||
|
|
||||||
|
rdata = {self.version: [name_bias, account_bias, mobile_bias, 0, key_bias]}
|
||||||
|
|
||||||
|
if version_list_path and os.path.exists(version_list_path):
|
||||||
|
with open(version_list_path, "r", encoding="utf-8") as f:
|
||||||
|
data = json.load(f)
|
||||||
|
data.update(rdata)
|
||||||
|
with open(version_list_path, "w", encoding="utf-8") as f:
|
||||||
|
json.dump(data, f, ensure_ascii=False, indent=4)
|
||||||
|
if os.path.exists(logging_path) and isinstance(logging_path, str):
|
||||||
|
with open(logging_path, "a", encoding="utf-8") as f:
|
||||||
|
f.write("{版本号:昵称,账号,手机号,邮箱,KEY}" + "\n")
|
||||||
|
f.write(str(rdata) + "\n")
|
||||||
|
elif logging_path:
|
||||||
|
print("{版本号:昵称,账号,手机号,邮箱,KEY}")
|
||||||
|
print(rdata)
|
||||||
|
return rdata
|
||||||
|
|
||||||
|
|
||||||
|
def get_info_without_key(h_process, address, n_size=64):
|
||||||
|
array = ctypes.create_string_buffer(n_size)
|
||||||
|
if ReadProcessMemory(h_process, void_p(address), array, n_size, 0) == 0: return "None"
|
||||||
|
array = bytes(array).split(b"\x00")[0] if b"\x00" in array else bytes(array)
|
||||||
|
text = array.decode('utf-8', errors='ignore')
|
||||||
|
return text.strip() if text.strip() != "" else "None"
|
206
app/ui/tool/get_bias_addr/getBiasAddrUi.py
Normal file
206
app/ui/tool/get_bias_addr/getBiasAddrUi.py
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'getBiasAddrUi.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.15.10
|
||||||
|
#
|
||||||
|
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
||||||
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
class Ui_Form(object):
|
||||||
|
def setupUi(self, Form):
|
||||||
|
Form.setObjectName("Form")
|
||||||
|
Form.resize(650, 580)
|
||||||
|
self.verticalLayout = QtWidgets.QVBoxLayout(Form)
|
||||||
|
self.verticalLayout.setObjectName("verticalLayout")
|
||||||
|
self.scrollArea = QtWidgets.QScrollArea(Form)
|
||||||
|
self.scrollArea.setFrameShape(QtWidgets.QFrame.NoFrame)
|
||||||
|
self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||||
|
self.scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
|
self.scrollArea.setWidgetResizable(True)
|
||||||
|
self.scrollArea.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||||
|
self.scrollArea.setObjectName("scrollArea")
|
||||||
|
self.scrollAreaWidgetContents = QtWidgets.QWidget()
|
||||||
|
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 632, 562))
|
||||||
|
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
|
||||||
|
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
|
||||||
|
self.verticalLayout_3.setObjectName("verticalLayout_3")
|
||||||
|
self.label_4 = QtWidgets.QLabel(self.scrollAreaWidgetContents)
|
||||||
|
self.label_4.setMaximumSize(QtCore.QSize(16777215, 20))
|
||||||
|
self.label_4.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
|
self.label_4.setObjectName("label_4")
|
||||||
|
self.verticalLayout_3.addWidget(self.label_4)
|
||||||
|
self.widget = QtWidgets.QWidget(self.scrollAreaWidgetContents)
|
||||||
|
self.widget.setStyleSheet("QWidget{\n"
|
||||||
|
" background-color:rgb(251,251,251);\n"
|
||||||
|
" border-radius: 10px;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"QPushButton{\n"
|
||||||
|
" background-color: rgb(250,252,253);\n"
|
||||||
|
" border-radius: 5px;\n"
|
||||||
|
" padding: 8px;\n"
|
||||||
|
" border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
"}\n"
|
||||||
|
"QPushButton:hover { \n"
|
||||||
|
" background-color: lightgray;\n"
|
||||||
|
"}")
|
||||||
|
self.widget.setObjectName("widget")
|
||||||
|
self.horizontalLayout = QtWidgets.QHBoxLayout(self.widget)
|
||||||
|
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||||
|
self.label = QtWidgets.QLabel(self.widget)
|
||||||
|
self.label.setMinimumSize(QtCore.QSize(80, 0))
|
||||||
|
self.label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.label.setObjectName("label")
|
||||||
|
self.horizontalLayout.addWidget(self.label)
|
||||||
|
self.lineEdit_tel = QtWidgets.QLineEdit(self.widget)
|
||||||
|
self.lineEdit_tel.setObjectName("lineEdit_tel")
|
||||||
|
self.horizontalLayout.addWidget(self.lineEdit_tel)
|
||||||
|
self.verticalLayout_3.addWidget(self.widget)
|
||||||
|
self.widget_3 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
|
||||||
|
self.widget_3.setStyleSheet("QWidget{\n"
|
||||||
|
" background-color:rgb(251,251,251);\n"
|
||||||
|
" border-radius: 10px;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"QPushButton{\n"
|
||||||
|
" background-color: rgb(250,252,253);\n"
|
||||||
|
" border-radius: 5px;\n"
|
||||||
|
" padding: 8px;\n"
|
||||||
|
" border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
"}\n"
|
||||||
|
"QPushButton:hover { \n"
|
||||||
|
" background-color: lightgray;\n"
|
||||||
|
"}")
|
||||||
|
self.widget_3.setObjectName("widget_3")
|
||||||
|
self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widget_3)
|
||||||
|
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||||
|
self.label_2 = QtWidgets.QLabel(self.widget_3)
|
||||||
|
self.label_2.setMinimumSize(QtCore.QSize(80, 0))
|
||||||
|
self.label_2.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.label_2.setObjectName("label_2")
|
||||||
|
self.horizontalLayout_3.addWidget(self.label_2)
|
||||||
|
self.lineEdit_wx_alias = QtWidgets.QLineEdit(self.widget_3)
|
||||||
|
self.lineEdit_wx_alias.setObjectName("lineEdit_wx_alias")
|
||||||
|
self.horizontalLayout_3.addWidget(self.lineEdit_wx_alias)
|
||||||
|
self.verticalLayout_3.addWidget(self.widget_3)
|
||||||
|
self.widget_4 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
|
||||||
|
self.widget_4.setStyleSheet("QWidget{\n"
|
||||||
|
" background-color:rgb(251,251,251);\n"
|
||||||
|
" border-radius: 10px;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"QPushButton{\n"
|
||||||
|
" background-color: rgb(250,252,253);\n"
|
||||||
|
" border-radius: 5px;\n"
|
||||||
|
" padding: 8px;\n"
|
||||||
|
" border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
"}\n"
|
||||||
|
"QPushButton:hover { \n"
|
||||||
|
" background-color: lightgray;\n"
|
||||||
|
"}")
|
||||||
|
self.widget_4.setObjectName("widget_4")
|
||||||
|
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(self.widget_4)
|
||||||
|
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
|
||||||
|
self.label_3 = QtWidgets.QLabel(self.widget_4)
|
||||||
|
self.label_3.setMinimumSize(QtCore.QSize(80, 0))
|
||||||
|
self.label_3.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||||
|
self.label_3.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.label_3.setObjectName("label_3")
|
||||||
|
self.horizontalLayout_4.addWidget(self.label_3)
|
||||||
|
self.lineEdit_wx_name = QtWidgets.QLineEdit(self.widget_4)
|
||||||
|
self.lineEdit_wx_name.setObjectName("lineEdit_wx_name")
|
||||||
|
self.horizontalLayout_4.addWidget(self.lineEdit_wx_name)
|
||||||
|
self.verticalLayout_3.addWidget(self.widget_4)
|
||||||
|
self.btn_get_bias_addr = QtWidgets.QPushButton(self.scrollAreaWidgetContents)
|
||||||
|
self.btn_get_bias_addr.setObjectName("btn_get_bias_addr")
|
||||||
|
self.verticalLayout_3.addWidget(self.btn_get_bias_addr)
|
||||||
|
self.widget_2 = QtWidgets.QWidget(self.scrollAreaWidgetContents)
|
||||||
|
self.widget_2.setStyleSheet("QWidget{\n"
|
||||||
|
" background-color:rgb(251,251,251);\n"
|
||||||
|
" border-radius: 10px;\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"QPushButton{\n"
|
||||||
|
" background-color: rgb(250,252,253);\n"
|
||||||
|
" border-radius: 5px;\n"
|
||||||
|
" padding: 8px;\n"
|
||||||
|
" border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
" border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */\n"
|
||||||
|
"}\n"
|
||||||
|
"QPushButton:hover { \n"
|
||||||
|
" background-color: lightgray;\n"
|
||||||
|
"}")
|
||||||
|
self.widget_2.setObjectName("widget_2")
|
||||||
|
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.widget_2)
|
||||||
|
self.horizontalLayout_2.setContentsMargins(9, -1, -1, -1)
|
||||||
|
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||||
|
self.commandLinkButton = QtWidgets.QCommandLinkButton(self.widget_2)
|
||||||
|
self.commandLinkButton.setEnabled(True)
|
||||||
|
self.commandLinkButton.setTabletTracking(False)
|
||||||
|
self.commandLinkButton.setFocusPolicy(QtCore.Qt.StrongFocus)
|
||||||
|
self.commandLinkButton.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
|
||||||
|
self.commandLinkButton.setToolTipDuration(-1)
|
||||||
|
self.commandLinkButton.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||||
|
self.commandLinkButton.setAutoFillBackground(False)
|
||||||
|
self.commandLinkButton.setCheckable(False)
|
||||||
|
self.commandLinkButton.setChecked(False)
|
||||||
|
self.commandLinkButton.setAutoRepeat(False)
|
||||||
|
self.commandLinkButton.setAutoExclusive(False)
|
||||||
|
self.commandLinkButton.setAutoDefault(False)
|
||||||
|
self.commandLinkButton.setDefault(False)
|
||||||
|
self.commandLinkButton.setObjectName("commandLinkButton")
|
||||||
|
self.horizontalLayout_2.addWidget(self.commandLinkButton)
|
||||||
|
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||||
|
self.horizontalLayout_2.addItem(spacerItem)
|
||||||
|
self.label_error_log = QtWidgets.QLabel(self.widget_2)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Preferred)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.label_error_log.sizePolicy().hasHeightForWidth())
|
||||||
|
self.label_error_log.setSizePolicy(sizePolicy)
|
||||||
|
self.label_error_log.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
|
self.label_error_log.setObjectName("label_error_log")
|
||||||
|
self.horizontalLayout_2.addWidget(self.label_error_log)
|
||||||
|
self.checkBox_send_error_log = QtWidgets.QCheckBox(self.widget_2)
|
||||||
|
self.checkBox_send_error_log.setText("")
|
||||||
|
self.checkBox_send_error_log.setIconSize(QtCore.QSize(64, 64))
|
||||||
|
self.checkBox_send_error_log.setChecked(True)
|
||||||
|
self.checkBox_send_error_log.setObjectName("checkBox_send_error_log")
|
||||||
|
self.horizontalLayout_2.addWidget(self.checkBox_send_error_log)
|
||||||
|
self.verticalLayout_3.addWidget(self.widget_2)
|
||||||
|
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
|
||||||
|
self.verticalLayout.addWidget(self.scrollArea)
|
||||||
|
|
||||||
|
self.retranslateUi(Form)
|
||||||
|
QtCore.QMetaObject.connectSlotsByName(Form)
|
||||||
|
|
||||||
|
def retranslateUi(self, Form):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
Form.setWindowTitle(_translate("Form", "Form"))
|
||||||
|
self.label_4.setText(_translate("Form", "为避免输入错误,下面信息请从微信里复制"))
|
||||||
|
self.label.setText(_translate("Form", "手机号:"))
|
||||||
|
self.lineEdit_tel.setPlaceholderText(_translate("Form", "填入微信绑定的手机号"))
|
||||||
|
self.label_2.setText(_translate("Form", "微信号:"))
|
||||||
|
self.lineEdit_wx_alias.setPlaceholderText(_translate("Form", "填入您的微信号"))
|
||||||
|
self.label_3.setText(_translate("Form", "微信昵称:"))
|
||||||
|
self.lineEdit_wx_name.setPlaceholderText(_translate("Form", "填入您的微信昵称"))
|
||||||
|
self.btn_get_bias_addr.setText(_translate("Form", "获取信息"))
|
||||||
|
self.commandLinkButton.setText(_translate("Form", "收集版本信息"))
|
||||||
|
self.commandLinkButton.setDescription(_translate("Form", "需要收集微信版本信息以支持更多用户"))
|
||||||
|
self.label_error_log.setText(_translate("Form", "开"))
|
145
app/ui/tool/get_bias_addr/get_bias_addr.py
Normal file
145
app/ui/tool/get_bias_addr/get_bias_addr.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import json
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from PyQt5.QtCore import pyqtSignal, QThread
|
||||||
|
from PyQt5.QtWidgets import QWidget, QMessageBox
|
||||||
|
|
||||||
|
from app.components.QCursorGif import QCursorGif
|
||||||
|
from app.decrypt.get_bias_addr import BiasAddr
|
||||||
|
from .getBiasAddrUi import Ui_Form
|
||||||
|
|
||||||
|
Stylesheet = """
|
||||||
|
QPushButton{
|
||||||
|
background-color: rgb(250,252,253);
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 8px;
|
||||||
|
border-right: 2px solid #888888; /* 按钮边框,2px宽,白色 */
|
||||||
|
border-bottom: 2px solid #888888; /* 按钮边框,2px宽,白色 */
|
||||||
|
border-left: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */
|
||||||
|
border-top: 1px solid #ffffff; /* 按钮边框,2px宽,白色 */
|
||||||
|
}
|
||||||
|
QPushButton:hover {
|
||||||
|
background-color: lightgray;
|
||||||
|
}
|
||||||
|
/*去掉item虚线边框*/
|
||||||
|
QListWidget, QListView, QTreeWidget, QTreeView {
|
||||||
|
outline: 0px;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
/*设置左侧选项的最小最大宽度,文字颜色和背景颜色*/
|
||||||
|
QListWidget {
|
||||||
|
min-width: 400px;
|
||||||
|
max-width: 400px;
|
||||||
|
min-height: 80px;
|
||||||
|
max-height: 80px;
|
||||||
|
color: black;
|
||||||
|
border:none;
|
||||||
|
}
|
||||||
|
QListWidget::item{
|
||||||
|
min-width: 80px;
|
||||||
|
max-width: 400px;
|
||||||
|
min-height: 80px;
|
||||||
|
max-height: 80px;
|
||||||
|
}
|
||||||
|
/*被选中时的背景颜色和左边框颜色*/
|
||||||
|
QListWidget::item:selected {
|
||||||
|
border-left:none;
|
||||||
|
color: black;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
QCheckBox::indicator {
|
||||||
|
background: rgb(251, 251, 251);
|
||||||
|
Width:60px;
|
||||||
|
Height:60px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
QCheckBox::indicator:unchecked{
|
||||||
|
Width:60px;
|
||||||
|
Height:60px;
|
||||||
|
image: url(:/icons/icons/按钮_关闭.svg);
|
||||||
|
}
|
||||||
|
QCheckBox::indicator:checked{
|
||||||
|
Width:60px;
|
||||||
|
Height:60px;
|
||||||
|
image: url(:/icons/icons/按钮_开启.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class GetBiasAddrControl(QWidget, Ui_Form, QCursorGif):
|
||||||
|
biasAddrSignal = pyqtSignal(dict)
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super(GetBiasAddrControl, self).__init__(parent)
|
||||||
|
self.thread = None
|
||||||
|
self.setStyleSheet(Stylesheet)
|
||||||
|
self.setupUi(self)
|
||||||
|
self.init_ui()
|
||||||
|
|
||||||
|
def init_ui(self):
|
||||||
|
self.initCursor([':/icons/icons/Cursors/%d.png' %
|
||||||
|
i for i in range(8)], self)
|
||||||
|
self.setCursorTimeout(100)
|
||||||
|
self.btn_get_bias_addr.clicked.connect(self.get_bias_addr)
|
||||||
|
self.commandLinkButton.clicked.connect(self.show_info)
|
||||||
|
self.checkBox_send_error_log.clicked.connect(self.set_error_log)
|
||||||
|
|
||||||
|
def set_error_log(self):
|
||||||
|
if self.checkBox_send_error_log.isChecked():
|
||||||
|
self.label_error_log.setText('开')
|
||||||
|
else:
|
||||||
|
self.label_error_log.setText('关')
|
||||||
|
|
||||||
|
def show_info(self):
|
||||||
|
QMessageBox.information(self, "收集版本信息",
|
||||||
|
"为了适配更多版本,需要收集微信的版本信息,该操作不会上传包括手机号、微信号、昵称等在内的任何信息\n示例数据:\n\"3.9.9.27\": [68065304, 0, 68065112, 0, 68066576]"
|
||||||
|
)
|
||||||
|
|
||||||
|
def upload(self, version_data):
|
||||||
|
url = "http://api.lc044.love/wxBiasAddr"
|
||||||
|
try:
|
||||||
|
requests.post(url, json=version_data)
|
||||||
|
print('版本信息上传成功')
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_bias_addr(self):
|
||||||
|
|
||||||
|
account = self.lineEdit_wx_alias.text()
|
||||||
|
mobile = self.lineEdit_tel.text()
|
||||||
|
name = self.lineEdit_wx_name.text()
|
||||||
|
if not all([account, mobile, name]):
|
||||||
|
QMessageBox.critical(self, "错误",
|
||||||
|
"请把所有信息填写完整")
|
||||||
|
return
|
||||||
|
key = None
|
||||||
|
db_path = "test"
|
||||||
|
self.startBusy()
|
||||||
|
self.thread = MyThread(account, mobile, name, key, db_path)
|
||||||
|
self.thread.signal.connect(self.set_bias_addr)
|
||||||
|
self.thread.start()
|
||||||
|
|
||||||
|
def set_bias_addr(self, data):
|
||||||
|
if self.checkBox_send_error_log.isChecked():
|
||||||
|
self.upload(data)
|
||||||
|
self.stopBusy()
|
||||||
|
self.biasAddrSignal.emit(data)
|
||||||
|
|
||||||
|
|
||||||
|
class MyThread(QThread):
|
||||||
|
signal = pyqtSignal(dict)
|
||||||
|
|
||||||
|
def __init__(self, account, mobile, name, key, db_path):
|
||||||
|
super(MyThread, self).__init__()
|
||||||
|
self.account = account
|
||||||
|
self.mobile = mobile
|
||||||
|
self.name = name
|
||||||
|
self.key = key
|
||||||
|
self.db_path = db_path
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
bias_addr = BiasAddr(self.account, self.mobile, self.name, self.key, self.db_path)
|
||||||
|
data = bias_addr.run(logging_path=True)
|
||||||
|
self.signal.emit(data)
|
@ -21,14 +21,17 @@ from ...Icon import Icon
|
|||||||
class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
||||||
DecryptSignal = pyqtSignal(bool)
|
DecryptSignal = pyqtSignal(bool)
|
||||||
get_wxidSignal = pyqtSignal(str)
|
get_wxidSignal = pyqtSignal(str)
|
||||||
|
versionErrorSignal = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(DecryptControl, self).__init__(parent)
|
super(DecryptControl, self).__init__(parent)
|
||||||
|
self.max_val = 0
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
# 设置忙碌光标图片数组
|
# 设置忙碌光标图片数组
|
||||||
self.initCursor([':/icons/icons/Cursors/%d.png' %
|
self.initCursor([':/icons/icons/Cursors/%d.png' %
|
||||||
i for i in range(8)], self)
|
i for i in range(8)], self)
|
||||||
self.setCursorTimeout(100)
|
self.setCursorTimeout(100)
|
||||||
|
self.version_list = None
|
||||||
self.btn_start.clicked.connect(self.decrypt)
|
self.btn_start.clicked.connect(self.decrypt)
|
||||||
self.btn_getinfo.clicked.connect(self.get_info)
|
self.btn_getinfo.clicked.connect(self.get_info)
|
||||||
self.btn_db_dir.clicked.connect(self.select_db_dir)
|
self.btn_db_dir.clicked.connect(self.select_db_dir)
|
||||||
@ -53,7 +56,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
|||||||
# @log
|
# @log
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
self.startBusy()
|
self.startBusy()
|
||||||
self.get_info_thread = MyThread()
|
self.get_info_thread = MyThread(self.version_list)
|
||||||
self.get_info_thread.signal.connect(self.set_info)
|
self.get_info_thread.signal.connect(self.set_info)
|
||||||
self.get_info_thread.start()
|
self.get_info_thread.start()
|
||||||
|
|
||||||
@ -62,8 +65,10 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
|||||||
if result[0] == -1:
|
if result[0] == -1:
|
||||||
QMessageBox.critical(self, "错误", "请登录微信")
|
QMessageBox.critical(self, "错误", "请登录微信")
|
||||||
elif result[0] == -2:
|
elif result[0] == -2:
|
||||||
|
self.versionErrorSignal.emit(result[1])
|
||||||
QMessageBox.critical(self, "错误",
|
QMessageBox.critical(self, "错误",
|
||||||
"微信版本不匹配\n请更新微信版本为:3.9.9.27(去微信官网下载)\n或更新本软件")
|
"微信版本不匹配\n请手动填写信息")
|
||||||
|
|
||||||
elif result[0] == -3:
|
elif result[0] == -3:
|
||||||
QMessageBox.critical(self, "错误", "WeChat WeChatWin.dll Not Found")
|
QMessageBox.critical(self, "错误", "WeChat WeChatWin.dll Not Found")
|
||||||
elif result[0] == -10086:
|
elif result[0] == -10086:
|
||||||
@ -151,11 +156,12 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
|||||||
# print("enter clicked")
|
# print("enter clicked")
|
||||||
# 中间可以添加处理逻辑
|
# 中间可以添加处理逻辑
|
||||||
# QMessageBox.about(self, "解密成功", "数据库文件存储在app/DataBase/Msg文件夹下")
|
# QMessageBox.about(self, "解密成功", "数据库文件存储在app/DataBase/Msg文件夹下")
|
||||||
|
self.progressBar_view(self.max_val)
|
||||||
self.DecryptSignal.emit(True)
|
self.DecryptSignal.emit(True)
|
||||||
# self.close()
|
# self.close()
|
||||||
|
|
||||||
def setProgressBarMaxNum(self, max_val):
|
def setProgressBarMaxNum(self, max_val):
|
||||||
|
self.max_val = max_val
|
||||||
self.progressBar.setRange(0, max_val)
|
self.progressBar.setRange(0, max_val)
|
||||||
|
|
||||||
def progressBar_view(self, value):
|
def progressBar_view(self, value):
|
||||||
@ -184,7 +190,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog, QCursorGif):
|
|||||||
except:
|
except:
|
||||||
with open('./info.json', 'w', encoding='utf-8') as f:
|
with open('./info.json', 'w', encoding='utf-8') as f:
|
||||||
f.write(json.dumps(dic))
|
f.write(json.dumps(dic))
|
||||||
|
self.progressBar_view(self.max_val)
|
||||||
self.DecryptSignal.emit(True)
|
self.DecryptSignal.emit(True)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
@ -271,8 +277,9 @@ class DecryptThread(QThread):
|
|||||||
class MyThread(QThread):
|
class MyThread(QThread):
|
||||||
signal = pyqtSignal(list)
|
signal = pyqtSignal(list)
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self,version_list = None):
|
||||||
super(MyThread, self).__init__()
|
super(MyThread, self).__init__()
|
||||||
|
self.version_list = version_list
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
pass
|
pass
|
||||||
@ -283,8 +290,11 @@ class MyThread(QThread):
|
|||||||
'version': version
|
'version': version
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
response = requests.post(url, json=data)
|
response = requests.get(url, json=data)
|
||||||
|
print(response)
|
||||||
|
print(response.text)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
|
|
||||||
update_info = response.json()
|
update_info = response.json()
|
||||||
return update_info
|
return update_info
|
||||||
else:
|
else:
|
||||||
@ -293,12 +303,15 @@ class MyThread(QThread):
|
|||||||
return {}
|
return {}
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
file_path = './app/resources/data/version_list.json'
|
if self.version_list:
|
||||||
if not os.path.exists(file_path):
|
VERSION_LIST = self.version_list
|
||||||
resource_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
|
else:
|
||||||
file_path = os.path.join(resource_dir, 'app', 'resources', 'data', 'version_list.json')
|
file_path = './app/resources/data/version_list.json'
|
||||||
with open(file_path, "r", encoding="utf-8") as f:
|
if not os.path.exists(file_path):
|
||||||
VERSION_LIST = json.loads(f.read())
|
resource_dir = getattr(sys, '_MEIPASS', os.path.abspath(os.path.dirname(__file__)))
|
||||||
|
file_path = os.path.join(resource_dir, 'app', 'resources', 'data', 'version_list.json')
|
||||||
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
|
VERSION_LIST = json.loads(f.read())
|
||||||
try:
|
try:
|
||||||
result = get_wx_info.get_info(VERSION_LIST)
|
result = get_wx_info.get_info(VERSION_LIST)
|
||||||
if result == -1:
|
if result == -1:
|
||||||
@ -313,6 +326,9 @@ class MyThread(QThread):
|
|||||||
if version_bias.get(version):
|
if version_bias.get(version):
|
||||||
logger.info(f"从云端获取内存基址:{version_bias}")
|
logger.info(f"从云端获取内存基址:{version_bias}")
|
||||||
result = get_wx_info.get_info(version_bias)
|
result = get_wx_info.get_info(version_bias)
|
||||||
|
else:
|
||||||
|
logger.info(f"从云端获取内存基址失败:{version}")
|
||||||
|
result = [-2,version]
|
||||||
except:
|
except:
|
||||||
logger.error(traceback.format_exc())
|
logger.error(traceback.format_exc())
|
||||||
result = [-10086]
|
result = [-10086]
|
||||||
|
@ -78,6 +78,7 @@ class SettingControl(QWidget, Ui_Form):
|
|||||||
def init_ui(self):
|
def init_ui(self):
|
||||||
self.checkBox.setText('是')
|
self.checkBox.setText('是')
|
||||||
self.checkBox_send_error_log.clicked.connect(self.set_error_log)
|
self.checkBox_send_error_log.clicked.connect(self.set_error_log)
|
||||||
|
|
||||||
def set_error_log(self):
|
def set_error_log(self):
|
||||||
if self.checkBox_send_error_log.isChecked():
|
if self.checkBox_send_error_log.isChecked():
|
||||||
self.label_error_log.setText('开')
|
self.label_error_log.setText('开')
|
||||||
|
@ -5,6 +5,7 @@ from PyQt5.QtWidgets import QWidget, QListWidgetItem, QLabel
|
|||||||
from app.ui.Icon import Icon
|
from app.ui.Icon import Icon
|
||||||
from .pc_decrypt import DecryptControl
|
from .pc_decrypt import DecryptControl
|
||||||
from .setting.setting import SettingControl
|
from .setting.setting import SettingControl
|
||||||
|
from .get_bias_addr.get_bias_addr import GetBiasAddrControl
|
||||||
from .toolUI import Ui_Dialog
|
from .toolUI import Ui_Dialog
|
||||||
|
|
||||||
# 美化样式表
|
# 美化样式表
|
||||||
@ -68,14 +69,22 @@ class ToolWindow(QWidget, Ui_Dialog):
|
|||||||
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
|
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
|
||||||
chat_item = QListWidgetItem(Icon.Decrypt_Icon, '解密', self.listWidget)
|
chat_item = QListWidgetItem(Icon.Decrypt_Icon, '解密', self.listWidget)
|
||||||
contact_item = QListWidgetItem(Icon.Contact_Icon, '设置', self.listWidget)
|
contact_item = QListWidgetItem(Icon.Contact_Icon, '设置', self.listWidget)
|
||||||
myinfo_item = QListWidgetItem(Icon.Home_Icon, '别点', self.listWidget)
|
myinfo_item = QListWidgetItem(Icon.Home_Icon, '解密2', self.listWidget)
|
||||||
tool_item = QListWidgetItem(Icon.Home_Icon, '别点', self.listWidget)
|
tool_item = QListWidgetItem(Icon.Home_Icon, '别点', self.listWidget)
|
||||||
decrypt_window = DecryptControl()
|
|
||||||
decrypt_window.get_wxidSignal.connect(self.get_info_signal)
|
self.decrypt_window = DecryptControl()
|
||||||
decrypt_window.DecryptSignal.connect(self.decrypt_success_signal)
|
self.decrypt_window.get_wxidSignal.connect(self.get_info_signal)
|
||||||
self.stackedWidget.addWidget(decrypt_window)
|
self.decrypt_window.DecryptSignal.connect(self.decrypt_success_signal)
|
||||||
|
self.decrypt_window.versionErrorSignal.connect(self.show_decrypt2)
|
||||||
|
self.stackedWidget.addWidget(self.decrypt_window)
|
||||||
|
|
||||||
setting_window = SettingControl()
|
setting_window = SettingControl()
|
||||||
self.stackedWidget.addWidget(setting_window)
|
self.stackedWidget.addWidget(setting_window)
|
||||||
|
|
||||||
|
self.get_bias_addr_window = GetBiasAddrControl()
|
||||||
|
self.get_bias_addr_window.biasAddrSignal.connect(self.decrypt)
|
||||||
|
self.stackedWidget.addWidget(self.get_bias_addr_window)
|
||||||
|
|
||||||
label = QLabel('都说了不让你点', self)
|
label = QLabel('都说了不让你点', self)
|
||||||
label.setFont(QFont("微软雅黑", 50))
|
label.setFont(QFont("微软雅黑", 50))
|
||||||
label.setAlignment(Qt.AlignCenter)
|
label.setAlignment(Qt.AlignCenter)
|
||||||
@ -84,10 +93,19 @@ class ToolWindow(QWidget, Ui_Dialog):
|
|||||||
# label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % (
|
# label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % (
|
||||||
# randint(0, 255), randint(0, 255), randint(0, 255)))
|
# randint(0, 255), randint(0, 255), randint(0, 255)))
|
||||||
|
|
||||||
self.stackedWidget.addWidget(label)
|
|
||||||
self.stackedWidget.addWidget(label)
|
self.stackedWidget.addWidget(label)
|
||||||
self.listWidget.setCurrentRow(0)
|
self.listWidget.setCurrentRow(0)
|
||||||
self.stackedWidget.setCurrentIndex(0)
|
self.stackedWidget.setCurrentIndex(0)
|
||||||
|
|
||||||
|
def decrypt(self, version_list):
|
||||||
|
self.listWidget.setCurrentRow(0)
|
||||||
|
self.stackedWidget.setCurrentIndex(0)
|
||||||
|
self.decrypt_window.version_list = version_list
|
||||||
|
self.decrypt_window.get_info()
|
||||||
|
|
||||||
|
def show_decrypt2(self, version):
|
||||||
|
self.listWidget.setCurrentRow(2)
|
||||||
|
self.stackedWidget.setCurrentIndex(2)
|
||||||
|
|
||||||
def setCurrentIndex(self, row):
|
def setCurrentIndex(self, row):
|
||||||
self.stackedWidget.setCurrentIndex(row)
|
self.stackedWidget.setCurrentIndex(row)
|
||||||
|
@ -33,6 +33,7 @@ def get_code(dat_read):
|
|||||||
return head_index, code
|
return head_index, code
|
||||||
head_index = head_index + 1
|
head_index = head_index + 1
|
||||||
print("not jpg, png, gif")
|
print("not jpg, png, gif")
|
||||||
|
return -1, -1
|
||||||
except:
|
except:
|
||||||
logger.error(f'image解析发生了错误:\n\n{traceback.format_exc()}')
|
logger.error(f'image解析发生了错误:\n\n{traceback.format_exc()}')
|
||||||
return -1, -1
|
return -1, -1
|
||||||
@ -48,8 +49,8 @@ def decode_dat(file_path, out_path):
|
|||||||
return None
|
return None
|
||||||
with open(file_path, 'rb') as file_in:
|
with open(file_path, 'rb') as file_in:
|
||||||
data = file_in.read()
|
data = file_in.read()
|
||||||
file_type, decode_code = get_code(data[:2])
|
data = get_code(data[:2])
|
||||||
|
file_type, decode_code = data
|
||||||
if decode_code == -1:
|
if decode_code == -1:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user