mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-28 08:04:13 +08:00
fix
1 Update winsharedutils.py 1 1 1 Update texthook.py Update static_data.json
This commit is contained in:
parent
6cec2a00bc
commit
072cf92917
@ -551,8 +551,8 @@ class WebivewWidget(QWidget):
|
|||||||
|
|
||||||
self.webview = _Webview(debug=debug, window=int(self.winId()))
|
self.webview = _Webview(debug=debug, window=int(self.winId()))
|
||||||
|
|
||||||
# self.webview.bind("__on_load", self._on_load)
|
self.webview.bind("__on_load", self._on_load)
|
||||||
# self.webview.init("""window.__on_load(window.location.href)""")
|
self.webview.init("""window.__on_load(window.location.href)""")
|
||||||
|
|
||||||
def _on_load(self, _, href):
|
def _on_load(self, _, href):
|
||||||
self.on_load.emit(json.loads(href)[0])
|
self.on_load.emit(json.loads(href)[0])
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
from libcurl import *
|
from libcurl import *
|
||||||
import winsharedutils
|
import threading, functools, queue
|
||||||
import threading
|
from ctypes import c_long, cast, pointer, POINTER, c_char
|
||||||
from ctypes import c_long, cast, pointer, POINTER
|
|
||||||
from network.requests_common import *
|
from network.requests_common import *
|
||||||
from traceback import print_exc
|
from traceback import print_exc
|
||||||
|
|
||||||
@ -25,9 +24,8 @@ class Response(ResponseBase):
|
|||||||
downloadeddata = b""
|
downloadeddata = b""
|
||||||
canend = False
|
canend = False
|
||||||
allbs = 0
|
allbs = 0
|
||||||
while not (self.cqueue.empty() and canend):
|
while not (self.queue.empty() and canend):
|
||||||
buff = self.cqueue.get()
|
buff = self.queue.get()
|
||||||
|
|
||||||
if buff is None:
|
if buff is None:
|
||||||
canend = True
|
canend = True
|
||||||
continue
|
continue
|
||||||
@ -174,23 +172,33 @@ class Session(Sessionbase):
|
|||||||
resp = Response()
|
resp = Response()
|
||||||
|
|
||||||
if stream:
|
if stream:
|
||||||
resp.cqueue = winsharedutils.lockedqueue()
|
|
||||||
curl_easy_setopt(curl, CURLoption.CURLOPT_WRITEDATA, resp.cqueue.ptr)
|
def WriteMemoryCallback(queue, contents, size, nmemb, userp):
|
||||||
|
realsize = size * nmemb
|
||||||
|
queue.put(cast(contents, POINTER(c_char))[:realsize])
|
||||||
|
return realsize
|
||||||
|
|
||||||
|
_content = []
|
||||||
|
_headers = []
|
||||||
|
resp.queue = queue.Queue()
|
||||||
|
headerqueue = queue.Queue()
|
||||||
|
resp.keepref1 = WRITEFUNCTION(
|
||||||
|
functools.partial(WriteMemoryCallback, resp.queue)
|
||||||
|
)
|
||||||
|
resp.keepref2 = WRITEFUNCTION(
|
||||||
|
functools.partial(WriteMemoryCallback, headerqueue)
|
||||||
|
)
|
||||||
curl_easy_setopt(
|
curl_easy_setopt(
|
||||||
curl,
|
curl,
|
||||||
CURLoption.CURLOPT_WRITEFUNCTION,
|
CURLoption.CURLOPT_WRITEFUNCTION,
|
||||||
winsharedutils.WriteMemoryToQueue,
|
cast(resp.keepref1, c_void_p).value,
|
||||||
)
|
)
|
||||||
|
|
||||||
headercqueue = winsharedutils.lockedqueue()
|
|
||||||
curl_easy_setopt(curl, CURLoption.CURLOPT_HEADERDATA, headercqueue.ptr)
|
|
||||||
curl_easy_setopt(
|
curl_easy_setopt(
|
||||||
curl,
|
curl,
|
||||||
CURLoption.CURLOPT_HEADERFUNCTION,
|
CURLoption.CURLOPT_HEADERFUNCTION,
|
||||||
winsharedutils.WriteMemoryToQueue,
|
cast(resp.keepref2, c_void_p).value,
|
||||||
)
|
)
|
||||||
headerok = threading.Lock()
|
|
||||||
headerok.acquire()
|
|
||||||
|
|
||||||
def ___perform():
|
def ___perform():
|
||||||
try:
|
try:
|
||||||
@ -198,31 +206,22 @@ class Session(Sessionbase):
|
|||||||
except:
|
except:
|
||||||
print_exc()
|
print_exc()
|
||||||
self.raise_for_status()
|
self.raise_for_status()
|
||||||
headercqueue.pushnone()
|
headerqueue.put(None)
|
||||||
headerok.acquire()
|
|
||||||
curl_easy_reset(curl)
|
curl_easy_reset(curl)
|
||||||
resp.cqueue.pushnone()
|
resp.queue.put(None)
|
||||||
|
|
||||||
threading.Thread(target=___perform, daemon=True).start()
|
threading.Thread(target=___perform, daemon=True).start()
|
||||||
|
|
||||||
headerb = b""
|
headerb = b""
|
||||||
CLRFnum = 1 + int(bool((proxy)))
|
|
||||||
while True:
|
while True:
|
||||||
_headerb = headercqueue.get()
|
_headerb = headerqueue.get()
|
||||||
if _headerb is None:
|
if _headerb is None:
|
||||||
self.raise_for_status()
|
self.raise_for_status()
|
||||||
headerb += _headerb
|
headerb += _headerb
|
||||||
if _headerb == b"\r\n":
|
if _headerb == b"\r\n":
|
||||||
# 使用代理时:
|
break
|
||||||
# b'HTTP/1.1 200 Connection established\r\n'
|
|
||||||
# b'\r\n'
|
|
||||||
CLRFnum -= 1
|
|
||||||
if CLRFnum == 0:
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
headerb = b""
|
|
||||||
resp.headers = self._update_header_cookie(headerb.decode("utf8"))
|
resp.headers = self._update_header_cookie(headerb.decode("utf8"))
|
||||||
headerok.release()
|
|
||||||
if proxy:
|
if proxy:
|
||||||
resp.status_code = int(
|
resp.status_code = int(
|
||||||
headerb.decode("utf8").split("\r\n")[0].split(" ")[1]
|
headerb.decode("utf8").split("\r\n")[0].split(" ")[1]
|
||||||
@ -230,24 +229,35 @@ class Session(Sessionbase):
|
|||||||
else:
|
else:
|
||||||
resp.status_code = self._getStatusCode(curl)
|
resp.status_code = self._getStatusCode(curl)
|
||||||
else:
|
else:
|
||||||
_content = winsharedutils.MemoryStruct()
|
|
||||||
curl_easy_setopt(curl, CURLoption.CURLOPT_WRITEDATA, pointer(_content))
|
def WriteMemoryCallback(saver, contents, size, nmemb, userp):
|
||||||
|
realsize = size * nmemb
|
||||||
|
saver.append(cast(contents, POINTER(c_char))[:realsize])
|
||||||
|
return realsize
|
||||||
|
|
||||||
|
_content = []
|
||||||
|
_headers = []
|
||||||
|
resp.keepref1 = WRITEFUNCTION(
|
||||||
|
functools.partial(WriteMemoryCallback, _content)
|
||||||
|
)
|
||||||
|
resp.keepref2 = WRITEFUNCTION(
|
||||||
|
functools.partial(WriteMemoryCallback, _headers)
|
||||||
|
)
|
||||||
|
|
||||||
curl_easy_setopt(
|
curl_easy_setopt(
|
||||||
curl,
|
curl,
|
||||||
CURLoption.CURLOPT_WRITEFUNCTION,
|
CURLoption.CURLOPT_WRITEFUNCTION,
|
||||||
winsharedutils.WriteMemoryCallback,
|
cast(resp.keepref1, c_void_p).value,
|
||||||
)
|
)
|
||||||
_headers = winsharedutils.MemoryStruct()
|
|
||||||
curl_easy_setopt(curl, CURLoption.CURLOPT_HEADERDATA, pointer(_headers))
|
|
||||||
curl_easy_setopt(
|
curl_easy_setopt(
|
||||||
curl,
|
curl,
|
||||||
CURLoption.CURLOPT_HEADERFUNCTION,
|
CURLoption.CURLOPT_HEADERFUNCTION,
|
||||||
winsharedutils.WriteMemoryCallback,
|
cast(resp.keepref2, c_void_p).value,
|
||||||
)
|
)
|
||||||
# curl_easy_setopt(curl,CURLoption.CURLOPT_HEADERFUNCTION,cast(WRITEFUNCTION(WRITEFUNCTIONXX),c_void_p))
|
|
||||||
self._perform(curl)
|
self._perform(curl)
|
||||||
resp.content = _content.get()
|
resp.content = b"".join(_content)
|
||||||
resp.headers = self._update_header_cookie(_headers.get().decode("utf8"))
|
resp.headers = self._update_header_cookie(b"".join(_headers).decode("utf8"))
|
||||||
resp.status_code = self._getStatusCode(curl)
|
resp.status_code = self._getStatusCode(curl)
|
||||||
curl_easy_reset(curl)
|
curl_easy_reset(curl)
|
||||||
resp.last_error = self.last_error
|
resp.last_error = self.last_error
|
||||||
|
@ -12,11 +12,13 @@ from myutils.hwnd import injectdll
|
|||||||
from myutils.wrapper import threader
|
from myutils.wrapper import threader
|
||||||
from ctypes import (
|
from ctypes import (
|
||||||
CDLL,
|
CDLL,
|
||||||
|
CFUNCTYPE,
|
||||||
c_bool,
|
c_bool,
|
||||||
POINTER,
|
POINTER,
|
||||||
Structure,
|
Structure,
|
||||||
c_int,
|
c_int,
|
||||||
pointer,
|
pointer,
|
||||||
|
c_char_p,
|
||||||
c_wchar_p,
|
c_wchar_p,
|
||||||
c_uint64,
|
c_uint64,
|
||||||
sizeof,
|
sizeof,
|
||||||
@ -71,21 +73,13 @@ class SearchParam(Structure):
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
class Message(Structure):
|
findhookcallback_t = CFUNCTYPE(None, c_wchar_p, c_wchar_p)
|
||||||
_fields_ = [
|
ProcessEvent = CFUNCTYPE(None, DWORD)
|
||||||
("read", c_bool),
|
ThreadEvent = CFUNCTYPE(None, c_wchar_p, c_char_p, ThreadParam)
|
||||||
("type", c_int),
|
OutputCallback = CFUNCTYPE(None, c_wchar_p, c_char_p, ThreadParam, c_wchar_p)
|
||||||
("pid", DWORD),
|
ConsoleHandler = CFUNCTYPE(None, c_wchar_p)
|
||||||
("hn", c_char * HOOK_NAME_SIZE),
|
HookInsertHandler = CFUNCTYPE(None, c_uint64, c_wchar_p)
|
||||||
("hc", c_wchar * HOOKCODE_LEN),
|
EmbedCallback = CFUNCTYPE(None, c_wchar_p, ThreadParam)
|
||||||
("tp", ThreadParam),
|
|
||||||
("stringptr", c_void_p),
|
|
||||||
("addr", c_uint64),
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class simplehooks(Structure):
|
|
||||||
_fields_ = [("hookcode", c_wchar * 500), ("text", c_void_p)]
|
|
||||||
|
|
||||||
|
|
||||||
class texthook(basetext):
|
class texthook(basetext):
|
||||||
@ -96,7 +90,7 @@ class texthook(basetext):
|
|||||||
autostarthookcode = []
|
autostarthookcode = []
|
||||||
if needinserthookcode is None:
|
if needinserthookcode is None:
|
||||||
needinserthookcode = []
|
needinserthookcode = []
|
||||||
|
self.keepref = []
|
||||||
self.newline = Queue()
|
self.newline = Queue()
|
||||||
self.newline_delaywait = Queue()
|
self.newline_delaywait = Queue()
|
||||||
self.is64bit = Is64bit(pids[0])
|
self.is64bit = Is64bit(pids[0])
|
||||||
@ -147,7 +141,16 @@ class texthook(basetext):
|
|||||||
self.Luna_Settings = LunaHost.Luna_Settings
|
self.Luna_Settings = LunaHost.Luna_Settings
|
||||||
self.Luna_Settings.argtypes = c_int, c_bool, c_int, c_int
|
self.Luna_Settings.argtypes = c_int, c_bool, c_int, c_int
|
||||||
self.Luna_Start = LunaHost.Luna_Start
|
self.Luna_Start = LunaHost.Luna_Start
|
||||||
self.Luna_Start.argtypes = (POINTER(HANDLE),)
|
self.Luna_Start.argtypes = (
|
||||||
|
c_void_p,
|
||||||
|
c_void_p,
|
||||||
|
c_void_p,
|
||||||
|
c_void_p,
|
||||||
|
c_void_p,
|
||||||
|
c_void_p,
|
||||||
|
c_void_p,
|
||||||
|
c_void_p,
|
||||||
|
)
|
||||||
self.Luna_Inject = LunaHost.Luna_Inject
|
self.Luna_Inject = LunaHost.Luna_Inject
|
||||||
self.Luna_Inject.argtypes = DWORD, LPCWSTR
|
self.Luna_Inject.argtypes = DWORD, LPCWSTR
|
||||||
self.Luna_CreatePipeAndCheck = LunaHost.Luna_CreatePipeAndCheck
|
self.Luna_CreatePipeAndCheck = LunaHost.Luna_CreatePipeAndCheck
|
||||||
@ -160,17 +163,12 @@ class texthook(basetext):
|
|||||||
self.Luna_RemoveHook.argtypes = DWORD, c_uint64
|
self.Luna_RemoveHook.argtypes = DWORD, c_uint64
|
||||||
self.Luna_Detach = LunaHost.Luna_Detach
|
self.Luna_Detach = LunaHost.Luna_Detach
|
||||||
self.Luna_Detach.argtypes = (DWORD,)
|
self.Luna_Detach.argtypes = (DWORD,)
|
||||||
self.Luna_cfree = LunaHost.Luna_cfree
|
|
||||||
self.Luna_cfree.argtypes = (c_void_p,)
|
|
||||||
self.Luna_FindHooks = LunaHost.Luna_FindHooks
|
self.Luna_FindHooks = LunaHost.Luna_FindHooks
|
||||||
self.Luna_FindHooks.argtypes = (
|
self.Luna_FindHooks.argtypes = (
|
||||||
DWORD,
|
DWORD,
|
||||||
SearchParam,
|
SearchParam,
|
||||||
POINTER(HANDLE),
|
c_void_p,
|
||||||
POINTER(POINTER(c_int)),
|
|
||||||
)
|
)
|
||||||
self.Luna_FindHooks_waiting = LunaHost.Luna_FindHooks_waiting
|
|
||||||
self.Luna_FindHooks_waiting.argtypes = (POINTER(c_int),)
|
|
||||||
self.Luna_EmbedSettings = LunaHost.Luna_EmbedSettings
|
self.Luna_EmbedSettings = LunaHost.Luna_EmbedSettings
|
||||||
self.Luna_EmbedSettings.argtypes = (
|
self.Luna_EmbedSettings.argtypes = (
|
||||||
DWORD,
|
DWORD,
|
||||||
@ -190,10 +188,24 @@ class texthook(basetext):
|
|||||||
self.Luna_embedcallback = LunaHost.Luna_embedcallback
|
self.Luna_embedcallback = LunaHost.Luna_embedcallback
|
||||||
self.Luna_embedcallback.argtypes = DWORD, LPCWSTR, LPCWSTR
|
self.Luna_embedcallback.argtypes = DWORD, LPCWSTR, LPCWSTR
|
||||||
|
|
||||||
|
def Luna_Startup(self):
|
||||||
|
procs = [
|
||||||
|
ProcessEvent(self.onprocconnect),
|
||||||
|
ProcessEvent(self.connectedpids.remove),
|
||||||
|
ThreadEvent(self.onnewhook),
|
||||||
|
ThreadEvent(lambda _1, _2, tp: self.onremovehook(tp)),
|
||||||
|
OutputCallback(self.handle_output),
|
||||||
|
ConsoleHandler(gobject.baseobject.hookselectdialog.sysmessagesignal.emit),
|
||||||
|
HookInsertHandler(self.newhookinsert),
|
||||||
|
EmbedCallback(self.getembedtext),
|
||||||
|
]
|
||||||
|
self.keepref += procs
|
||||||
|
ptrs = [cast(_, c_void_p).value for _ in procs]
|
||||||
|
self.Luna_Start(*ptrs)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.hRead = HANDLE()
|
|
||||||
self.Luna_Start(pointer(self.hRead))
|
self.Luna_Startup()
|
||||||
self.solveeventthread()
|
|
||||||
self.setsettings()
|
self.setsettings()
|
||||||
|
|
||||||
injectpids = []
|
injectpids = []
|
||||||
@ -216,7 +228,6 @@ class texthook(basetext):
|
|||||||
# subprocess.Popen('"{}" dllinject {} "{}"'.format(injecter,pid,dll))
|
# subprocess.Popen('"{}" dllinject {} "{}"'.format(injecter,pid,dll))
|
||||||
injectdll(injectpids, injecter, dll)
|
injectdll(injectpids, injecter, dll)
|
||||||
|
|
||||||
@threader
|
|
||||||
def onprocconnect(self, pid):
|
def onprocconnect(self, pid):
|
||||||
self.connectedpids.append(pid)
|
self.connectedpids.append(pid)
|
||||||
time.sleep(savehook_new_data[self.pname]["inserthooktimeout"] / 1000)
|
time.sleep(savehook_new_data[self.pname]["inserthooktimeout"] / 1000)
|
||||||
@ -225,45 +236,6 @@ class texthook(basetext):
|
|||||||
self.showgamename()
|
self.showgamename()
|
||||||
self.flashembedsettings(pid)
|
self.flashembedsettings(pid)
|
||||||
|
|
||||||
@threader
|
|
||||||
def solveeventthread(self):
|
|
||||||
while self.ending == False:
|
|
||||||
message = windows.ReadFile(self.hRead, sizeof(Message))
|
|
||||||
if len(message) != sizeof(Message):
|
|
||||||
break
|
|
||||||
message = Message.from_buffer_copy(message)
|
|
||||||
_type = message.type
|
|
||||||
if _type in [0, 1]:
|
|
||||||
pid = message.pid
|
|
||||||
if _type == 0:
|
|
||||||
self.onprocconnect(pid)
|
|
||||||
elif _type == 1:
|
|
||||||
self.connectedpids.remove(pid)
|
|
||||||
elif _type in [2, 3]:
|
|
||||||
if _type == 2:
|
|
||||||
self.onnewhook(message.hc, message.hn, message.tp)
|
|
||||||
elif _type == 3:
|
|
||||||
self.onremovehook(message.tp)
|
|
||||||
elif _type == 4:
|
|
||||||
self.handle_output(
|
|
||||||
message.hc,
|
|
||||||
message.hn,
|
|
||||||
message.tp,
|
|
||||||
cast(message.stringptr, c_wchar_p).value,
|
|
||||||
)
|
|
||||||
elif _type == 5:
|
|
||||||
gobject.baseobject.hookselectdialog.sysmessagesignal.emit(
|
|
||||||
cast(message.stringptr, c_wchar_p).value
|
|
||||||
)
|
|
||||||
elif _type == 6:
|
|
||||||
self.newhookinsert(
|
|
||||||
message.addr, cast(message.stringptr, c_wchar_p).value
|
|
||||||
)
|
|
||||||
elif _type == 7:
|
|
||||||
self.getembedtext(cast(message.stringptr, c_wchar_p).value, message.tp)
|
|
||||||
if message.stringptr:
|
|
||||||
self.Luna_cfree(message.stringptr)
|
|
||||||
|
|
||||||
def newhookinsert(self, addr, hcode):
|
def newhookinsert(self, addr, hcode):
|
||||||
for _hc, _addr, _ctx1, _ctx2 in savehook_new_data[self.pname]["embedablehook"]:
|
for _hc, _addr, _ctx1, _ctx2 in savehook_new_data[self.pname]["embedablehook"]:
|
||||||
if hcode == _hc:
|
if hcode == _hc:
|
||||||
@ -415,32 +387,24 @@ class texthook(basetext):
|
|||||||
def findhook(self, usestruct):
|
def findhook(self, usestruct):
|
||||||
savefound = {}
|
savefound = {}
|
||||||
pids = self.connectedpids.copy()
|
pids = self.connectedpids.copy()
|
||||||
|
cntref = []
|
||||||
|
|
||||||
headers = {}
|
def __callback(cntref, hcode, text):
|
||||||
waiters = {}
|
if hcode not in savefound:
|
||||||
|
savefound[hcode] = []
|
||||||
|
savefound[hcode].append(text)
|
||||||
|
cntref.append(0)
|
||||||
|
|
||||||
|
_callback = findhookcallback_t(functools.partial(__callback, cntref))
|
||||||
|
self.keepref.append(_callback)
|
||||||
for pid in pids:
|
for pid in pids:
|
||||||
headers[pid] = HANDLE()
|
self.Luna_FindHooks(pid, usestruct, cast(_callback, c_void_p).value)
|
||||||
count = POINTER(c_int)()
|
|
||||||
waiters[pid] = count
|
|
||||||
self.Luna_FindHooks(pid, usestruct, pointer(headers[pid]), pointer(count))
|
|
||||||
|
|
||||||
def ReadThread(hread):
|
while True:
|
||||||
while True:
|
lastsize = len(cntref)
|
||||||
message = windows.ReadFile(hread, sizeof(simplehooks))
|
time.sleep(2)
|
||||||
if len(message) != sizeof(simplehooks):
|
if lastsize == len(cntref) and lastsize != 0:
|
||||||
break
|
break
|
||||||
message = simplehooks.from_buffer_copy(message)
|
|
||||||
hc = message.hookcode
|
|
||||||
text = cast(message.text, c_wchar_p).value
|
|
||||||
if hc not in savefound:
|
|
||||||
savefound[hc] = []
|
|
||||||
savefound[hc].append(text)
|
|
||||||
self.Luna_cfree(message.text)
|
|
||||||
windows.CloseHandle(hread)
|
|
||||||
|
|
||||||
threading.Thread(target=ReadThread, args=(headers[pid],)).start()
|
|
||||||
for pid in pids:
|
|
||||||
self.Luna_FindHooks_waiting(waiters[pid])
|
|
||||||
gobject.baseobject.hookselectdialog.getfoundhooksignal.emit(savefound)
|
gobject.baseobject.hookselectdialog.getfoundhooksignal.emit(savefound)
|
||||||
|
|
||||||
def inserthook(self, hookcode):
|
def inserthook(self, hookcode):
|
||||||
|
@ -238,65 +238,10 @@ def extracticon2data(fname):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
WriteMemoryCallback = utilsdll.WriteMemoryCallback
|
|
||||||
c_free = utilsdll.c_free
|
c_free = utilsdll.c_free
|
||||||
c_free.argtypes = (c_void_p,)
|
c_free.argtypes = (c_void_p,)
|
||||||
|
|
||||||
|
|
||||||
class MemoryStruct(Structure):
|
|
||||||
_fields_ = [("memory", c_void_p), ("size", c_size_t)]
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self.memory = 0
|
|
||||||
self.size = 0
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
if self.memory:
|
|
||||||
c_free(self.memory)
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
return cast(self.memory, POINTER(c_char))[: self.size]
|
|
||||||
|
|
||||||
|
|
||||||
WriteMemoryToQueue = utilsdll.WriteMemoryToQueue
|
|
||||||
lockedqueuecreate = utilsdll.lockedqueuecreate
|
|
||||||
lockedqueuecreate.restype = c_void_p
|
|
||||||
lockedqueuefree = utilsdll.lockedqueuefree
|
|
||||||
lockedqueuefree.argtypes = (c_void_p,)
|
|
||||||
lockedqueueget = utilsdll.lockedqueueget
|
|
||||||
lockedqueueget.argtypes = c_void_p, POINTER(c_size_t)
|
|
||||||
lockedqueueget.restype = c_void_p
|
|
||||||
lockedqueuepush = utilsdll.lockedqueuepush
|
|
||||||
lockedqueuepush.argtypes = c_void_p, c_size_t, c_void_p
|
|
||||||
lockedqueueempty = utilsdll.lockedqueueempty
|
|
||||||
lockedqueueempty.argtypes = (c_void_p,)
|
|
||||||
lockedqueueempty.restype = c_bool
|
|
||||||
|
|
||||||
|
|
||||||
class lockedqueue:
|
|
||||||
def __init__(self) -> None:
|
|
||||||
self.ptr = lockedqueuecreate()
|
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
lockedqueuefree(self.ptr)
|
|
||||||
|
|
||||||
def get(self):
|
|
||||||
sz = c_size_t()
|
|
||||||
dataptr = lockedqueueget(self.ptr, pointer(sz))
|
|
||||||
data = cast(dataptr, POINTER(c_char))[: sz.value]
|
|
||||||
c_free(dataptr)
|
|
||||||
if sz.value == 0:
|
|
||||||
return None
|
|
||||||
return data
|
|
||||||
|
|
||||||
def pushnone(self):
|
|
||||||
lockedqueuepush(self.ptr, 0, b"\0")
|
|
||||||
|
|
||||||
def empty(self):
|
|
||||||
return lockedqueueempty(self.ptr)
|
|
||||||
|
|
||||||
|
|
||||||
_queryversion = utilsdll.queryversion
|
_queryversion = utilsdll.queryversion
|
||||||
_queryversion.restype = c_bool
|
_queryversion.restype = c_bool
|
||||||
_queryversion.argtypes = (
|
_queryversion.argtypes = (
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version":"v2.46.2",
|
"version":"v2.47.0",
|
||||||
"themes":{
|
"themes":{
|
||||||
"dark":[
|
"dark":[
|
||||||
{"file":"dark1.qss","name":"PyQtDarkTheme"},
|
{"file":"dark1.qss","name":"PyQtDarkTheme"},
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
PyQt5==5.15.10
|
PyQt5==5.15.10
|
||||||
PyQt5-Qt5==5.15.2
|
PyQt5-Qt5==5.15.2
|
||||||
webviewpy==1.0.4
|
webviewpy==1.0.5
|
||||||
nuitka==2.0.5
|
nuitka==2.0.5
|
||||||
imageio
|
imageio
|
||||||
pefile
|
pefile
|
@ -102,36 +102,33 @@ struct ThreadParam
|
|||||||
uint64_t ctx; // The context of the hook: by default the first value on stack, usually the return address
|
uint64_t ctx; // The context of the hook: by default the first value on stack, usually the return address
|
||||||
uint64_t ctx2; // The subcontext of the hook: 0 by default, generated in a method specific to the hook
|
uint64_t ctx2; // The subcontext of the hook: 0 by default, generated in a method specific to the hook
|
||||||
};
|
};
|
||||||
struct messagelist
|
typedef void (*ProcessEvent)(DWORD);
|
||||||
{
|
typedef void (*ThreadEvent)(wchar_t *, char *, ThreadParam);
|
||||||
bool read;
|
typedef void (*OutputCallback)(wchar_t *, char *, ThreadParam, const wchar_t *);
|
||||||
int type;
|
typedef void (*ConsoleHandler)(const wchar_t *);
|
||||||
DWORD pid;
|
typedef void (*HookInsertHandler)(uint64_t, const wchar_t *);
|
||||||
char name[HOOK_NAME_SIZE];
|
typedef void (*EmbedCallback)(const wchar_t *, ThreadParam);
|
||||||
wchar_t hookcode[HOOKCODE_LEN];
|
nlohmann::json config;
|
||||||
ThreadParam tp;
|
std::map<std::string, std::string> translation;
|
||||||
wchar_t *stringptr;
|
std::unordered_set<DWORD> connectedpids;
|
||||||
uint64_t addr;
|
void (*Luna_Start)(ProcessEvent Connect, ProcessEvent Disconnect, ThreadEvent Create, ThreadEvent Destroy, OutputCallback Output, ConsoleHandler console, HookInsertHandler hookinsert, EmbedCallback embed);
|
||||||
};
|
void (*Luna_Inject)(DWORD pid, LPCWSTR basepath);
|
||||||
|
void (*Luna_EmbedSettings)(DWORD pid, UINT32 waittime, UINT8 fontCharSet, bool fontCharSetEnabled, wchar_t *fontFamily, UINT32 spaceadjustpolicy, UINT32 keeprawtext, bool fastskipignore);
|
||||||
|
void (*Luna_useembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2, bool use);
|
||||||
|
bool (*Luna_checkisusingembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2);
|
||||||
|
void (*Luna_embedcallback)(DWORD pid, LPCWSTR text, LPCWSTR trans);
|
||||||
|
std::set<std::string> notranslation;
|
||||||
|
HANDLE hsema;
|
||||||
class lunapatch
|
class lunapatch
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
HANDLE hMessage;
|
HANDLE hMessage;
|
||||||
HANDLE hwait;
|
HANDLE hwait;
|
||||||
nlohmann::json config;
|
|
||||||
std::map<std::string, std::string> translation;
|
lunapatch(std::wstring dll, nlohmann::json &&_translation, nlohmann::json &&_config)
|
||||||
std::unordered_set<DWORD> connectedpids;
|
|
||||||
void (*Luna_Start)(HANDLE *hRead);
|
|
||||||
void (*Luna_Inject)(DWORD pid, LPCWSTR basepath);
|
|
||||||
void (*Luna_EmbedSettings)(DWORD pid, UINT32 waittime, UINT8 fontCharSet, bool fontCharSetEnabled, wchar_t *fontFamily, UINT32 spaceadjustpolicy, UINT32 keeprawtext, bool fastskipignore);
|
|
||||||
void (*Luna_useembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2, bool use);
|
|
||||||
bool (*Luna_checkisusingembed)(DWORD pid, uint64_t address, uint64_t ctx1, uint64_t ctx2);
|
|
||||||
void (*Luna_embedcallback)(DWORD pid, LPCWSTR text, LPCWSTR trans);
|
|
||||||
std::set<std::string> notranslation;
|
|
||||||
HANDLE hsema;
|
|
||||||
lunapatch(std::wstring dll, nlohmann::json &&_translation, nlohmann::json &&_config) : translation(_translation), config(_config)
|
|
||||||
{
|
{
|
||||||
|
translation = _translation;
|
||||||
|
config = _config;
|
||||||
auto LunaHost = LoadLibraryW(dll.c_str());
|
auto LunaHost = LoadLibraryW(dll.c_str());
|
||||||
|
|
||||||
Luna_Start = (decltype(Luna_Start))GetProcAddress(LunaHost, "Luna_Start");
|
Luna_Start = (decltype(Luna_Start))GetProcAddress(LunaHost, "Luna_Start");
|
||||||
@ -141,10 +138,54 @@ public:
|
|||||||
Luna_checkisusingembed = (decltype(Luna_checkisusingembed))GetProcAddress(LunaHost, "Luna_checkisusingembed");
|
Luna_checkisusingembed = (decltype(Luna_checkisusingembed))GetProcAddress(LunaHost, "Luna_checkisusingembed");
|
||||||
Luna_embedcallback = (decltype(Luna_embedcallback))GetProcAddress(LunaHost, "Luna_embedcallback");
|
Luna_embedcallback = (decltype(Luna_embedcallback))GetProcAddress(LunaHost, "Luna_embedcallback");
|
||||||
hsema = CreateSemaphore(NULL, 0, 100, NULL);
|
hsema = CreateSemaphore(NULL, 0, 100, NULL);
|
||||||
Luna_Start(&hMessage);
|
Luna_Start(
|
||||||
std::thread([&]()
|
[](DWORD pid)
|
||||||
{ Parsehostmessage(); })
|
{
|
||||||
.detach();
|
auto font = StringToWideString(config["embedsettings"]["font"]);
|
||||||
|
auto insertspace_policy = config["embedsettings"]["insertspace_policy"];
|
||||||
|
auto keeprawtext = config["embedsettings"]["keeprawtext"];
|
||||||
|
Luna_EmbedSettings(pid, 1000, 2, false, font.data(), insertspace_policy, keeprawtext, false);
|
||||||
|
connectedpids.insert(pid);
|
||||||
|
},
|
||||||
|
[](DWORD pid)
|
||||||
|
{
|
||||||
|
connectedpids.erase(pid);
|
||||||
|
ReleaseSemaphore(hsema, 1, NULL);
|
||||||
|
},
|
||||||
|
[](auto, auto, auto) {},
|
||||||
|
[](auto, auto, auto) {},
|
||||||
|
[](auto, auto, auto, auto) {},
|
||||||
|
[](auto) {},
|
||||||
|
[](uint64_t addr, const wchar_t *output)
|
||||||
|
{
|
||||||
|
std::wstring newhookcode = output;
|
||||||
|
for (auto hook : config["embedhook"])
|
||||||
|
{
|
||||||
|
auto hookcode = StringToWideString(hook[0]);
|
||||||
|
uint64_t _addr = hook[1];
|
||||||
|
uint64_t _ctx1 = hook[2];
|
||||||
|
uint64_t _ctx2 = hook[3];
|
||||||
|
if (hookcode == newhookcode)
|
||||||
|
{
|
||||||
|
for (auto pid : connectedpids)
|
||||||
|
{
|
||||||
|
Luna_useembed(pid, addr, _ctx1, _ctx2, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[](const wchar_t *output, ThreadParam tp)
|
||||||
|
{
|
||||||
|
std::wstring text = output;
|
||||||
|
for (auto pid : connectedpids)
|
||||||
|
{
|
||||||
|
if ((Luna_checkisusingembed(pid, tp.addr, tp.ctx, tp.ctx2)))
|
||||||
|
{
|
||||||
|
auto trans = findtranslation(text);
|
||||||
|
Luna_embedcallback(pid, output, trans.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
void run()
|
void run()
|
||||||
{
|
{
|
||||||
@ -194,7 +235,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::wstring findtranslation(const std::wstring &text)
|
static std::wstring findtranslation(const std::wstring &text)
|
||||||
{
|
{
|
||||||
auto utf8text = WideStringToString(text);
|
auto utf8text = WideStringToString(text);
|
||||||
if (translation.find(utf8text) == translation.end())
|
if (translation.find(utf8text) == translation.end())
|
||||||
@ -205,71 +246,6 @@ public:
|
|||||||
}
|
}
|
||||||
return StringToWideString(translation.at(utf8text));
|
return StringToWideString(translation.at(utf8text));
|
||||||
}
|
}
|
||||||
void Parsehostmessage()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
messagelist message;
|
|
||||||
DWORD _;
|
|
||||||
ReadFile(hMessage, &message, sizeof(message), &_, NULL);
|
|
||||||
switch (message.type)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
auto font = StringToWideString(config["embedsettings"]["font"]);
|
|
||||||
auto insertspace_policy = config["embedsettings"]["insertspace_policy"];
|
|
||||||
auto keeprawtext = config["embedsettings"]["keeprawtext"];
|
|
||||||
Luna_EmbedSettings(message.pid, 1000, 2, false, font.data(), insertspace_policy, keeprawtext, false);
|
|
||||||
connectedpids.insert(message.pid);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
connectedpids.erase(message.pid);
|
|
||||||
ReleaseSemaphore(hsema, 1, NULL);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
{
|
|
||||||
std::wstring text = message.stringptr;
|
|
||||||
auto tp = message.tp;
|
|
||||||
for (auto pid : connectedpids)
|
|
||||||
{
|
|
||||||
if ((Luna_checkisusingembed(pid, tp.addr, tp.ctx, tp.ctx2)))
|
|
||||||
{
|
|
||||||
auto trans = findtranslation(text);
|
|
||||||
Luna_embedcallback(pid, text.c_str(), trans.c_str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
{
|
|
||||||
std::wstring newhookcode = message.stringptr;
|
|
||||||
for (auto hook : config["embedhook"])
|
|
||||||
{
|
|
||||||
auto hookcode = StringToWideString(hook[0]);
|
|
||||||
uint64_t _addr = hook[1];
|
|
||||||
uint64_t _ctx1 = hook[2];
|
|
||||||
uint64_t _ctx2 = hook[3];
|
|
||||||
if (hookcode == newhookcode)
|
|
||||||
{
|
|
||||||
for (auto pid : connectedpids)
|
|
||||||
{
|
|
||||||
Luna_useembed(pid, message.addr, _ctx1, _ctx2, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.stringptr)
|
|
||||||
free(message.stringptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
std::wstring GetExecutablePath()
|
std::wstring GetExecutablePath()
|
||||||
{
|
{
|
||||||
|
@ -64,104 +64,7 @@ wchar_t **vecwstr2c(std::vector<std::wstring> &vs)
|
|||||||
return argv;
|
return argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MemoryStruct
|
|
||||||
{
|
|
||||||
char *memory;
|
|
||||||
size_t size;
|
|
||||||
};
|
|
||||||
size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
|
||||||
{
|
|
||||||
size_t realsize = size * nmemb;
|
|
||||||
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
|
|
||||||
|
|
||||||
char *ptr;
|
|
||||||
if (mem->memory)
|
|
||||||
ptr = (char *)realloc(mem->memory, mem->size + realsize + 1);
|
|
||||||
else
|
|
||||||
ptr = (char *)malloc(mem->size + realsize + 1);
|
|
||||||
if (!ptr)
|
|
||||||
{
|
|
||||||
/* out of memory! */
|
|
||||||
printf("not enough memory (realloc returned NULL)\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
mem->memory = ptr;
|
|
||||||
memcpy(&(mem->memory[mem->size]), contents, realsize);
|
|
||||||
mem->size += realsize;
|
|
||||||
mem->memory[mem->size] = 0;
|
|
||||||
|
|
||||||
return realsize;
|
|
||||||
}
|
|
||||||
void c_free(void *ptr)
|
void c_free(void *ptr)
|
||||||
{
|
{
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
class lockedqueue
|
|
||||||
{
|
|
||||||
std::mutex lock;
|
|
||||||
std::queue<std::string> data;
|
|
||||||
HANDLE hsema;
|
|
||||||
|
|
||||||
public:
|
|
||||||
lockedqueue()
|
|
||||||
{
|
|
||||||
hsema = CreateSemaphore(NULL, 0, 65535, NULL);
|
|
||||||
}
|
|
||||||
~lockedqueue()
|
|
||||||
{
|
|
||||||
CloseHandle(hsema);
|
|
||||||
}
|
|
||||||
void push(std::string &&_)
|
|
||||||
{
|
|
||||||
std::lock_guard _l(lock);
|
|
||||||
data.push(std::move(_));
|
|
||||||
ReleaseSemaphore(hsema, 1, NULL);
|
|
||||||
}
|
|
||||||
std::string pop()
|
|
||||||
{
|
|
||||||
WaitForSingleObject(hsema, INFINITE);
|
|
||||||
std::lock_guard _l(lock);
|
|
||||||
auto _ = data.front();
|
|
||||||
data.pop();
|
|
||||||
return _;
|
|
||||||
}
|
|
||||||
bool empty()
|
|
||||||
{
|
|
||||||
std::lock_guard _l(lock);
|
|
||||||
return data.empty();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
void *lockedqueuecreate()
|
|
||||||
{
|
|
||||||
return new lockedqueue();
|
|
||||||
}
|
|
||||||
void lockedqueuefree(void *q)
|
|
||||||
{
|
|
||||||
delete reinterpret_cast<lockedqueue *>(q);
|
|
||||||
}
|
|
||||||
void *lockedqueueget(void *q, size_t *l)
|
|
||||||
{
|
|
||||||
auto data = reinterpret_cast<lockedqueue *>(q)->pop();
|
|
||||||
auto datastatic = new char[data.size()];
|
|
||||||
memcpy(datastatic, data.data(), data.size());
|
|
||||||
*l = data.size();
|
|
||||||
return datastatic;
|
|
||||||
}
|
|
||||||
void lockedqueuepush(void *q, size_t l, void *ptr)
|
|
||||||
{
|
|
||||||
reinterpret_cast<lockedqueue *>(q)->push(std::string((char *)ptr, l));
|
|
||||||
}
|
|
||||||
bool lockedqueueempty(void *q)
|
|
||||||
{
|
|
||||||
return reinterpret_cast<lockedqueue *>(q)->empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t WriteMemoryToQueue(void *contents, size_t size, size_t nmemb, void *userp)
|
|
||||||
{
|
|
||||||
size_t realsize = size * nmemb;
|
|
||||||
auto queue = reinterpret_cast<lockedqueue *>(userp);
|
|
||||||
queue->push(std::string((char *)contents, realsize));
|
|
||||||
return realsize;
|
|
||||||
}
|
|
||||||
|
@ -33,12 +33,5 @@ extern "C"
|
|||||||
|
|
||||||
__declspec(dllexport) void *extracticon2data(const wchar_t *name, size_t *l);
|
__declspec(dllexport) void *extracticon2data(const wchar_t *name, size_t *l);
|
||||||
|
|
||||||
__declspec(dllexport) size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp);
|
|
||||||
__declspec(dllexport) size_t WriteMemoryToQueue(void *contents, size_t size, size_t nmemb, void *userp);
|
|
||||||
__declspec(dllexport) void *lockedqueuecreate();
|
|
||||||
__declspec(dllexport) void lockedqueuefree(void *);
|
|
||||||
__declspec(dllexport) void *lockedqueueget(void *, size_t *);
|
|
||||||
__declspec(dllexport) void lockedqueuepush(void *, size_t, void *);
|
|
||||||
__declspec(dllexport) bool lockedqueueempty(void *);
|
|
||||||
__declspec(dllexport) void c_free(void *);
|
__declspec(dllexport) void c_free(void *);
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user