2021-11-20 19:14:59 +06:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2023-02-24 19:11:15 +06:00
|
|
|
'''
|
|
|
|
Copyright (c) 2021-2023 Leseratte10
|
|
|
|
This file is part of the ACSM Input Plugin by Leseratte10
|
|
|
|
ACSM Input Plugin for Calibre / acsm-calibre-plugin
|
|
|
|
|
|
|
|
For more information, see:
|
|
|
|
https://github.com/Leseratte10/acsm-calibre-plugin
|
|
|
|
'''
|
|
|
|
|
2022-01-16 22:43:29 +06:00
|
|
|
#@@CALIBRE_COMPAT_CODE@@
|
2021-11-20 19:14:59 +06:00
|
|
|
|
2022-10-23 14:04:26 +06:00
|
|
|
import sys, binascii, traceback
|
2021-11-25 14:15:37 +06:00
|
|
|
|
2022-06-21 12:15:09 +06:00
|
|
|
def GetMasterKey(wineprefix):
|
2021-11-20 19:14:59 +06:00
|
|
|
import subprocess, os, re
|
|
|
|
|
2021-11-25 14:15:37 +06:00
|
|
|
verbose_logging = False
|
|
|
|
try:
|
|
|
|
import calibre_plugins.deacsm.prefs as prefs
|
2022-09-05 22:34:40 +06:00
|
|
|
deacsmprefs = prefs.ACSMInput_Prefs()
|
2021-11-25 14:15:37 +06:00
|
|
|
verbose_logging = deacsmprefs["detailed_logging"]
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
2021-11-20 19:14:59 +06:00
|
|
|
print("Asking WINE to decrypt encrypted key for us ...")
|
|
|
|
|
|
|
|
if wineprefix == "" or not os.path.exists(wineprefix):
|
2022-06-21 12:15:09 +06:00
|
|
|
print("Wineprefix not found!")
|
2021-11-20 19:14:59 +06:00
|
|
|
return None
|
|
|
|
|
|
|
|
|
|
|
|
# Default to win32 binary, unless we find arch in registry
|
|
|
|
winearch = "win32"
|
|
|
|
|
|
|
|
try:
|
|
|
|
system_registry_path = os.path.join(wineprefix, "system.reg")
|
|
|
|
regfile = open(system_registry_path, "r")
|
|
|
|
while True:
|
|
|
|
line = regfile.readline()
|
|
|
|
if not line:
|
|
|
|
break
|
|
|
|
|
2022-06-21 12:15:09 +06:00
|
|
|
archkey = re.match(r'#arch=(win32|win64)', line)
|
|
|
|
if (archkey):
|
|
|
|
winearch = archkey.groups()[0]
|
2021-11-20 19:14:59 +06:00
|
|
|
break
|
|
|
|
regfile.close()
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
env_dict = os.environ
|
|
|
|
env_dict["PYTHONPATH"] = ""
|
|
|
|
env_dict["WINEPREFIX"] = wineprefix
|
2021-11-25 14:15:37 +06:00
|
|
|
#env_dict["WINEDEBUG"] = "-all,+crypt"
|
|
|
|
env_dict["WINEDEBUG"] = "+err,+fixme"
|
2021-11-20 19:14:59 +06:00
|
|
|
|
|
|
|
try:
|
|
|
|
from calibre.utils.config import config_dir
|
2022-10-08 21:51:15 +06:00
|
|
|
from calibre_plugins.deacsm.__init__ import maindir as plg_maindir
|
|
|
|
|
|
|
|
if plg_maindir is not None:
|
|
|
|
print("FOUND MOD DIR!")
|
|
|
|
moddir = os.path.join(plg_maindir,"modules")
|
|
|
|
else:
|
|
|
|
pluginsdir = os.path.join(config_dir,"plugins")
|
|
|
|
maindir = os.path.join(pluginsdir,"ACSMInput")
|
|
|
|
moddir = os.path.join(maindir,"modules")
|
2021-11-20 19:14:59 +06:00
|
|
|
except:
|
|
|
|
import os
|
2021-11-25 14:15:37 +06:00
|
|
|
moddir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "keyextract")
|
2021-11-20 19:14:59 +06:00
|
|
|
|
2022-10-23 14:04:26 +06:00
|
|
|
|
|
|
|
# extract the EXE file from Python code:
|
|
|
|
# EXE files are obfuscated with base64 so that stupid AV programs
|
|
|
|
# don't flag this whole plugin as malicious.
|
|
|
|
# See keyextractDecryptor.py and the folder "keyextract" for more information.
|
|
|
|
|
|
|
|
try:
|
|
|
|
print("Extracting WINE key tools ...")
|
|
|
|
from keyextractDecryptor import get_win32_data, get_win64_data
|
|
|
|
|
|
|
|
if winearch == "win32":
|
|
|
|
file32 = os.path.join(moddir, "decrypt_win32.exe")
|
|
|
|
f = open(file32, "wb")
|
|
|
|
f.write(get_win32_data())
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
elif winearch == "win64":
|
|
|
|
file64 = os.path.join(moddir, "decrypt_win64.exe")
|
|
|
|
f = open(file64, "wb")
|
|
|
|
f.write(get_win64_data())
|
|
|
|
f.close()
|
|
|
|
|
|
|
|
else:
|
|
|
|
print("Invalid winearch: " + str(winearch))
|
|
|
|
|
|
|
|
except:
|
|
|
|
print("Error while extracting packed WINE ADE key extraction EXE files ")
|
|
|
|
traceback.print_exc()
|
|
|
|
|
2021-11-20 19:14:59 +06:00
|
|
|
# calls decrypt_win32.exe or decrypt_win64.exe
|
2022-06-21 11:03:54 +06:00
|
|
|
proc = subprocess.Popen(["wine", "decrypt_" + winearch + ".exe"], shell=False, cwd=moddir, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
2022-06-21 12:15:09 +06:00
|
|
|
prog_stdout, prog_stderr = proc.communicate()
|
|
|
|
|
|
|
|
if verbose_logging:
|
|
|
|
print("Stderr log:\n{}".format(prog_stderr.decode("utf-8")))
|
|
|
|
print("Stdout log: {}".format(prog_stdout.decode("utf-8")))
|
|
|
|
print("Exit code: {}".format(proc.returncode))
|
2021-11-20 19:14:59 +06:00
|
|
|
|
2022-06-21 12:15:09 +06:00
|
|
|
if proc.returncode == 0:
|
2021-11-25 14:15:37 +06:00
|
|
|
if verbose_logging:
|
2022-06-21 12:15:09 +06:00
|
|
|
print("Successfully got encryption key from WINE: {}".format(prog_stdout.decode("utf-8")))
|
2021-11-25 14:15:37 +06:00
|
|
|
else:
|
|
|
|
print("Successfully got encryption key from WINE.")
|
2022-06-21 12:15:09 +06:00
|
|
|
master_key = binascii.unhexlify(prog_stdout)
|
|
|
|
return master_key
|
2021-11-20 19:14:59 +06:00
|
|
|
else:
|
2022-06-21 12:15:09 +06:00
|
|
|
print("Failed to extract encryption key from WINE.")
|
|
|
|
print("Exit code: {}".format(proc.returncode))
|
2021-11-25 14:15:37 +06:00
|
|
|
|
2022-06-21 11:03:54 +06:00
|
|
|
|
2022-06-21 12:15:09 +06:00
|
|
|
return None
|
2021-11-20 19:14:59 +06:00
|
|
|
|
|
|
|
|
2021-11-25 14:15:37 +06:00
|
|
|
if __name__ == "__main__":
|
|
|
|
print("Do not execute this directly!")
|
|
|
|
exit()
|