Skip to content
This repository was archived by the owner on Aug 29, 2021. It is now read-only.

Commit 0e5b494

Browse files
committed
make wvguesser faster
1 parent c0cb3e4 commit 0e5b494

File tree

6 files changed

+95
-21
lines changed

6 files changed

+95
-21
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@
1616

1717
## 本地破解
1818

19-
如果是exe版本,直接将`offline_config.json`拖到`wvguesser_v1.1.0.exe`上即可
19+
如果是exe版本,直接将`offline_config.json`拖到`wvguesser_v1.2.0.exe`上即可
2020

2121
运行程序,等待解密
2222

2323
- `python -m wvguesser.mainv2`
2424

2525
根据现有算法,只能是单线程
2626

27-
演示
27+
效果演示,3600X三分钟左右出结果
2828

29-
![](/images/oCam_2021_07_30_20_58_41_915.gif)
29+
![](/images/oCam_2021_07_31_05_10_50_756.gif)
3030

3131
# main.exe
3232

@@ -39,7 +39,7 @@ g++ -o main -pthread -std=gnu++0x -static main.cpp misc.cpp codelift.cpp algebra
3939
# 打包
4040

4141
```bash
42-
pyinstaller -n wvguesser_v1.1.0 -F wvguesser\__main__.py
42+
pyinstaller -n wvguesser_v1.2.0 -F wvguesser\__main__.py
4343
```
4444

4545
# 推荐更好的方案

guesskey/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ int main(int argc,char **argv)
6060
std::string::size_type sz;
6161
int port = std::stoi(argv[1], &sz);
6262
cout << "listen at:" << port << endl;
63-
SocketServer in(port, 5);
63+
SocketServer in(port, 10);
6464
while (1) {
6565
Socket* s=in.Accept();
6666
unsigned ret;
-1.59 MB
Binary file not shown.
1.34 MB
Loading

main.exe

0 Bytes
Binary file not shown.

wvguesser/mainv2.py

Lines changed: 90 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,110 @@
66
import socket
77
import binascii
88
import subprocess
9+
from typing import List
10+
from concurrent.futures import ThreadPoolExecutor
911
from pathlib import Path
1012
from random import randint
1113
from Crypto.Cipher import AES
1214
from Crypto.Hash import CMAC
1315

1416

15-
port = randint(20000, 50000)
16-
MAIN_EXE = (Path('.') / 'main.exe').resolve().as_posix()
17-
p = subprocess.Popen(f'{MAIN_EXE} {port}', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
18-
time.sleep(1)
19-
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
20-
client.connect(('127.0.0.1', port))
17+
servers = []
18+
clients = []
19+
for i in range(5):
20+
port = randint(20000, 50000)
21+
MAIN_EXE = (Path('.') / 'main.exe').resolve().as_posix()
22+
p = subprocess.Popen(f'{MAIN_EXE} {port}', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
23+
servers.append(p)
24+
time.sleep(0.3)
25+
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
26+
client.connect(('127.0.0.1', port))
27+
clients.append(client)
2128

2229

2330
def handle_exit(signum, frame):
24-
p.kill()
31+
close()
2532

2633

27-
def call_func(msg: bytes):
28-
client.send(msg.encode("utf-8"))
34+
def close():
35+
try:
36+
[p.close() for p in clients]
37+
[p.kill() for p in servers]
38+
except Exception:
39+
pass
40+
41+
42+
def call_func(client, msg: bytes):
43+
client.send(msg)
2944
resp = client.recv(1024)
3045
return resp.decode('utf-8').strip()
3146

3247

33-
def guessInput(text: str):
34-
return call_func(f'guessInput|{text}\n')
48+
def multi_guessInput(bufs: List[bytes]):
49+
results = []
50+
with ThreadPoolExecutor(max_workers=5) as executor:
51+
results = executor.map(guessInput, clients, bufs)
52+
return results
53+
54+
55+
def guessInput(client, buf: bytes):
56+
# return call_func(client, f'guessInput|{buf}\n')
57+
return call_func(client, b'guessInput|' + buf + b'\n')
58+
59+
60+
def getDeoaep(client, buf: bytes):
61+
# return call_func(client, f'getDeoaep|{buf}\n')
62+
return call_func(client, b'getDeoaep|' + buf + b'\n')
3563

3664

37-
def getDeoaep(text: str):
38-
return call_func(f'getDeoaep|{text}\n')
65+
def runv2(hex_session_key: str):
66+
ts = time.time()
67+
encKey = binascii.a2b_hex(hex_session_key)
68+
print(hex_session_key)
69+
buf = [0] * 1026
70+
offset = 2
71+
while offset < 1026:
72+
print(f'[Progress] {(offset - 2) / 1024 * 100:.2f}% time used {time.time() - ts:.2f}s')
73+
bt = math.floor((offset - 2) / 4)
74+
offs = math.floor((offset - 2) % 4)
75+
desired = (encKey[len(encKey) - bt - 1] >> (offs * 2)) & 3
76+
destail = hex_session_key[len(hex_session_key) - bt * 2:len(hex_session_key)]
77+
bufs = []
78+
j = buf[offset]
79+
for _j in range(5):
80+
buf[offset] = _j
81+
bufs.append(binascii.b2a_hex(bytes(buf)))
82+
for _j, val in enumerate(multi_guessInput(bufs)):
83+
sub = int(val[len(val) - bt * 2 - 2:len(val) - bt * 2], 16)
84+
got = (sub >> (offs * 2)) & 3
85+
gtail = val[len(hex_session_key) - bt * 2:len(hex_session_key) + bt * 2]
86+
if got == desired and gtail == destail:
87+
buf[offset] = _j
88+
j = buf[offset]
89+
break
90+
if j == 8:
91+
buf[offset] = 0
92+
offset -= 1
93+
if offset < 2:
94+
print('Could not match input')
95+
assert 1 == 0, "Could not find proper input encoding"
96+
buf[offset] += 1
97+
while buf[offset] == 8:
98+
buf[offset] = 0
99+
offset -= 1
100+
if offset < 2:
101+
print('Could not match input')
102+
assert 1 == 0, "Could not find proper input encoding"
103+
buf[offset] += 1
104+
else:
105+
offset += 1
106+
print(f'==> time used {time.time() - ts:.2f}s')
107+
print("Output", buf)
108+
outp = getDeoaep(clients[0], binascii.b2a_hex(bytes(buf)))
109+
print(outp)
110+
if len(outp) < 10:
111+
assert 1 == 0, 'Could not remove padding, probably invalid key'
112+
return outp
39113

40114

41115
def run(hex_session_key: str):
@@ -87,7 +161,6 @@ def run(hex_session_key: str):
87161
if len(outp) < 10:
88162
assert 1 == 0, 'Could not remove padding, probably invalid key'
89163
print(st)
90-
p.kill()
91164
return outp
92165

93166

@@ -110,9 +183,10 @@ def main():
110183
if len(sys.argv) == 2:
111184
path = sys.argv[1]
112185
else:
113-
path = (Path('.') / 'offline_config_yk.json').resolve().as_posix()
186+
path = (Path('.') / 'offline_config.json').resolve().as_posix()
114187
config = json.loads(Path(path).read_text(encoding='utf-8'))
115-
clear_session_key = run(config['enc_session_key'])
188+
clear_session_key = runv2(config['enc_session_key'])
189+
close()
116190
decrypt_license_keys(clear_session_key, config['enc_key'], config['key_infos'])
117191
sys.stdin.read()
118192

0 commit comments

Comments
 (0)