Python软件逆向-SE工具箱
原因
今天在网上看见以个SE工具箱,号称可以通过某人的qq、手机号或者微博进行反查信息,只需知道其中一个便可查询其他信息。我一看,这不就是一社工库吗,于是便想下载来看一下
结果发现这软件竟然收费,而且是用python写的
破解过程
解包
对exe进行解包用的是pyinstxtractor
下载地址:https://github.com/extremecoders-re/pyinstxtractor/releases/
下载完成后将压缩包进行解压,得到了一下文件
然后将要解包的exe放进这个目录
打开powershell进入当前目录输入
python .\pyinstxtractor.py <要解包程序的地址>
然后执行
这时在当前目录下便出现了一个新的文件夹
反编译
进入该文件夹,找到与exe文件同名的pyc文件,尝试使用uncompyle6进行反编译
pip install uncompyle6
uncompyle6 .\SE工具箱.pyc >so.py
这里的so.py
是将反编译的结果保存至so.py这一文件
但是发现使用uncompyle6反编译失败,于是果断选择在网上寻找在线反编译工具
https://tool.lu/pyc/
反编译的到如下代码
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.9
import threading
import win32api
import pyDes
from binascii import b2a_hex, a2b_hex
import base64
import requests
import re
import os
import random
import time
import PySimpleGUI as Sg
Des_Key = '12345678'
Des_IV = '00000000'
TYPE = 'DB'
class Register:
def __init__(self, TYPE):
self.TYPE = TYPE
self.Des_Key = Des_Key
self.Des_IV = Des_IV
def getCVolumeSerialNumber(self):
CVolumeSerialNumber = win32api.GetVolumeInformation('C:\\')[1]
if CVolumeSerialNumber:
return str(CVolumeSerialNumber)
return None
def DesEncrypt(self, str):
k = pyDes.des(self.Des_Key, pyDes.CBC, self.Des_IV, None, pyDes.PAD_PKCS5, **('pad', 'padmode'))
encryptStr = k.encrypt(str)
string = base64.b64encode(encryptStr)
return string
def DesDecrypt(self, string):
string = base64.b64decode(string)
k = pyDes.des(self.Des_Key, pyDes.CBC, self.Des_IV, None, pyDes.PAD_PKCS5, **('pad', 'padmode'))
decryptStr = k.decrypt(string)
return decryptStr
def Regist_New(self):
pass
# WARNING: Decompyle incomplete
def encryCode(self):
global serialnumber
rand = str(random.randrange(1, 1000))
serialnumber = self.getCVolumeSerialNumber()
content = str({
'stat': '',
'Serial': serialnumber,
'Random': rand,
'Type': self.TYPE })
encryptstr = self.DesEncrypt(content).decode('utf8')
return encryptstr
def checKey(self):
key = values['-key-']
# WARNING: Decompyle incomplete
def GetTime(self):
url = 'http://api.m.taobao.com/rest/api3.do?api=mtop.common.getTimestamp'
# WARNING: Decompyle incomplete
def CheckTimeTri(self):
if int(self.GetTime()) >= self.deadline:
os.remove('conf.bin')
return 403
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3877.400 QQBrowser/10.8.4506.400' }
def SeTool():
global phone, phonediqu, lolName, lolDaqu, qqlm, weibo, qq, qq, phone, weibo
def qqMsg():
global phone, phonediqu, lolName, lolDaqu, qqlm
print('正在查询...')
url = 'https://www.hmily.vip/api/qb/?qq=' + str(qq)
html = requests.get(url, headers, **('url', 'headers'))
if html.json()['code'] == 1:
phone = html.json()['phone']
phonediqu = html.json()['phonediqu']
lolName = html.json()['lolName']
lolDaqu = html.json()['lolDaqu']
qqlm = html.json()['qqlm']
def phoneMsg():
global qq, phonediqu, weibo
print('正在查询...')
url3 = 'https://hmily.vip/api/phone/?phone=' + str(phone)
html = requests.get(url3, headers, **('url', 'headers'))
if html.json()['code'] == 1:
qq = html.json()['qq']
phonediqu = html.json()['phonediqu']
weibo = html.json()['weibo']
def wbMsg():
global phone, phonediqu
print('正在查询...')
url3 = 'https://www.hmily.vip/api/wb/?id=' + str(weibo)
html = requests.get(url3, headers, **('url', 'headers'))
if html.json()['code'] == 1:
phone = html.json()['phone']
phonediqu = html.json()['phonediqu']
layout = [
[
Sg.T('查询结果:')],
[
Sg.Multiline('查询需要时间,提交后请耐心等待结果\n', (70, 20), '-show-', True, **('size', 'key', 'autoscroll'))],
[
Sg.T('说明:请选择与输入号码相对应的查询方式', '-text-', 'white', **('key', 'text_color'))],
[
Sg.T('请输入查询号码'),
Sg.In('-content-', **('key',))],
[
Sg.T('请选择查询方式')] + (lambda .0: [ Sg.Radio(i, 1, i, **('group_id', 'key')) for i in .0 ])(('qq号', '手机号', '微博UID')),
[
Sg.B('确认提交'),
Sg.B('清空')]]
window = Sg.Window('SE工具箱', layout)
flag = Sg.popup_ok_cancel('免责声明:请勿把软件用在违法犯罪途径!\n造成的一切后果本作者概不负责\n如若同意请点击ok进入软件', '提示', ('黑体', 13), **('title', 'font'))
if flag == 'Cancel':
os._exit(0)
(event, values) = window.read(300)
if res2 == 3 or res1 == 3:
res = Reg.CheckTimeTri()
if res == 403:
Sg.popup('软件使用时间已到期\n请重新购买登录码', '提示', ('黑体', 13), **('title', 'font'))
if event == '确认提交' and values['-content-'] != '':
phone = '没有查询到'
phonediqu = '没有查询到'
lolName = '没有查询到'
lolDaqu = '没有查询到'
qqlm = '没有查询到'
weibo = '没有查询到'
qq = '没有查询到'
message = ''
msg = ''
t = time.strftime('%Y/%m/%d %H:%M:%S', time.localtime())
if values['qq号']:
qq = values['-content-']
message = window['-show-'].get()
window['-show-'].update('')
t1 = threading.Thread(qqMsg, **('target',))
t1.start()
t1.join()
if phone == '没有查询到':
msg = f'''\n时间: {t}\nQQ号码: {qq}\n未查到任何信息! \n'''
else:
msg = f'''\n查询成功!\n时间: {t}\nQQ号码: {qq}\n手机号码: {phone}\n地区: {phonediqu}\nLOL账号: {lolName}\nLOL大区: {lolDaqu}\nQQ密码: {qqlm}\n '''
elif values['手机号']:
phone = values['-content-']
message = window['-show-'].get()
window['-show-'].update('')
t2 = threading.Thread(phoneMsg, **('target',))
t2.start()
t2.join()
if qq == '没有查询到':
msg = f'''\n时间: {t}\n手机号码: {phone}\n未查到任何信息! \n'''
else:
msg = f'''\n查询成功!\n时间: {t}\n手机号码: {phone}\n地区: {phonediqu}\nQQ账号: {qq}\n微博ID: {weibo}\n'''
elif values['微博UID']:
weibo = values['-content-']
message = window['-show-'].get()
window['-show-'].update('')
wbMsg()
if phone == '没有查询到':
msg = f'''\n时间: {t}\n微博ID: {weibo}\n未查到任何信息! \n'''
else:
msg = f'''\n查询成功!\n时间: {t}\n微博ID: {weibo}\n手机号码: {phone}\n地区: {phonediqu}\n'''
else:
window['-show-'].update('请选择一个查询方式,点击提交后请耐心等待查询结果')
window['-show-'].update(message + '\n' + msg)
window['-content-'].update('')
if event == '清空':
window['-show-'].update('')
if event is None:
pass
window.close()
Reg = Register(TYPE)
res1 = Reg.Regist_New()
deadline = ''
res2 = ''
if res1 in (1, 2, 3):
SeTool()
elif res1 == 4:
Sg.popup('登陆码验证失败 请重新输入', '提示', ('黑体', 13), **('title', 'font'))
if res1 == 5:
Sg.popup('请勿非法获得验证文件!', '提示', ('黑体', 13), **('title', 'font'))
entryCode = Reg.encryCode()
layout = [
[
Sg.Text('输入你的登录码后进入软件', ('黑体', 13), **('font',))],
[
Sg.Text('机器码:', True, (7, 1), ('黑体', 12), **('enable_events', 'size', 'font')),
Sg.InputText(entryCode, '-serial-', **('key',))],
[
Sg.Text('登录码:', (7, 1), ('黑体', 12), **('size', 'font')),
Sg.InputText('', '-key-', **('key',))],
[
Sg.Button('确认', ('微软雅黑', 9), **('font',)),
Sg.Button('退出', ('微软雅黑', 9), **('font',)),
Sg.Text('点我购买登录码', ((200, 10), (0, 0)), True, '#fff200', **('pad', 'enable_events', 'text_color'))]]
window1 = Sg.Window('SE工具箱', layout)
(event, values) = window1.read()
if event == None:
pass
elif event == '确认' and values['-key-'] != '':
res2 = Reg.checKey()
if res2 == 1:
Sg.popup('登录成功!', ('黑体', 12), **('font',))
window1.close()
SeTool()
elif res2 == 3:
timeArry = time.localtime(Reg.deadline / 1000)
Sg.popup(f'''登录成功!到期时间\n{time.strftime('%Y/%m/%d %H:%M:%S', timeArry)}''', ('黑体', 13), **('font',))
window1.close()
SeTool()
elif res2 == 5:
Sg.popup('登陆码验证失败 请重新输入', '提示', ('黑体', 12), **('title', 'font'))
if event == '退出':
pass
elif event == '点我购买登录码':
Sg.popup('购买登录码20R\n联系QQ:2900548175\n微信号:tangmin903', '提示', ('黑体', 12), **('title', 'font'))
continue
window1.close()
return None
结果
然后翻阅源码发现如下几个接口:
- https://www.hmily.vip/api/qb/?qq=
- https://hmily.vip/api/phone/?phone=
- https://www.hmily.vip/api/wb/?id=
这分别是QQ,手机号及微博ID的查询接口