mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-27 15:44:12 +08:00
recons
This commit is contained in:
parent
34e05da0fa
commit
75713f8322
@ -293,7 +293,7 @@ class MAINUI() :
|
||||
self.refresh_on_get_trans_signature=_showrawfunction_sig
|
||||
_showrawfunction()
|
||||
|
||||
if currentsignature==self.currentsignature:
|
||||
if currentsignature==self.currentsignature and globalconfig['showfanyi']:
|
||||
self.translation_ui.displayres.emit(globalconfig['fanyi'][classname]['name'],globalconfig['fanyi'][classname]['color'],res,onlytrans)
|
||||
|
||||
if embedcallback:
|
||||
|
@ -1,7 +1,13 @@
|
||||
baseobject=None
|
||||
from traceback import print_exc
|
||||
import io,sys
|
||||
|
||||
import io,sys,platform,os
|
||||
isbit64= platform.architecture()[0]=='64bit'
|
||||
DLL3264path=os.path.abspath('files/plugins/DLL'+('32','64')[isbit64])
|
||||
def GetDllpath(_):
|
||||
if isinstance(_,str):
|
||||
return os.path.join(DLL3264path,_)
|
||||
elif isinstance(_,(list,tuple)):
|
||||
return os.path.join(DLL3264path,_[isbit64])
|
||||
class debugoutput(io.IOBase):
|
||||
def __init__(self,idx,file=sys.stdout) -> None:
|
||||
super().__init__()
|
||||
|
@ -304,6 +304,7 @@ class hookselect(closeashidewindow):
|
||||
self.allres=OrderedDict()
|
||||
self.hidesearchhookbuttons()
|
||||
def addnewhook(self,ss ,select,textthread):
|
||||
hc,hn,tp=textthread
|
||||
if len(self.save)==0:
|
||||
if gobject.baseobject.textsource.allow_set_text_name:
|
||||
self.ttCombomodelmodel.setHorizontalHeaderLabels(_TRL(['显示','类型','HOOK','文本']))
|
||||
@ -354,8 +355,8 @@ class hookselect(closeashidewindow):
|
||||
label.setStyleSheet("background-color: rgba(255, 255, 255, 0)")
|
||||
checkbtn=QPushButton()
|
||||
checkbtn.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
|
||||
def _t():
|
||||
_isusing=gobject.baseobject.textsource.checkisusingembed(textthread[0].tp.addr,textthread[0].tp.ctx,textthread[0].tp.ctx2)
|
||||
def _t(tp):
|
||||
_isusing=gobject.baseobject.textsource.checkisusingembed(tp.addr,tp.ctx,tp.ctx2)
|
||||
if _isusing:
|
||||
_text='取消内嵌翻译'
|
||||
checkifnewgame(gobject.baseobject.textsource.pname)
|
||||
@ -371,21 +372,21 @@ class hookselect(closeashidewindow):
|
||||
_text="使用内嵌翻译"
|
||||
checkbtn.setText('【'+_TR(_text)+'】')
|
||||
return _isusing
|
||||
_t()
|
||||
def _c(_):
|
||||
gobject.baseobject.textsource.useembed(textthread[0].tp.addr,textthread[0].tp.ctx,textthread[0].tp.ctx2,not _t())
|
||||
_use=_t()
|
||||
_t(tp)
|
||||
def _c(hc,tp,_):
|
||||
gobject.baseobject.textsource.useembed(tp.addr,tp.ctx,tp.ctx2,not _t(tp))
|
||||
_use=_t(tp)
|
||||
if _use:
|
||||
savehook_new_data[gobject.baseobject.textsource.pname]['embedablehook'].append([textthread[0].hpcode,textthread[0].tp.addr,textthread[0].tp.ctx,textthread[0].tp.ctx2])
|
||||
savehook_new_data[gobject.baseobject.textsource.pname]['embedablehook'].append([hc,tp.addr,tp.ctx,tp.ctx2])
|
||||
else:
|
||||
save=[]
|
||||
for _ in savehook_new_data[gobject.baseobject.textsource.pname]['embedablehook']:
|
||||
hc,ad,c1,c2=_
|
||||
if(hc,ad,c1,c2)==(textthread[0].hpcode,textthread[0].tp.addr,textthread[0].tp.ctx,textthread[0].tp.ctx2):
|
||||
if(hc,ad,c1,c2)==(hc,tp.addr,tp.ctx,tp.ctx2):
|
||||
save.append(_)
|
||||
for _ in save:
|
||||
savehook_new_data[gobject.baseobject.textsource.pname]['embedablehook'].remove(_)
|
||||
checkbtn.clicked.connect(_c)
|
||||
checkbtn.clicked.connect(functools.partial(_c,hc,tp))
|
||||
hlay.addWidget(checkbtn)
|
||||
colidx=2+(gobject.baseobject.textsource.allow_set_text_name)
|
||||
self.tttable.setIndexWidget(self.ttCombomodelmodel.index(rown,colidx),embedw)
|
||||
|
@ -28,7 +28,8 @@ def gethookgrid(self) :
|
||||
[('文本缓冲区长度',5),(getspinbox(0,10000,globalconfig,'flushbuffersize',callback=lambda x:gobject.baseobject.textsource.setsettings()),3)],
|
||||
[('过滤包含乱码的文本行',5),(getsimpleswitch(globalconfig,'filter_chaos_code'),1),(getcolorbutton(globalconfig,'',icon='fa.gear',constcolor="#FF69B4",callback=lambda:codeacceptdialog(self)),1)],
|
||||
[],
|
||||
[('区分人名和文本',5),getsimpleswitch(globalconfig,'allow_set_text_name')]
|
||||
[('区分人名和文本',5),getsimpleswitch(globalconfig,'allow_set_text_name')],
|
||||
[('使用YAPI注入',5),getsimpleswitch(globalconfig,'use_yapi')],
|
||||
|
||||
]
|
||||
|
||||
|
@ -133,7 +133,7 @@ def setTabThree_lazy(self) :
|
||||
[('显示日语注音',4),self.show_hira_switch,'',('注音颜色',4),getcolorbutton(globalconfig,'jiamingcolor',callback=lambda: selectcolor(self,globalconfig, "jiamingcolor", self.jiamingcolor_b),name='jiamingcolor_b',parent=self),'',('注音字体缩放',3),(getspinbox(0.05,1,globalconfig,'kanarate',double=True,step=0.05,dec=2),2)],
|
||||
[('语法加亮',4 ),self.show_fenciswitch,'',
|
||||
('词性颜色(需要Mecab)',4), getcolorbutton(globalconfig,'',callback=lambda : multicolorset(self),icon='fa.gear',constcolor="#FF69B4") ,],
|
||||
[("显示翻译器名称",4),(getsimpleswitch(globalconfig ,'showfanyisource'),1)],
|
||||
[("显示翻译器名称",4),(getsimpleswitch(globalconfig ,'showfanyisource'),1),'',("显示翻译",4),(getsimpleswitch(globalconfig ,'showfanyi'),1)],
|
||||
[('最长显示字数',4),(getspinbox(0,1000000,globalconfig,'maxoriginlength'),2)],
|
||||
|
||||
[],
|
||||
|
@ -1,7 +1,7 @@
|
||||
import platform,os
|
||||
import gobject,os
|
||||
from ctypes import CDLL,c_void_p,c_int,c_char_p,c_long,cast,CFUNCTYPE,c_size_t,Structure,pointer,create_string_buffer,memmove,POINTER,c_char,c_int64,c_uint
|
||||
curlpath=os.path.abspath(os.path.join('./files/plugins',['./libcurl-x64.dll','./libcurl.dll'][platform.architecture()[0]=='32bit']))
|
||||
libcurl=CDLL(curlpath)
|
||||
libcurl=CDLL(os.path.join(gobject.DLL3264path,('./libcurl.dll','./libcurl-x64.dll')[gobject.isbit64]))
|
||||
|
||||
CURL = c_void_p
|
||||
CURLSH=c_void_p
|
||||
class curl_slist(Structure):
|
||||
|
@ -1,11 +1,8 @@
|
||||
|
||||
from ctypes import CDLL,c_size_t,c_void_p,POINTER,pointer,create_string_buffer
|
||||
import os,platform
|
||||
|
||||
dllpath=os.path.abspath(os.path.join('./files/plugins/brotli',['./x64/brotlicommon.dll','./x86/brotlicommon.dll'][platform.architecture()[0]=='32bit']))
|
||||
_brotli=CDLL(dllpath)
|
||||
dllpath=os.path.abspath(os.path.join('./files/plugins/brotli',['./x64/brotlidec.dll','./x86/brotlidec.dll'][platform.architecture()[0]=='32bit']))
|
||||
_brotli=CDLL(dllpath)
|
||||
import os,gobject
|
||||
_brotli=CDLL(gobject.GetDllpath('brotlicommon.dll'))
|
||||
_brotli=CDLL(gobject.GetDllpath('brotlidec.dll'))
|
||||
BrotliDecoderDecompress=_brotli.BrotliDecoderDecompress
|
||||
BrotliDecoderDecompress.argtypes=c_size_t,c_void_p,POINTER(c_size_t),c_void_p
|
||||
def decompress(data):
|
||||
|
@ -7,15 +7,10 @@ import base64
|
||||
from ocrengines.baseocrclass import baseocr
|
||||
from ctypes import CDLL,c_char_p ,create_string_buffer,c_uint32,POINTER,c_int32
|
||||
import os
|
||||
import platform
|
||||
import gobject
|
||||
class ocrwrapper:
|
||||
def __init__(self) -> None:
|
||||
|
||||
if platform.architecture()[0]=='64bit':
|
||||
bit='64'
|
||||
else:
|
||||
bit='32'
|
||||
self.dll=CDLL(os.path.abspath('./files/plugins/ocr{}.dll'.format(bit)) )
|
||||
def __init__(self) -> None:
|
||||
self.dll=CDLL(gobject.GetDllpath(('ocr32.dll','ocr64.dll')))
|
||||
def _OcrInit(self,szDetModel, szRecModel, szKeyPath,szClsModel='', nThreads=4):
|
||||
|
||||
_OcrInit=self.dll.OcrInit
|
||||
|
@ -1,203 +0,0 @@
|
||||
STRING = 12
|
||||
|
||||
MESSAGE_SIZE = 500
|
||||
PIPE_BUFFER_SIZE = 50000
|
||||
SHIFT_JIS = 932
|
||||
MAX_MODULE_SIZE = 120
|
||||
PATTERN_SIZE = 30
|
||||
HOOK_NAME_SIZE = 60
|
||||
FIXED_SPLIT_VALUE = 0x10001
|
||||
import ctypes
|
||||
from ctypes import Structure,c_int,c_char,c_uint64,c_uint,sizeof,c_wchar,c_short,c_uint32,c_bool,c_ubyte
|
||||
class HostNotificationType(c_int):
|
||||
pass
|
||||
|
||||
HOST_NOTIFICATION_TEXT=0
|
||||
HOST_NOTIFICATION_NEWHOOK=1
|
||||
HOST_NOTIFICATION_FOUND_HOOK=2
|
||||
HOST_NOTIFICATION_RMVHOOK=3
|
||||
HOST_NOTIFICATION_INSERTHOOK=4
|
||||
class HostCommandType(c_uint):
|
||||
pass
|
||||
HOST_COMMAND_NEW_HOOK=0
|
||||
HOST_COMMAND_REMOVE_HOOK=1
|
||||
HOST_COMMAND_FIND_HOOK=2
|
||||
HOST_COMMAND_MODIFY_HOOK=3
|
||||
HOST_COMMAND_HIJACK_PROCESS=4
|
||||
HOST_COMMAND_DETACH=5
|
||||
HOST_COMMAND_NEW_HOOK_NAIVE=6
|
||||
|
||||
class ThreadParam(Structure):
|
||||
_fields_=[
|
||||
('processId',c_uint),
|
||||
('addr',c_uint64),
|
||||
('ctx',c_uint64),
|
||||
('ctx2',c_uint64)
|
||||
]
|
||||
def __hash__(self):
|
||||
return hash((self.processId, self.addr,self.ctx,self.ctx2))
|
||||
def __eq__(self, __value ):
|
||||
return self.__hash__()==__value.__hash__()
|
||||
|
||||
class HookParam(Structure):
|
||||
_fields_=[
|
||||
('address',c_uint64),
|
||||
('offset',c_int),
|
||||
('index',c_int),
|
||||
('split',c_int),
|
||||
('split_index',c_int),
|
||||
('null_length',c_int),
|
||||
('module',c_wchar*MAX_MODULE_SIZE),
|
||||
('function',c_char*MAX_MODULE_SIZE),
|
||||
('type',c_uint),
|
||||
('codepage', c_uint),
|
||||
('length_offset',c_short),
|
||||
('padding',c_uint64), #uintptr_t
|
||||
('user_value',c_uint),
|
||||
('text_fun',c_uint64),
|
||||
('filter_fun',c_uint64),
|
||||
('hook_fun',c_uint64),
|
||||
('length_fun',c_uint64), #函数指针
|
||||
('_1',c_uint64),
|
||||
('_2',c_uint64),
|
||||
('_3',c_uint64),
|
||||
('_4',c_uint64),
|
||||
('name',c_char*HOOK_NAME_SIZE)
|
||||
]
|
||||
class TextHook(Structure):
|
||||
_fields_=[
|
||||
('hp',HookParam),
|
||||
('address',c_uint64), #union{uint64 && void*}
|
||||
('useCount',c_uint),
|
||||
('readerThread',c_uint64), #HANLDE ->void*
|
||||
('readerEvent',c_uint64),
|
||||
('err',c_bool),
|
||||
('trampoline',c_ubyte*140),
|
||||
('local_buffer',c_uint64)
|
||||
]
|
||||
MAX_HOOK=2500
|
||||
|
||||
class SearchParam(Structure):
|
||||
_fields_=[
|
||||
('pattern',c_char*30),
|
||||
('address_method',c_int),
|
||||
('search_method',c_int),
|
||||
('length',c_int),
|
||||
('offset',c_int),
|
||||
('searchTime',c_int),
|
||||
('maxRecords',c_int),
|
||||
('codepage',c_int),
|
||||
('padding',c_uint64),
|
||||
('minAddress',c_uint64),
|
||||
('maxAddress',c_uint64),
|
||||
('boundaryModule',c_wchar*120),
|
||||
('exportModule',c_wchar*120),
|
||||
('text',c_wchar*30)
|
||||
]
|
||||
|
||||
|
||||
class DetachCmd(Structure):
|
||||
_fields_=[
|
||||
('command',HostCommandType),
|
||||
]
|
||||
def __init__(self) -> None:
|
||||
self.command=HOST_COMMAND_DETACH
|
||||
class RemoveHookCmd(Structure):
|
||||
_fields_=[
|
||||
('command',HostCommandType),
|
||||
('address',c_uint64)
|
||||
]
|
||||
def __init__(self, address) -> None:
|
||||
self.command=HOST_COMMAND_REMOVE_HOOK
|
||||
self.address=address
|
||||
|
||||
class InsertHookCmd(Structure):
|
||||
_fields_=[
|
||||
('command',HostCommandType),
|
||||
('hp',HookParam)
|
||||
]
|
||||
def __init__(self, hp) -> None:
|
||||
self.command=HOST_COMMAND_NEW_HOOK
|
||||
self.hp=hp
|
||||
class InsertHookCodeNaive(Structure):
|
||||
_fields_=[
|
||||
('command',HostCommandType),
|
||||
('hcode',c_wchar*500)
|
||||
]
|
||||
def __init__(self, hp) -> None:
|
||||
self.command=HOST_COMMAND_NEW_HOOK_NAIVE
|
||||
self.hcode=hp
|
||||
|
||||
class FindHookCmd(Structure):
|
||||
_fields_=[
|
||||
('command',HostCommandType),
|
||||
('sp',SearchParam)
|
||||
]
|
||||
def __init__(self, sp) -> None:
|
||||
self.command=HOST_COMMAND_FIND_HOOK
|
||||
self.sp=sp
|
||||
class RemoveHookCmd(Structure):
|
||||
_fields_=[
|
||||
('command',HostCommandType),
|
||||
('address',c_uint64)
|
||||
]
|
||||
def __init__(self, address) -> None:
|
||||
self.command=HOST_COMMAND_REMOVE_HOOK
|
||||
self.address=address
|
||||
class hookfoundtext(Structure):
|
||||
_fields_=[('text',c_wchar*MESSAGE_SIZE)]
|
||||
|
||||
|
||||
class HookFoundNotif(Structure):
|
||||
_fields_=[
|
||||
('command',HostNotificationType),
|
||||
('hp',HookParam),
|
||||
('hcode',c_wchar*500),
|
||||
('text',hookfoundtext)
|
||||
]
|
||||
class ConsoleOutputNotif(Structure):
|
||||
_fields_=[
|
||||
('command',HostNotificationType),
|
||||
('message',c_char*MESSAGE_SIZE)
|
||||
]
|
||||
class HookRemovedNotif(Structure):
|
||||
_fields_=[
|
||||
('command',HostNotificationType),
|
||||
('address',c_uint64)
|
||||
]
|
||||
class HookInsertingNotif(Structure):
|
||||
_fields_=[
|
||||
('command',HostNotificationType),
|
||||
('addr',c_uint64),
|
||||
]
|
||||
SHAREDMEMDPREFIX='LUNA_VNR_SECTION_'
|
||||
HOOKCODEGET='LUNA_HOOKCODE_'
|
||||
|
||||
HOOK_PIPE_NAME="\\\\.\\pipe\\LUNA_HOOK"
|
||||
HOST_PIPE_NAME="\\\\.\\pipe\\LUNA_HOST"
|
||||
PIPE_AVAILABLE_EVENT = "LUNA_PIPE_AVAILABLE"
|
||||
|
||||
|
||||
class Hookcodeshared(Structure):
|
||||
_fields_=[('code',c_wchar*500)]
|
||||
|
||||
class EmbedSharedMem(ctypes.Structure):
|
||||
_fields_=[
|
||||
('using',ctypes.c_uint64*10),
|
||||
('addr',ctypes.c_uint64*10),
|
||||
('ctx1',ctypes.c_uint64*10),
|
||||
('ctx2',ctypes.c_uint64*10),
|
||||
('waittime',ctypes.c_uint32),
|
||||
('spaceadjustpolicy',ctypes.c_uint32),
|
||||
('keeprawtext',ctypes.c_uint32),
|
||||
('hash',ctypes.c_uint64),
|
||||
('text',ctypes.c_wchar*1000),
|
||||
('fontCharSetEnabled',ctypes.c_bool),
|
||||
('fontCharSet',ctypes.c_uint8),
|
||||
('fontFamily',ctypes.c_wchar*100),
|
||||
]
|
||||
|
||||
EMBED_SHARED_MEM="EMBED_SHARED_MEM"
|
||||
|
||||
LUNA_NOTIFY="LUNA_NOTIFY.%s.%s"
|
||||
ITH_HOOKMAN_MUTEX_="LUNA_VNR_HOOKMAN_"
|
@ -1,265 +0,0 @@
|
||||
import textsource.hook.define as define
|
||||
import windows
|
||||
from traceback import print_exc
|
||||
#import define
|
||||
import re,copy
|
||||
USING_STRING = 0x1 # type(data) is char * or wchar_t * and has length
|
||||
USING_UNICODE = 0x2 # type(data) is wchar_t or wchar_t*
|
||||
BIG_ENDIAN = 0x4 # type(data) is char
|
||||
DATA_INDIRECT = 0x8
|
||||
USING_SPLIT = 0x10 # use ctx2 or not
|
||||
SPLIT_INDIRECT = 0x20
|
||||
MODULE_OFFSET = 0x40 # address is relative to module
|
||||
FUNCTION_OFFSET = 0x80 # address is relative to function
|
||||
USING_UTF8 = 0x100
|
||||
NO_CONTEXT = 0x200
|
||||
HOOK_EMPTY = 0x400
|
||||
FIXING_SPLIT = 0x800
|
||||
DIRECT_READ = 0x1000 # /R read code instead of classic / H hook code
|
||||
FULL_STRING = 0x2000
|
||||
HEX_DUMP = 0x4000
|
||||
HOOK_ENGINE = 0x8000
|
||||
HOOK_ADDITIONAL = 0x10000
|
||||
KNOWN_UNSTABLE = 0x20000
|
||||
def ConsumeHexInt(HCode):
|
||||
match = re.match(r'^([+-]?[0-9a-fA-F]+)', HCode)
|
||||
if match:
|
||||
value = int(match.group(1), 16)
|
||||
HCode = HCode[match.end():]
|
||||
return HCode,value
|
||||
else:
|
||||
return HCode,0
|
||||
def Hex(st):
|
||||
return hex(st).replace('0x','').upper()
|
||||
def ParseRCode(RCode) :
|
||||
hp=define.HookParam()
|
||||
hp.type |= DIRECT_READ
|
||||
if RCode[0]=='S':
|
||||
pass
|
||||
elif RCode[0] == 'Q':
|
||||
hp.type |= USING_UNICODE
|
||||
elif RCode[0] == 'V':
|
||||
hp.type |= USING_UTF8
|
||||
elif RCode[0] == 'M':
|
||||
hp.type |= USING_UNICODE | HEX_DUMP
|
||||
else:
|
||||
return None
|
||||
RCode = RCode[1:]
|
||||
# [null_length<]
|
||||
match = re.match(r"^([0-9]+)<", RCode)
|
||||
if match:
|
||||
hp.null_length = int(match.group(1))
|
||||
RCode = RCode[len(match.group(0)):]
|
||||
# [codepage#]
|
||||
match = re.match(r"^([0-9]+)#", RCode)
|
||||
if match:
|
||||
hp.codepage = int(match.group(1))
|
||||
RCode = RCode[len(match.group(0)):]
|
||||
# @addr
|
||||
match = re.match(r"@([0-9a-fA-F]+)", RCode)
|
||||
if not match:
|
||||
return None
|
||||
hp.address = int(match.group(1), 16)
|
||||
return hp
|
||||
|
||||
def ParseHCode(HCode):
|
||||
hp=define.HookParam()
|
||||
if HCode[0] == 'A':
|
||||
hp.type |= BIG_ENDIAN
|
||||
hp.length_offset = 1
|
||||
elif HCode[0] == 'B':
|
||||
hp.length_offset = 1
|
||||
elif HCode[0] == 'W':
|
||||
hp.type |= USING_UNICODE
|
||||
hp.length_offset = 1
|
||||
elif HCode[0] == 'H':
|
||||
hp.type |= USING_UNICODE | HEX_DUMP
|
||||
hp.length_offset = 1
|
||||
elif HCode[0] == 'S':
|
||||
hp.type |= USING_STRING
|
||||
elif HCode[0] == 'Q':
|
||||
hp.type |= USING_STRING | USING_UNICODE
|
||||
elif HCode[0] == 'V':
|
||||
hp.type |= USING_STRING | USING_UTF8
|
||||
elif HCode[0] == 'M':
|
||||
hp.type |= USING_STRING | USING_UNICODE | HEX_DUMP
|
||||
else:
|
||||
return None
|
||||
HCode = HCode[1:]
|
||||
|
||||
if hp.type & USING_STRING:
|
||||
if HCode[0] == 'F':
|
||||
hp.type |= FULL_STRING
|
||||
HCode = HCode[1:]
|
||||
# [null_length<]
|
||||
match = re.match(r'^([0-9]+)<', HCode)
|
||||
if match:
|
||||
hp.null_length = int(match.group(1))
|
||||
HCode = HCode[match.end():]
|
||||
# [N]
|
||||
if HCode[0] == 'N':
|
||||
hp.type |= NO_CONTEXT
|
||||
HCode = HCode[1:]
|
||||
# [codepage#]
|
||||
match = re.match(r'^([0-9]+)#', HCode)
|
||||
if match:
|
||||
hp.codepage = int(match.group(1))
|
||||
HCode = HCode[match.end():]
|
||||
# [padding+]
|
||||
match = re.match(r'^([0-9a-fA-F]+)\+', HCode)
|
||||
if match:
|
||||
hp.padding = int(match.group(1), 16)
|
||||
HCode = HCode[match.end():]
|
||||
HCode,hp.offset=ConsumeHexInt(HCode)
|
||||
# [*deref_offset1]
|
||||
if HCode[0] == '*':
|
||||
hp.type |= DATA_INDIRECT
|
||||
HCode = HCode[1:]
|
||||
HCode,hp.index=ConsumeHexInt(HCode)
|
||||
# [:split_offset[*deref_offset2]]
|
||||
if HCode[0] == ':':
|
||||
hp.type |= USING_SPLIT
|
||||
HCode = HCode[1:]
|
||||
HCode,hp.split=ConsumeHexInt(HCode)
|
||||
if HCode[0] == '*':
|
||||
hp.type |= SPLIT_INDIRECT
|
||||
HCode = HCode[1:]
|
||||
HCode,hp.split_index=ConsumeHexInt(HCode)
|
||||
# @addr[:module[:func]]
|
||||
match = re.match(r'^@([0-9a-fA-F]+)(:.+?)?(:.+)?$', HCode)
|
||||
if match is None:
|
||||
return None
|
||||
hp.address = int(match.group(1), 16)
|
||||
if match.group(2):
|
||||
hp.type |= MODULE_OFFSET
|
||||
hp.module = match.group(2)[1:]
|
||||
if match.group(3):
|
||||
hp.type |= FUNCTION_OFFSET
|
||||
hp.function =bytes(match.group(3)[1:],encoding='ascii')
|
||||
|
||||
# ITH has registers offset by 4 vs AGTH: need this to correct
|
||||
if hp.offset < 0:
|
||||
hp.offset -= 4
|
||||
if hp.split < 0:
|
||||
hp.split -= 4
|
||||
|
||||
return hp
|
||||
def Parse(code):
|
||||
code=code.strip().replace('\r','').replace('\n','').replace('\t','')
|
||||
if(code[0]=='/'):code=code[1:]
|
||||
if('/' in code):code=code.split('/')[0]
|
||||
if(code[0]=='R'):
|
||||
hp=ParseRCode(code[1:])
|
||||
elif(code[0]=='H'):
|
||||
hp=ParseHCode(code[1:])
|
||||
else:
|
||||
hp=None
|
||||
return hp
|
||||
def GenerateRCode(hp):
|
||||
RCode = 'R'
|
||||
if hp.type & USING_UNICODE:
|
||||
if hp.type & HEX_DUMP:
|
||||
RCode += 'M'
|
||||
else:
|
||||
RCode += 'Q'
|
||||
if hp.null_length != 0:
|
||||
RCode += str(hp.null_length) + '<'
|
||||
else:
|
||||
RCode += 'S'
|
||||
if hp.null_length != 0:
|
||||
RCode += str(hp.null_length) + '<'
|
||||
if hp.codepage != 0:
|
||||
RCode += str(hp.codepage) + '#'
|
||||
RCode += '@' + Hex(hp.address)
|
||||
return RCode
|
||||
|
||||
def GenerateHCode(hp,processId):
|
||||
HCode = "H"
|
||||
if hp.type & USING_UNICODE:
|
||||
if hp.type & HEX_DUMP:
|
||||
if hp.type & USING_STRING:
|
||||
HCode += "M"
|
||||
else:
|
||||
HCode += "H"
|
||||
else:
|
||||
if hp.type & USING_STRING:
|
||||
HCode += "Q"
|
||||
else:
|
||||
HCode += "W"
|
||||
|
||||
else:
|
||||
if hp.type & USING_STRING:
|
||||
HCode += "S"
|
||||
elif hp.type & BIG_ENDIAN:
|
||||
HCode += "A"
|
||||
else:
|
||||
HCode += "B"
|
||||
if hp.type & FULL_STRING:
|
||||
HCode += "F"
|
||||
|
||||
if hp.null_length != 0:
|
||||
HCode += str(hp.null_length) + "<"
|
||||
if hp.type & NO_CONTEXT:
|
||||
HCode += "N"
|
||||
|
||||
if hp.text_fun or hp.filter_fun or hp.hook_fun or hp.length_fun:
|
||||
HCode += "X" # no AGTH equivalent
|
||||
if hp.codepage != 0 and not (hp.type & USING_UNICODE):
|
||||
HCode += str(hp.codepage) + "#"
|
||||
|
||||
if hp.padding:
|
||||
HCode += Hex(hp.padding) + "+"
|
||||
if hp.offset < 0:
|
||||
hp.offset += 4
|
||||
|
||||
if hp.split < 0:
|
||||
hp.split += 4
|
||||
HCode += Hex(hp.offset)
|
||||
if hp.type & DATA_INDIRECT:
|
||||
HCode += "*" + Hex(hp.index)
|
||||
if hp.type & USING_SPLIT:
|
||||
HCode += ":" + Hex(hp.split)
|
||||
if hp.type & SPLIT_INDIRECT:
|
||||
HCode += "*" + Hex(hp.split_index)
|
||||
# Attempt to make the address relative
|
||||
try:
|
||||
if processId and not (hp.type & MODULE_OFFSET):
|
||||
process =windows.AutoHandle(windows.OpenProcess(windows.PROCESS_VM_READ | windows.PROCESS_QUERY_INFORMATION, False, processId))
|
||||
if process:
|
||||
info=windows.VirtualQueryEx(process,hp.address)
|
||||
if info.AllocationBase:
|
||||
module_name =windows.GetModuleFileNameEx(process, info.AllocationBase)
|
||||
if module_name:
|
||||
hp.address -= info.AllocationBase
|
||||
hp.type |= MODULE_OFFSET
|
||||
hp.module = module_name[module_name.rfind('\\')+1:][:120]
|
||||
|
||||
except:
|
||||
pass
|
||||
#print_exc()
|
||||
HCode += "@" + Hex(hp.address)
|
||||
|
||||
if hp.type & MODULE_OFFSET:
|
||||
HCode += ":" + hp.module
|
||||
|
||||
if hp.type & FUNCTION_OFFSET:
|
||||
HCode += ":" + hp.function.decode('ascii')
|
||||
return HCode
|
||||
def Generate(_hp,process_id):
|
||||
hp=copy.copy(_hp)
|
||||
if hp.type&DIRECT_READ :
|
||||
code=GenerateRCode(hp)
|
||||
else:
|
||||
code=GenerateHCode(hp,process_id)
|
||||
|
||||
return code
|
||||
if __name__=='__main__':
|
||||
# print(Parse("/HQN936#1+-c*C:C*1C@4AA:gdi.dll:GetTextOutA",hp))
|
||||
# print(Parse("/HQN936#-c*C:C*1C@4AA:gdi.dll:GetTextOutA /KF",hp))
|
||||
# print(Parse("HB4@0" ,hp)),
|
||||
# print(Parse("/RS65001#@44",hp)),
|
||||
# print(Parse("HQ@4",hp,))
|
||||
print(Parse('/HS8:-14@76D85270'))
|
||||
# print(Parse("/RW@44",hp)),
|
||||
# print(Parse("/HWG@33",hp))
|
||||
|
@ -1,303 +0,0 @@
|
||||
import threading
|
||||
import textsource.hook.define as define
|
||||
|
||||
import ctypes,time
|
||||
from ctypes import Structure,c_int,c_char,sizeof,cast,POINTER
|
||||
from myutils.wrapper import threader
|
||||
import sys
|
||||
import os ,subprocess
|
||||
from myutils.config import globalconfig
|
||||
import windows
|
||||
from myutils.hwnd import testprivilege
|
||||
|
||||
import ctypes
|
||||
import textsource.hook.hookcode as hookcode
|
||||
class ProcessRecord():
|
||||
def __init__(self,pipe,processId) -> None:
|
||||
self.pipe=pipe
|
||||
self.processId=processId
|
||||
buff=define.MAX_HOOK*define.TextHook
|
||||
HOOK_SECTION_SIZE=sizeof(buff)
|
||||
self.OnHookFound=0
|
||||
fmap1=windows.OpenFileMapping(windows.FILE_MAP_READ,False,define.SHAREDMEMDPREFIX+str(processId))
|
||||
address1=windows.MapViewOfFile(fmap1, windows.FILE_MAP_READ, HOOK_SECTION_SIZE)
|
||||
|
||||
fmap2=windows.OpenFileMapping(windows.FILE_MAP_READ,False,define.HOOKCODEGET+str(processId))
|
||||
address2=windows.MapViewOfFile(fmap2, windows.FILE_MAP_READ, sizeof(define.MAX_HOOK*define.Hookcodeshared))
|
||||
|
||||
self.sharedtexthook=cast(address1,POINTER(buff))
|
||||
self.sharedhookcode=cast(address2,POINTER(define.MAX_HOOK*define.Hookcodeshared))
|
||||
|
||||
def GetHook(self,addr):
|
||||
for i,_hook in enumerate(self.sharedtexthook.contents):
|
||||
if(_hook.address==addr):
|
||||
code=self.sharedhookcode.contents[i].code
|
||||
return _hook,code
|
||||
return None,None
|
||||
def Send(self,struct):
|
||||
windows.WriteFile(self.pipe,bytes(struct))
|
||||
#calls
|
||||
def Detach(self):
|
||||
self.Send(define.DetachCmd())
|
||||
def RemoveHook(self,address):
|
||||
self.Send((define.RemoveHookCmd(address)))
|
||||
def InsertHookCode(self,string):
|
||||
if len(string) and string[0]=='E':
|
||||
self.Send(define.InsertHookCodeNaive(string))
|
||||
else:
|
||||
hp=hookcode.Parse(string)
|
||||
print(hp)
|
||||
if hp:
|
||||
self.Send(define.InsertHookCmd(hp))
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def FindHooks(self,sp,OnHookFound):
|
||||
self.OnHookFound=OnHookFound
|
||||
self.Send(define.FindHookCmd(sp))
|
||||
self.OnHookFound=OnHookFound
|
||||
def RemoveHook(self,addr):
|
||||
self.Send(define.RemoveHookCmd(addr));
|
||||
class TextThread():
|
||||
def __init__(self,rpc,tp,_,host) -> None:
|
||||
(texthook,hcode)=_
|
||||
hp=texthook.hp
|
||||
self.tp=tp
|
||||
self.rpc=rpc
|
||||
self.hp=hp
|
||||
self.hpcode=hcode#hookcode.Generate(hp,tp.processId)
|
||||
self.host=host
|
||||
self.buffer=''
|
||||
self.lasttime=0
|
||||
self.lock=threading.Lock()
|
||||
self.leadbyte=0
|
||||
self.saverepeat=''
|
||||
def Push(self,buff):
|
||||
|
||||
self.lock.acquire()
|
||||
buffer=self.parsebuff(buff)
|
||||
if self.rpc.setting.timeout==0 and self.hp.type&hookcode.FULL_STRING:
|
||||
self.rpc.Output(self,buffer)
|
||||
elif not( globalconfig['direct_filterrepeat']and (len(buffer)>=3) and (buffer in self.saverepeat)):
|
||||
self.buffer+=buffer
|
||||
self.lasttime=time.time()
|
||||
if len(self.buffer):
|
||||
self.saverepeat=self.buffer
|
||||
|
||||
if len(self.buffer)>=self.host.setting.flushbuffersize:
|
||||
_=self.buffer
|
||||
self.buffer=''
|
||||
self.rpc.Output(self,_)
|
||||
|
||||
self.lock.release()
|
||||
|
||||
def parsebuff(self,buff):
|
||||
hp=self.hp
|
||||
if hp.codepage==0:
|
||||
cp=self.host.setting.defaultcodepag
|
||||
else:
|
||||
cp=hp.codepage
|
||||
if len(buff)==1:
|
||||
if self.leadbyte:
|
||||
buff=self.leadbyte+buff
|
||||
self.leadbyte=0
|
||||
else:
|
||||
if(windows.IsDBCSLeadByteEx(cp,buff[0])):
|
||||
self.leadbyte=buff
|
||||
return ''
|
||||
|
||||
|
||||
if (hp.type &hookcode.HEX_DUMP) :
|
||||
_ret=buff.hex()
|
||||
elif hp.type& hookcode.USING_UNICODE:
|
||||
try:
|
||||
_ret=buff.decode('utf-16',errors='ignore')
|
||||
except:
|
||||
return ''
|
||||
else:
|
||||
if hp.codepage==0:
|
||||
cp=self.host.setting.defaultcodepag
|
||||
else:
|
||||
cp=hp.codepage
|
||||
_ret=windows.MultiByteToWideChar(buff,len(buff),cp)
|
||||
if _ret is None:
|
||||
_ret=''
|
||||
if hp.type&hookcode.FULL_STRING:
|
||||
_ret+='\n'
|
||||
return _ret
|
||||
class RPCSettings:
|
||||
def __init__(self) -> None:
|
||||
self.timeout=100
|
||||
self.defaultcodepag=932
|
||||
self.flushbuffersize=3000
|
||||
class RPC():
|
||||
def callbacks(self,OnConnect,OnDisconnect,OnCreate,OnDestroy,Output,Console,EmbedCall,HookInsert):
|
||||
self.OnDisconnect=threader(OnDisconnect)
|
||||
self.OnConnect=threader(OnConnect)
|
||||
self.OnCreate=(OnCreate) #有并发问题,会插入Embed的text两次
|
||||
self.OnDestroy=threader(OnDestroy)
|
||||
self.Output=threader(Output)
|
||||
self.Console=threader(Console)
|
||||
self.EmbedCall=threader(EmbedCall)
|
||||
self.HookInsert=threader(HookInsert)
|
||||
def toint(self,byte4):
|
||||
return c_int.from_buffer_copy(byte4).value
|
||||
def end(self):
|
||||
for _ in self.hookPipes:
|
||||
windows.CancelIo(_)
|
||||
def __init__(self) -> None:
|
||||
self.ProcessRecord={}
|
||||
self.textthreadslock=threading.Lock()
|
||||
self.textthreads={}
|
||||
self.hookPipes=[]
|
||||
self.setting=RPCSettings()
|
||||
threading.Thread(target=self.outputthread).start()
|
||||
def outputthread(self):
|
||||
while True:
|
||||
time.sleep(0.001)
|
||||
timenow=time.time()
|
||||
self.textthreadslock.acquire()
|
||||
for _,textthread in self.textthreads.items():
|
||||
textthread.lock.acquire()
|
||||
if len(textthread.buffer)>0 and (timenow-textthread.lasttime>self.setting.timeout/1000):
|
||||
buff=textthread.buffer
|
||||
textthread.buffer=''
|
||||
self.Output(textthread,buff)
|
||||
textthread.lasttime=timenow
|
||||
textthread.lock.release()
|
||||
self.textthreadslock.release()
|
||||
def start(self,pid):
|
||||
|
||||
hookPipe = windows.CreateNamedPipe(define.HOOK_PIPE_NAME+str(pid),
|
||||
windows.PIPE_ACCESS_INBOUND,
|
||||
windows.PIPE_TYPE_MESSAGE | windows.PIPE_READMODE_MESSAGE | windows.PIPE_WAIT,
|
||||
windows.PIPE_UNLIMITED_INSTANCES,
|
||||
0,
|
||||
0,
|
||||
0)
|
||||
hostPipe = windows.CreateNamedPipe(define.HOST_PIPE_NAME+str(pid),
|
||||
windows.PIPE_ACCESS_OUTBOUND,
|
||||
windows.PIPE_TYPE_MESSAGE | windows.PIPE_READMODE_MESSAGE | windows.PIPE_WAIT,
|
||||
windows.PIPE_UNLIMITED_INSTANCES,
|
||||
0,
|
||||
0,
|
||||
0 )
|
||||
|
||||
pipeAvailableEvent = windows.CreateEvent(False, False, define.PIPE_AVAILABLE_EVENT+str(pid))
|
||||
windows.SetEvent(pipeAvailableEvent)
|
||||
self.hookPipes.append(hookPipe)
|
||||
def _():
|
||||
windows.ConnectNamedPipe(hookPipe, None)
|
||||
windows.CloseHandle(pipeAvailableEvent)
|
||||
processId = self.toint(windows.ReadFile(hookPipe, 4,None) )
|
||||
|
||||
self.ProcessRecord[processId]=ProcessRecord(hostPipe,processId)
|
||||
self.OnConnect(processId)
|
||||
|
||||
while True:
|
||||
data=windows.ReadFile(hookPipe,50000,None)
|
||||
if len(data)==0 :break
|
||||
if len(data)==50000:continue
|
||||
self.OnMessage(data,processId)
|
||||
self.ProcessRecord.pop(processId)
|
||||
windows.CloseHandle(hookPipe)
|
||||
windows.CloseHandle(hostPipe)
|
||||
self.removethreads(processId)
|
||||
self.OnDisconnect((processId))
|
||||
threading.Thread(target=_,daemon=True).start()
|
||||
def removethreads(self,pid,addr=None):
|
||||
self.textthreadslock.acquire()
|
||||
toremove=[]
|
||||
for textthread in self.textthreads:
|
||||
if textthread.processId==pid:
|
||||
if addr:
|
||||
if textthread.addr==addr:
|
||||
toremove.append(textthread)
|
||||
else:
|
||||
toremove.append(textthread)
|
||||
for _ in toremove:
|
||||
self.textthreads.pop(_)
|
||||
self.OnDestroy(_)
|
||||
self.textthreadslock.release()
|
||||
def OnMessage(self,data,processId):
|
||||
cmd=self.toint(data[:4])
|
||||
if(cmd==define. HOST_NOTIFICATION_TEXT):
|
||||
try:
|
||||
message=define.ConsoleOutputNotif.from_buffer_copy(data).message.decode('utf8')
|
||||
except:
|
||||
message="ErrorDecodeMessage"
|
||||
self.Console(message)
|
||||
|
||||
elif(cmd==define.HOST_NOTIFICATION_FOUND_HOOK):
|
||||
_HookFoundNotif=define.HookFoundNotif
|
||||
_HookFoundNotif=_HookFoundNotif.from_buffer_copy(data)
|
||||
text=_HookFoundNotif.text.text
|
||||
#print(_HookFoundNotif.hcode,hookcode.Generate(_HookFoundNotif.hp,processId))
|
||||
hp=hookcode.Parse(_HookFoundNotif.hcode)
|
||||
if len(text)>12:
|
||||
self.ProcessRecord[processId].OnHookFound(hookcode.Generate(hp,processId),text)
|
||||
hp.type&=~hookcode.USING_UNICODE
|
||||
codepages=[hp.codepage]
|
||||
if hp.codepage!=65001:
|
||||
codepages+=[65001]
|
||||
|
||||
for codepage in codepages:
|
||||
try:
|
||||
hp.codepage=codepage
|
||||
text=windows.MultiByteToWideChar(_HookFoundNotif.text.text,sizeof(define.hookfoundtext),hp.codepage)
|
||||
if text is not None and len(text)>12:
|
||||
self.ProcessRecord[processId].OnHookFound(hookcode.Generate(hp,processId),text)
|
||||
except:pass
|
||||
|
||||
elif(cmd==define.HOST_NOTIFICATION_RMVHOOK):
|
||||
self.removethreads(processId,define.HookRemovedNotif.from_buffer_copy(data).address)
|
||||
elif(cmd==define.HOST_NOTIFICATION_INSERTHOOK):
|
||||
|
||||
addr=define.HookInsertingNotif.from_buffer_copy(data).addr
|
||||
_,hcode=self.ProcessRecord[processId].GetHook(addr)
|
||||
self.HookInsert(addr,hcode)
|
||||
else:
|
||||
tp=define.ThreadParam.from_buffer_copy(data)
|
||||
|
||||
if tp not in self.textthreads:
|
||||
self.textthreadslock.acquire()
|
||||
self.textthreads[tp]=TextThread(self,tp,self.ProcessRecord[tp.processId].GetHook(tp.addr),self)
|
||||
self.OnCreate(self.textthreads[tp])
|
||||
self.textthreadslock.release()
|
||||
if self.textthreads[tp].hpcode[0]=='E':
|
||||
#self.Output(self.textthreads[tp],self.textthreads[tp].parsebuff(data[sizeof(tp):]))
|
||||
self.EmbedCall(self.textthreads[tp].parsebuff(data[sizeof(tp):]),self.textthreads[tp])
|
||||
self.textthreads[tp].Push(data[sizeof(tp):])
|
||||
#
|
||||
def Attach(self,pids,arch):
|
||||
|
||||
injecter=os.path.abspath('./files/plugins/shareddllproxy{}.exe'.format(arch))
|
||||
dll=os.path.abspath('./files/plugins/LunaHook/LunaHook{}.dll'.format(arch))
|
||||
print(injecter,os.path.exists(injecter))
|
||||
print(dll,os.path.exists(dll))
|
||||
#subprocess.Popen('"{}" dllinject {} "{}"'.format(injecter,pid,dll))
|
||||
pid=' '.join([str(_) for _ in pids])
|
||||
if any(map(testprivilege,pids))==False:
|
||||
windows.ShellExecute(0,'runas',injecter,'dllinject {} "{}"'.format(pid,dll),None,windows.SW_HIDE)
|
||||
else:
|
||||
ret=subprocess.run('"{}" dllinject {} "{}"'.format(injecter,pid,dll)).returncode
|
||||
if(ret==0):
|
||||
windows.ShellExecute(0,'runas',injecter,'dllinject {} "{}"'.format(pid,dll),None,windows.SW_HIDE)
|
||||
@threader
|
||||
def InsertHookCode(self,pid,hookcode):
|
||||
if pid in self.ProcessRecord:
|
||||
self.ProcessRecord[pid].InsertHookCode(hookcode)
|
||||
@threader
|
||||
def FindHooks(self,pid,sp,onfound):
|
||||
if pid in self.ProcessRecord:
|
||||
self.ProcessRecord[pid].FindHooks(sp,onfound)
|
||||
@threader
|
||||
def Detach(self,pid):
|
||||
if pid in self.ProcessRecord:
|
||||
self.ProcessRecord[pid].Detach()
|
||||
@threader
|
||||
def RemoveHook(self,pid,addr):
|
||||
if pid in self.ProcessRecord:
|
||||
self.ProcessRecord[pid].RemoveHook(addr)
|
||||
|
@ -4,17 +4,67 @@ import re ,os
|
||||
import time ,gobject
|
||||
from collections import OrderedDict
|
||||
import ctypes,functools
|
||||
import windows
|
||||
import textsource.hook.define as define
|
||||
import windows,subprocess
|
||||
from myutils.config import globalconfig ,savehook_new_data ,_TR,static_data
|
||||
from textsource.textsourcebase import basetext
|
||||
from myutils.utils import checkchaos
|
||||
from textsource.hook.host import RPC
|
||||
|
||||
from myutils.utils import checkchaos
|
||||
from myutils.hwnd import testprivilege
|
||||
from myutils.wrapper import threader
|
||||
from ctypes import CDLL,c_bool,POINTER,Structure,c_int,pointer,c_wchar_p,c_uint64,sizeof,c_void_p,cast,c_wchar,c_uint32,c_uint8,c_uint,c_char,c_short
|
||||
from ctypes.wintypes import DWORD,LPCWSTR,HANDLE
|
||||
from gui.usefulwidget import getQMessageBox
|
||||
|
||||
MAX_MODULE_SIZE = 120
|
||||
HOOK_NAME_SIZE = 60
|
||||
HOOKCODE_LEN=500
|
||||
class ThreadParam(Structure):
|
||||
_fields_=[
|
||||
('processId',c_uint),
|
||||
('addr',c_uint64),
|
||||
('ctx',c_uint64),
|
||||
('ctx2',c_uint64)
|
||||
]
|
||||
def __hash__(self):
|
||||
return hash((self.processId, self.addr,self.ctx,self.ctx2))
|
||||
def __eq__(self, __value ):
|
||||
return self.__hash__()==__value.__hash__()
|
||||
|
||||
class SearchParam(Structure):
|
||||
_fields_=[
|
||||
('pattern',c_char*30),
|
||||
('address_method',c_int),
|
||||
('search_method',c_int),
|
||||
('length',c_int),
|
||||
('offset',c_int),
|
||||
('searchTime',c_int),
|
||||
('maxRecords',c_int),
|
||||
('codepage',c_int),
|
||||
('padding',c_uint64),
|
||||
('minAddress',c_uint64),
|
||||
('maxAddress',c_uint64),
|
||||
('boundaryModule',c_wchar*120),
|
||||
('exportModule',c_wchar*120),
|
||||
('text',c_wchar*30),
|
||||
('_1',c_uint64)
|
||||
]
|
||||
class Message(Structure):
|
||||
_fields_=[
|
||||
('read',c_bool),
|
||||
('type',c_int),
|
||||
('pid',DWORD),
|
||||
('hn',c_char*HOOK_NAME_SIZE),
|
||||
('hc',c_wchar*HOOKCODE_LEN),
|
||||
('tp',ThreadParam),
|
||||
('stringptr',c_void_p),
|
||||
('addr',c_uint64)
|
||||
]
|
||||
class simplehooks(Structure):
|
||||
_fields_=[
|
||||
('hookcode',c_wchar*500),
|
||||
('text',c_void_p)
|
||||
]
|
||||
class texthook(basetext ):
|
||||
def __init__(self,pids,hwnd,pname ,autostarthookcode=None,needinserthookcode=None) :
|
||||
print(pids,hwnd,pname ,autostarthookcode,needinserthookcode)
|
||||
self.RPC=RPC()
|
||||
if autostarthookcode is None:
|
||||
autostarthookcode=[]
|
||||
if needinserthookcode is None:
|
||||
@ -43,84 +93,143 @@ class texthook(basetext ):
|
||||
self.isremoveuseless=savehook_new_data[self.pname]["removeuseless"] and len(self.autostarthookcode)
|
||||
self.needinserthookcode=needinserthookcode
|
||||
self.removedaddress=[]
|
||||
self.HookCode=None
|
||||
self.sharedcell=None
|
||||
self.RPC.callbacks(
|
||||
lambda pid:time.sleep(savehook_new_data[self.pname]['inserthooktimeout']/1000) or [self.RPC.InsertHookCode(pid,hookcode) for hookcode in needinserthookcode]+[self.createembedsharedmem(pid),self.showgamename()],
|
||||
lambda pid: print(pid,"disconenct"),
|
||||
self.onnewhook,
|
||||
self.onremovehook,
|
||||
self.handle_output,
|
||||
gobject.baseobject.hookselectdialog.sysmessagesignal.emit,
|
||||
self.getembedtext,
|
||||
self.newhookinsert
|
||||
)
|
||||
self.setsettings()
|
||||
|
||||
|
||||
gobject.baseobject.hookselectdialog.changeprocessclearsignal.emit()
|
||||
if len(autostarthookcode)==0 and len(savehook_new_data[self.pname]['embedablehook'])==0:
|
||||
gobject.baseobject.hookselectdialog.realshowhide.emit(True)
|
||||
|
||||
|
||||
threading.Thread(target=self.delaycollectallselectedoutput).start()
|
||||
_pids=[]
|
||||
for pid in self.pids:
|
||||
if self.testalready(pid)==False:
|
||||
self.RPC.start(pid)
|
||||
_pids.append(pid)
|
||||
|
||||
if len(_pids):
|
||||
self.RPC.Attach(_pids,'64' if self.is64bit else '32')
|
||||
super(texthook,self).__init__(*self.checkmd5prefix(pname))
|
||||
def testalready(self,pid):
|
||||
_mutext=windows.AutoHandle(windows.CreateMutex(False,define.ITH_HOOKMAN_MUTEX_+str(pid)))
|
||||
err=windows.GetLastError()
|
||||
exists= err==windows.ERROR_ALREADY_EXISTS
|
||||
return exists
|
||||
self.declare()
|
||||
self.start()
|
||||
def declare(self):
|
||||
LunaHost=CDLL(gobject.GetDllpath(('LunaHost32.dll','LunaHost64.dll')))
|
||||
self.Luna_Settings=LunaHost.Luna_Settings
|
||||
self.Luna_Settings.argtypes=c_int,c_bool,c_int,c_int
|
||||
self.Luna_Start=LunaHost.Luna_Start
|
||||
self.Luna_Start.argtypes=POINTER(HANDLE),
|
||||
self.Luna_Inject=LunaHost.Luna_Inject
|
||||
self.Luna_Inject.argtypes=DWORD,LPCWSTR
|
||||
self.Luna_CreatePipeAndCheck=LunaHost.Luna_CreatePipeAndCheck
|
||||
self.Luna_CreatePipeAndCheck.argtypes=DWORD,
|
||||
self.Luna_CreatePipeAndCheck.restype=c_bool
|
||||
self.Luna_InsertHookCode=LunaHost.Luna_InsertHookCode
|
||||
self.Luna_InsertHookCode.argtypes=DWORD,LPCWSTR
|
||||
self.Luna_InsertHookCode.restype=c_bool
|
||||
self.Luna_RemoveHook=LunaHost.Luna_RemoveHook
|
||||
self.Luna_RemoveHook.argtypes=DWORD,c_uint64
|
||||
self.Luna_Detach=LunaHost.Luna_Detach
|
||||
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.argtypes=DWORD,SearchParam,POINTER(HANDLE),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.argtypes=DWORD,c_uint32,c_uint8,c_bool,c_wchar_p,c_uint32,c_uint32
|
||||
self.Luna_checkisusingembed=LunaHost.Luna_checkisusingembed
|
||||
self.Luna_checkisusingembed.argtypes=DWORD,c_uint64,c_uint64,c_uint64
|
||||
self.Luna_checkisusingembed.restype=c_bool
|
||||
self.Luna_useembed=LunaHost.Luna_useembed
|
||||
self.Luna_useembed.argtypes=DWORD,c_uint64,c_uint64,c_uint64,c_bool
|
||||
self.Luna_embedcallback=LunaHost.Luna_embedcallback
|
||||
self.Luna_embedcallback.argtypes=DWORD,LPCWSTR,LPCWSTR
|
||||
def start(self):
|
||||
self.hRead=HANDLE()
|
||||
self.Luna_Start(pointer(self.hRead) )
|
||||
self.setsettings()
|
||||
|
||||
injectpids=[]
|
||||
for pid in self.pids:
|
||||
if globalconfig['use_yapi']:
|
||||
self.Luna_Inject(pid,os.path.abspath('./files/plugins/LunaHook'))
|
||||
else:
|
||||
if(self.Luna_CreatePipeAndCheck(pid)):
|
||||
injectpids.append(pid)
|
||||
if len(injectpids):
|
||||
arch=['32','64'][self.is64bit]
|
||||
injecter=os.path.abspath('./files/plugins/shareddllproxy{}.exe'.format(arch))
|
||||
dll=os.path.abspath('./files/plugins/LunaHook/LunaHook{}.dll'.format(arch))
|
||||
print(injecter,os.path.exists(injecter))
|
||||
print(dll,os.path.exists(dll))
|
||||
#subprocess.Popen('"{}" dllinject {} "{}"'.format(injecter,pid,dll))
|
||||
pid=' '.join([str(_) for _ in injectpids])
|
||||
if any(map(testprivilege,injectpids))==False:
|
||||
windows.ShellExecute(0,'runas',injecter,'dllinject {} "{}"'.format(pid,dll),None,windows.SW_HIDE)
|
||||
else:
|
||||
ret=subprocess.run('"{}" dllinject {} "{}"'.format(injecter,pid,dll)).returncode
|
||||
if(ret==0):
|
||||
windows.ShellExecute(0,'runas',injecter,'dllinject {} "{}"'.format(pid,dll),None,windows.SW_HIDE)
|
||||
threading.Thread(target=self.solveeventthread).start()
|
||||
@threader
|
||||
def onprocconnect(self,pid):
|
||||
time.sleep(savehook_new_data[self.pname]['inserthooktimeout']/1000)
|
||||
for hookcode in self.needinserthookcode:
|
||||
self.Luna_InsertHookCode(pid,hookcode)
|
||||
self.showgamename()
|
||||
self.flashembedsettings(pid)
|
||||
def solveeventthread(self):
|
||||
while self.ending==False:
|
||||
message=windows.ReadFile(self.hRead,sizeof(Message),None)
|
||||
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:
|
||||
gobject.baseobject.hookselectdialog.sysmessagesignal.emit('{} disconenct'.format(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):
|
||||
for _hc,_addr,_ctx1,_ctx2 in savehook_new_data[self.pname]['embedablehook']:
|
||||
if hcode==_hc:
|
||||
self.useembed(addr,_ctx1,_ctx2,True)
|
||||
def getembedtext(self,text,tt):
|
||||
def getembedtext(self,text,tp):
|
||||
if globalconfig['autorun']==False:
|
||||
self.embedcallback(text,0,text)
|
||||
return
|
||||
if self.checkisusingembed(tt.tp.addr,tt.tp.ctx,tt.tp.ctx2):
|
||||
if self.checkisusingembed(tp.addr,tp.ctx,tp.ctx2):
|
||||
self.newline.put((text,False, functools.partial(self.embedcallback,text),True))
|
||||
|
||||
def embedcallback(self,text,_unused,trans):
|
||||
self.sharedcell.contents.text=trans
|
||||
|
||||
self.notify(self.EMBEDPID,text)
|
||||
def createembedsharedmem(self,pid):
|
||||
|
||||
self.EMBEDPID=pid
|
||||
fmap1=windows.OpenFileMapping(windows.FILE_MAP_READ|0x2,False,'EMBED_SHARED_MEM'+str(pid))
|
||||
address1=windows.MapViewOfFile(fmap1, windows.FILE_MAP_READ|0x2, 4096)
|
||||
|
||||
self.sharedcell=ctypes.cast(address1,ctypes.POINTER(define.EmbedSharedMem))
|
||||
self.flashembedsettings()
|
||||
def flashembedsettings(self):
|
||||
if self.sharedcell is None:return
|
||||
self.sharedcell.contents.waittime=int(1000* globalconfig['embedded']['timeout_translate'])
|
||||
self.sharedcell.contents.fontCharSet=2#static_data["charsetmap"][globalconfig['embedded']['changecharset_charset']]
|
||||
self.sharedcell.contents.fontCharSetEnabled=False#globalconfig['embedded']['changecharset']
|
||||
self.sharedcell.contents.fontFamily=globalconfig['embedded']['changefont_font'] if globalconfig['embedded']['changefont'] else ''
|
||||
self.sharedcell.contents.spaceadjustpolicy=globalconfig['embedded']['insertspace_policy']
|
||||
self.sharedcell.contents.keeprawtext=globalconfig['embedded']['keeprawtext']
|
||||
def notify(self,pid,text):
|
||||
_b=text.encode('utf-16-le')
|
||||
def hs(text):
|
||||
_b=text.encode('utf-16-le')
|
||||
u64=ctypes.c_uint64(5381)
|
||||
for i in range(len(_b)):
|
||||
u64=ctypes.c_uint64((u64.value<<5)+u64.value+_b[i])
|
||||
return (u64.value)
|
||||
hash_=hs(text)
|
||||
eventName = define.LUNA_NOTIFY % (pid, hash_)
|
||||
ev = windows.AutoHandle(windows.CreateEvent( False, False, eventName) )
|
||||
windows.SetEvent(ev)
|
||||
for pid in self.pids:
|
||||
self.Luna_embedcallback(pid,text,trans)
|
||||
|
||||
def flashembedsettings(self,pid=None):
|
||||
if pid:
|
||||
pids=[pid]
|
||||
else:
|
||||
pids=self.pids
|
||||
for pid in pids:
|
||||
self.Luna_EmbedSettings(pid,
|
||||
int(1000* globalconfig['embedded']['timeout_translate']),
|
||||
2, #static_data["charsetmap"][globalconfig['embedded']['changecharset_charset']]
|
||||
False,#globalconfig['embedded']['changecharset']
|
||||
globalconfig['embedded']['changefont_font'] if globalconfig['embedded']['changefont'] else '',
|
||||
globalconfig['embedded']['insertspace_policy'],
|
||||
globalconfig['embedded']['keeprawtext'])
|
||||
|
||||
def onremovehook(self,tp):
|
||||
toremove=[]
|
||||
self.lock.acquire()
|
||||
@ -131,26 +240,26 @@ class texthook(basetext ):
|
||||
gobject.baseobject.hookselectdialog.removehooksignal.emit(key)
|
||||
self.hookdatacollecter.pop(key)
|
||||
self.lock.release()
|
||||
def parsetextthread(self,textthread):
|
||||
def parsetextthread(self,hc,hn,tp):
|
||||
key=(
|
||||
textthread.tp.processId,
|
||||
textthread.tp.addr,
|
||||
textthread.tp.ctx,
|
||||
textthread.tp.ctx2,
|
||||
textthread.hp.name.decode('ascii'),
|
||||
textthread.hpcode
|
||||
tp.processId,
|
||||
tp.addr,
|
||||
tp.ctx,
|
||||
tp.ctx2,
|
||||
hn.decode('ascii'),
|
||||
hc
|
||||
)
|
||||
return key
|
||||
def match_compatibility(self,key,autostarthookcode):
|
||||
base= (key[2]&0xffff,key[3]&0xffff,key[5])==(autostarthookcode[2]&0xffff,autostarthookcode[3]&0xffff,autostarthookcode[5])
|
||||
name=((key[-1][:8]=='UserHook' and autostarthookcode[-1][:8]=='UserHook' )or(key[-1]==autostarthookcode[-1]))
|
||||
return base and name
|
||||
def onnewhook(self,textthread):
|
||||
def onnewhook(self,hc,hn,tp):
|
||||
|
||||
key=self.parsetextthread(textthread)
|
||||
key=self.parsetextthread(hc,hn,tp)
|
||||
if self.isremoveuseless:
|
||||
if key[1] not in [_[1] for _ in self.autostarthookcode]:
|
||||
self.RPC.RemoveHook(key[0],key[1])
|
||||
self.Luna_RemoveHook(key[0],key[1])
|
||||
return False
|
||||
|
||||
self.lock.acquire()
|
||||
@ -164,13 +273,11 @@ class texthook(basetext ):
|
||||
|
||||
self.hookdatacollecter[key]=[]
|
||||
self.hooktypecollecter[key]=0
|
||||
gobject.baseobject.hookselectdialog.addnewhooksignal.emit(key ,select,[textthread])
|
||||
gobject.baseobject.hookselectdialog.addnewhooksignal.emit(key ,select,[hc,hn,tp])
|
||||
self.lock.release()
|
||||
return True
|
||||
def setsettings(self):
|
||||
self.RPC.setting.timeout=globalconfig['textthreaddelay']
|
||||
self.RPC.setting.flushbuffersize=globalconfig['flushbuffersize']
|
||||
self.RPC.setting.defaultcodepag=self.codepage()
|
||||
self.Luna_Settings(globalconfig['textthreaddelay'],globalconfig['direct_filterrepeat'],self.codepage() ,globalconfig['flushbuffersize'])
|
||||
def codepage(self):
|
||||
try:
|
||||
cpi=savehook_new_data[self.pname]["codepage_index"]
|
||||
@ -180,7 +287,7 @@ class texthook(basetext ):
|
||||
return cp
|
||||
|
||||
def defaultsp(self):
|
||||
usestruct=define.SearchParam()
|
||||
usestruct=SearchParam()
|
||||
if not self.is64bit:
|
||||
usestruct.pattern=bytes([0x55,0x8b,0xec])
|
||||
usestruct.length=3
|
||||
@ -200,44 +307,44 @@ class texthook(basetext ):
|
||||
usestruct.codepage=self.codepage()
|
||||
usestruct.boundaryModule=os.path.basename(self.pname)
|
||||
return usestruct
|
||||
|
||||
@threader
|
||||
def findhook(self,usestruct):
|
||||
self.savefound={}
|
||||
self.foundnum=0
|
||||
def __waitforok():
|
||||
#time.sleep(usestruct.searchTime/1000)
|
||||
_last=0
|
||||
for i in range(100):
|
||||
#print(self.foundnum)
|
||||
if _last!=self.foundnum or _last==0:
|
||||
_last=self.foundnum
|
||||
time.sleep(1)
|
||||
else:
|
||||
break
|
||||
print('??',_last,self.foundnum)
|
||||
gobject.baseobject.hookselectdialog.getfoundhooksignal.emit(self.savefound.copy())
|
||||
def _(hc,text):
|
||||
# try:print(hc,text)
|
||||
# except:print(hc)
|
||||
if hc not in self.savefound:
|
||||
self.savefound[hc]=[]
|
||||
self.savefound[hc].append(text)
|
||||
if self.foundnum==0:
|
||||
threading.Thread(target=__waitforok).start()
|
||||
self.foundnum+=1
|
||||
#print(self.foundnum)
|
||||
for pid in self.pids:
|
||||
self.RPC.FindHooks(pid,usestruct,_)
|
||||
savefound={}
|
||||
pids=self.pids.copy()
|
||||
|
||||
|
||||
def inserthook(self,hookcode):
|
||||
for pid in self.pids:
|
||||
print(hookcode)
|
||||
self.RPC.InsertHookCode(pid,hookcode)
|
||||
headers={}
|
||||
waiters={}
|
||||
for pid in pids:
|
||||
headers[pid]=HANDLE()
|
||||
count=POINTER(c_int)()
|
||||
waiters[pid]=count
|
||||
self.Luna_FindHooks(pid,usestruct,pointer(headers[pid]),pointer(count))
|
||||
def ReadThread(hread):
|
||||
while True:
|
||||
message=windows.ReadFile(hread,sizeof(simplehooks),None)
|
||||
if len(message)!=sizeof(simplehooks):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)
|
||||
def inserthook(self,hookcode):
|
||||
succ=True
|
||||
for pid in self.pids:
|
||||
succ=self.Luna_InsertHookCode(pid,hookcode) and succ
|
||||
if succ==False:
|
||||
getQMessageBox(gobject.baseobject.hookselectdialog,"Error","Invalie Hook Code Format!")
|
||||
|
||||
def removehook(self,pid,address):
|
||||
for pid in self.pids:
|
||||
self.RPC.RemoveHook(pid,address)
|
||||
self.Luna_RemoveHook(pid,address)
|
||||
def delaycollectallselectedoutput(self):
|
||||
collector=[]
|
||||
while True:
|
||||
@ -249,16 +356,15 @@ class texthook(basetext ):
|
||||
self.newline.put(collector)
|
||||
self.runonce_line=collector
|
||||
collector=[]
|
||||
def handle_output(self,textthread,output):
|
||||
#print(output)
|
||||
key=self.parsetextthread(textthread)
|
||||
def handle_output(self,hc,hn,tp,output):
|
||||
key=self.parsetextthread(hc,hn,tp)
|
||||
|
||||
if globalconfig['filter_chaos_code'] and checkchaos(output):
|
||||
return
|
||||
|
||||
|
||||
if key not in self.hookdatacollecter:
|
||||
if self.onnewhook(textthread)==False:
|
||||
if self.onnewhook(hc,hn,tp)==False:
|
||||
return
|
||||
self.lock.acquire()
|
||||
if self.hooktypecollecter[key]==1:
|
||||
@ -284,31 +390,13 @@ class texthook(basetext ):
|
||||
|
||||
self.lock.release()
|
||||
def checkisusingembed(self,address,ctx1,ctx2):
|
||||
if self.sharedcell is None:return
|
||||
for i in range(10):
|
||||
if(self.sharedcell.contents.using[i]):
|
||||
if (self.sharedcell.contents.addr[i],self.sharedcell.contents.ctx1[i],self.sharedcell.contents.ctx2[i])==(address,ctx1,ctx2):
|
||||
return True
|
||||
|
||||
return False
|
||||
for pid in self.pids:
|
||||
if self.Luna_checkisusingembed(pid,address,ctx1,ctx2):
|
||||
return True
|
||||
return False
|
||||
def useembed(self,address,ctx1,ctx2,use):
|
||||
if self.sharedcell is None:return
|
||||
for i in range(10):
|
||||
if(self.sharedcell.contents.using[i]):
|
||||
if (self.sharedcell.contents.addr[i],self.sharedcell.contents.ctx1[i],self.sharedcell.contents.ctx2[i])==(address,ctx1,ctx2):
|
||||
if use==False:
|
||||
self.sharedcell.contents.addr[i]=0
|
||||
self.sharedcell.contents.ctx1[i]=0
|
||||
self.sharedcell.contents.ctx2[i]=0
|
||||
self.sharedcell.contents.using[i]=0
|
||||
if use:
|
||||
for i in range(10):
|
||||
if(self.sharedcell.contents.using[i]==0):
|
||||
self.sharedcell.contents.using[i]=1
|
||||
self.sharedcell.contents.addr[i]=address
|
||||
self.sharedcell.contents.ctx1[i]=ctx1
|
||||
self.sharedcell.contents.ctx2[i]=ctx2
|
||||
break
|
||||
for pid in self.pids:
|
||||
self.Luna_useembed(pid,address,ctx1,ctx2,use)
|
||||
|
||||
def gettextthread(self ):
|
||||
text=self.newline.get()
|
||||
@ -320,8 +408,7 @@ class texthook(basetext ):
|
||||
return self.runonce_line
|
||||
def end(self):
|
||||
for pid in self.pids:
|
||||
self.RPC.Detach(pid)
|
||||
self.RPC.end()
|
||||
self.Luna_Detach(pid)
|
||||
time.sleep(0.1)
|
||||
super().end()
|
||||
|
@ -1,15 +1,11 @@
|
||||
from ctypes import c_uint,c_bool,POINTER,c_char_p,c_uint64,c_wchar_p,pointer,CDLL,Structure,c_void_p,cast
|
||||
import platform,os
|
||||
import platform,os,gobject
|
||||
|
||||
if platform.architecture()[0]=='64bit':
|
||||
pythonbit='64'
|
||||
else:
|
||||
pythonbit='32'
|
||||
try:
|
||||
if platform.system() != "Windows" or int(platform.version().split('.')[0])<6:
|
||||
raise Exception()
|
||||
|
||||
winrtutilsdll=CDLL(os.path.abspath('./files/plugins/winrtutils{}.dll'.format(pythonbit)) )
|
||||
winrtutilsdll=CDLL(gobject.GetDllpath(('winrtutils32.dll','winrtutils64.dll')))
|
||||
except:
|
||||
winrtutilsdll=0
|
||||
|
||||
|
@ -1,11 +1,7 @@
|
||||
from ctypes import c_uint,c_bool,POINTER,c_char_p,c_uint64,c_wchar_p,pointer,CDLL,c_int,Structure,c_void_p,cast,memmove,create_unicode_buffer,create_string_buffer,c_size_t,windll
|
||||
import platform,os
|
||||
|
||||
if platform.architecture()[0]=='64bit':
|
||||
pythonbit='64'
|
||||
else:
|
||||
pythonbit='32'
|
||||
utilsdll=CDLL(os.path.abspath('./files/plugins/winsharedutils{}.dll'.format(pythonbit)) )
|
||||
import os,gobject
|
||||
|
||||
utilsdll=CDLL(gobject.GetDllpath(('winsharedutils32.dll','winsharedutils64.dll')))
|
||||
|
||||
_freewstringlist=utilsdll.freewstringlist
|
||||
_freewstringlist.argtypes=POINTER(c_wchar_p),c_uint
|
||||
@ -77,8 +73,7 @@ def distance(s1,s2):
|
||||
|
||||
class mecabwrap:
|
||||
def __init__(self,mecabpath) -> None:
|
||||
|
||||
self.kks=_mecab_init(mecabpath.encode('utf8'),os.path.abspath('./files/plugins/libmecab{}.dll'.format(pythonbit)) )
|
||||
self.kks=_mecab_init(mecabpath.encode('utf8'),gobject.GetDllpath('libmecab.dll') )
|
||||
def __del__(self):
|
||||
_mecab_end(self.kks)
|
||||
def parse(self,text):
|
||||
|
@ -118,6 +118,8 @@
|
||||
"isshowhira": false,
|
||||
"locktools": true,
|
||||
"showfanyisource": false,
|
||||
"use_yapi":true,
|
||||
"showfanyi":true,
|
||||
"autoread": false,
|
||||
"show_fenci": false,
|
||||
"jiamingcolor": "black",
|
||||
@ -465,7 +467,7 @@
|
||||
},
|
||||
"_6": {
|
||||
"use": false,
|
||||
"name": "显示/隐藏历史翻译",
|
||||
"name": "显示/隐藏历史翻译和调试输出",
|
||||
"key1": -1,
|
||||
"key2": -1,
|
||||
"keystring": ""
|
||||
|
File diff suppressed because one or more lines are too long
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "نص طول المخزن المؤقت",
|
||||
"显示/隐藏历史翻译和调试输出": "عرض / إخفاء تاريخ الترجمة وتصحيح الأخطاء الناتج",
|
||||
"历史翻译和调试输出": "تاريخ الترجمة وتصحيح الأخطاء الناتج",
|
||||
"调试输出": "التصحيح الناتج"
|
||||
"调试输出": "التصحيح الناتج",
|
||||
"显示翻译": "عرض الترجمة",
|
||||
"使用YAPI注入": "استخدام حقن YAPI"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "文字緩衝區長度",
|
||||
"显示/隐藏历史翻译和调试输出": "顯示/隱藏歷史翻譯和調試輸出",
|
||||
"历史翻译和调试输出": "歷史翻譯和調試輸出",
|
||||
"调试输出": "調試輸出"
|
||||
"调试输出": "調試輸出",
|
||||
"显示翻译": "顯示翻譯",
|
||||
"使用YAPI注入": "使用YAPI注入"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Text buffer length",
|
||||
"显示/隐藏历史翻译和调试输出": "Show/hide historical translation and debugging output",
|
||||
"历史翻译和调试输出": "Historical translation and debugging output",
|
||||
"调试输出": "Debugging output"
|
||||
"调试输出": "Debugging output",
|
||||
"显示翻译": "Display translation",
|
||||
"使用YAPI注入": "Using YAPI injection"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Longitud del colchón de texto",
|
||||
"显示/隐藏历史翻译和调试输出": "Mostrar / ocultar la traducción histórica y depurar la salida",
|
||||
"历史翻译和调试输出": "Traducción histórica y salida de depuración",
|
||||
"调试输出": "Salida de depuración"
|
||||
"调试输出": "Salida de depuración",
|
||||
"显示翻译": "Mostrar traducción",
|
||||
"使用YAPI注入": "Inyección con Yapi"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Longueur du tampon de texte",
|
||||
"显示/隐藏历史翻译和调试输出": "Afficher / masquer la traduction historique et la sortie de débogage",
|
||||
"历史翻译和调试输出": "Traduction historique et sortie de débogage",
|
||||
"调试输出": "Sortie de débogage"
|
||||
"调试输出": "Sortie de débogage",
|
||||
"显示翻译": "Afficher la traduction",
|
||||
"使用YAPI注入": "Injection avec Yapi"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Lunghezza buffer di testo",
|
||||
"显示/隐藏历史翻译和调试输出": "Mostra/nasconde l'output storico di traduzione e debug",
|
||||
"历史翻译和调试输出": "Risultato storico di traduzione e debug",
|
||||
"调试输出": "Debug output"
|
||||
"调试输出": "Debug output",
|
||||
"显示翻译": "Mostra traduzione",
|
||||
"使用YAPI注入": "Uso dell'iniezione di YAPI"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "テキストバッファ長",
|
||||
"显示/隐藏历史翻译和调试输出": "履歴翻訳とデバッグ出力の表示/非表示",
|
||||
"历史翻译和调试输出": "履歴翻訳とデバッグ出力",
|
||||
"调试输出": "デバッグ出力"
|
||||
"调试输出": "デバッグ出力",
|
||||
"显示翻译": "翻訳を表示",
|
||||
"使用YAPI注入": "YAPI注入を使用する"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "텍스트 버퍼 길이",
|
||||
"显示/隐藏历史翻译和调试输出": "히스토리 번역 및 디버그 출력 표시 / 숨기기",
|
||||
"历史翻译和调试输出": "역사 번역 및 디버그 출력",
|
||||
"调试输出": "출력 디버그"
|
||||
"调试输出": "출력 디버그",
|
||||
"显示翻译": "번역 표시",
|
||||
"使用YAPI注入": "YAPI 주입 사용"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Długość bufora tekstu",
|
||||
"显示/隐藏历史翻译和调试输出": "Pokaż/ukryj historyczne tłumaczenie i wyjście debugowania",
|
||||
"历史翻译和调试输出": "Historiczne tłumaczenie i debugowanie",
|
||||
"调试输出": "Wyjście debugowania"
|
||||
"调试输出": "Wyjście debugowania",
|
||||
"显示翻译": "Wyświetl tłumaczenie",
|
||||
"使用YAPI注入": "Zastosowanie wstrzykiwań YAPI"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Длина буфера текста",
|
||||
"显示/隐藏历史翻译和调试输出": "Показать / скрыть исторический перевод и отладочный вывод",
|
||||
"历史翻译和调试输出": "Исторический перевод и отладка вывода",
|
||||
"调试输出": "Отладочный вывод"
|
||||
"调试输出": "Отладочный вывод",
|
||||
"显示翻译": "Показать перевод",
|
||||
"使用YAPI注入": "Использовать инъекцию YAPI"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "ความยาวบัฟเฟอร์ข้อความ",
|
||||
"显示/隐藏历史翻译和调试输出": "แสดง / ซ่อนการแปลประวัติและการแก้จุดบกพร่องเอาท์พุท",
|
||||
"历史翻译和调试输出": "การแปลประวัติและการแก้จุดบกพร่องเอาท์พุท",
|
||||
"调试输出": "การว่าจ้างเอาท์พุท"
|
||||
"调试输出": "การว่าจ้างเอาท์พุท",
|
||||
"显示翻译": "แสดงคำแปล",
|
||||
"使用YAPI注入": "ใช้ YAPI ฉีด"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Metin buffer uzunluğu",
|
||||
"显示/隐藏历史翻译和调试输出": "Tarihi çevirimi ve arızasızlandırma çıkışını göster/gizle",
|
||||
"历史翻译和调试输出": "Tarihi çeviri ve hata ayıklama çıkışı",
|
||||
"调试输出": "Hata ayıklama çıkışı"
|
||||
"调试输出": "Hata ayıklama çıkışı",
|
||||
"显示翻译": "Çeviri göster",
|
||||
"使用YAPI注入": "YAPI injeksiyonu kullanıyor"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Довжина текстового буфера",
|
||||
"显示/隐藏历史翻译和调试输出": "Показувати/сховати історичний переклад і вивід зневаджування",
|
||||
"历史翻译和调试输出": "Історічний переклад і вивід зневаджування",
|
||||
"调试输出": "Вивод зневаджування"
|
||||
"调试输出": "Вивод зневаджування",
|
||||
"显示翻译": "Показувати переклад",
|
||||
"使用YAPI注入": "Використання інструкції YAPI"
|
||||
}
|
@ -685,5 +685,7 @@
|
||||
"文本缓冲区长度": "Chiều dài bộ đệm văn bản",
|
||||
"显示/隐藏历史翻译和调试输出": "Hiển thị/ẩn lịch sử dịch và đầu ra gỡ lỗi",
|
||||
"历史翻译和调试输出": "Lịch sử dịch và gỡ lỗi đầu ra",
|
||||
"调试输出": "Đầu ra gỡ lỗi"
|
||||
"调试输出": "Đầu ra gỡ lỗi",
|
||||
"显示翻译": "Hiện bản dịch",
|
||||
"使用YAPI注入": "Sử dụng YAPI Injection"
|
||||
}
|
@ -686,5 +686,6 @@
|
||||
"历史翻译和调试输出": "",
|
||||
"历史翻译": "",
|
||||
"调试输出": "",
|
||||
"显示/隐藏历史翻译": ""
|
||||
"显示翻译": "",
|
||||
"使用YAPI注入": ""
|
||||
}
|
@ -6,27 +6,15 @@ if x86:
|
||||
nuitkadist=r'..\build\x86\LunaTranslator_main.dist'
|
||||
targetdir=r'..\build\LunaTranslator_x86'
|
||||
launch=r'..\plugins\exec\builds\_x86'
|
||||
badcdlls= [
|
||||
'libcurl-x64.dll','libmecab64.dll',
|
||||
'ocr64.dll',
|
||||
'winsharedutils64.dll','winrtutils64.dll',
|
||||
r'brotli\x64\brotlicommon.dll',
|
||||
r'brotli\x64\brotlidec.dll',
|
||||
]
|
||||
downlevel=f'C:\Windows\SysWOW64\downlevel'
|
||||
target='LunaTranslator_x86.zip'
|
||||
baddll='DLL64'
|
||||
else:
|
||||
baddll='DLL32'
|
||||
target='LunaTranslator.zip'
|
||||
launch=r'..\plugins\exec\builds\_x64'
|
||||
nuitkadist=r'..\build\x64\LunaTranslator_main.dist'
|
||||
targetdir=r'..\build\LunaTranslator'
|
||||
badcdlls= [
|
||||
'libcurl.dll','libmecab32.dll',
|
||||
'ocr32.dll',
|
||||
'winsharedutils32.dll','winrtutils32.dll',
|
||||
r'brotli\x86\brotlicommon.dll',
|
||||
r'brotli\x86\brotlidec.dll',
|
||||
]
|
||||
downlevel=f'C:\Windows\system32\downlevel'
|
||||
targetdir_in=rf'{targetdir}\LunaTranslator'
|
||||
def get_import_table(file_path):
|
||||
@ -62,9 +50,7 @@ for f in [
|
||||
for f in ['imageformats','platforms','styles']:
|
||||
os.rename(rf'{targetdir_in}\PyQt5\qt-plugins\{f}',rf'{targetdir_in}\{f}')
|
||||
|
||||
|
||||
for f in badcdlls:
|
||||
remove(rf'{targetdir}\files\plugins\{f}')
|
||||
remove(rf'{targetdir}\files\plugins\{baddll}')
|
||||
|
||||
collect=[]
|
||||
for _dir,_,fs in os.walk(targetdir):
|
||||
|
Loading…
x
Reference in New Issue
Block a user