From 3682ccebe92a4eea6d5c9e837875fc121b8f3895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=81=8D=E5=85=AE=E6=83=9A=E5=85=AE?= <101191390+HIllya51@users.noreply.github.com> Date: Thu, 8 Feb 2024 21:48:24 +0800 Subject: [PATCH] =?UTF-8?q?renpy2&3=E5=86=85=E5=B5=8C=E7=BF=BB=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LunaHook/embed_util.cc | 24 +++++++++++------------- LunaHook/engine32/CatSystem.cpp | 3 +-- LunaHook/engines/python/python2.cpp | 25 ++++++++++++++++++++++++- LunaHook/engines/python/python3.cpp | 28 ++++++++++++++++++++++++---- LunaHook/main.cc | 1 - LunaHook/texthook.cc | 1 - LunaHost/host.cpp | 14 ++++++-------- LunaHost/textthread.cpp | 4 +--- include/const.h | 3 ++- include/stringutils.cpp | 10 ++++++++++ include/stringutils.h | 2 ++ include/types.h | 4 ++-- 12 files changed, 83 insertions(+), 36 deletions(-) diff --git a/LunaHook/embed_util.cc b/LunaHook/embed_util.cc index 8a461d6..df2deee 100644 --- a/LunaHook/embed_util.cc +++ b/LunaHook/embed_util.cc @@ -8,14 +8,10 @@ #include"defs.h" DynamicShiftJISCodec *dynamiccodec=new DynamicShiftJISCodec(932); -std::wstring cast_a2w(HookParam hp,void*data ,size_t len){ - if(hp.type&CODEC_UTF16) - return std::wstring((wchar_t*)(data),len/2); - return StringToWideString(std::string((char*)data,len),hp.codepage?hp.codepage:embedsharedmem->codepage).value(); -} -void cast_back(HookParam hp,void*data ,size_t *len,std::wstring trans,bool normal){ - if(hp.type&CODEC_UTF16){ +void cast_back(const HookParam& hp,void*data ,size_t *len,const std::wstring& trans,bool normal){ + + if((hp.type&EMBED_CODEC_UTF16)||(hp.type&CODEC_UTF16)){//renpy wcscpy((wchar_t*)data,trans.c_str()); *len=trans.size()*2; } @@ -25,8 +21,7 @@ void cast_back(HookParam hp,void*data ,size_t *len,std::wstring trans,bool norma astr=dynamiccodec->encodeSTD(trans,0); } else{ - astr=WideStringToString(trans,hp.codepage?hp.codepage:embedsharedmem->codepage); - + astr=WideStringToString(trans,hp.codepage?hp.codepage:((hp.type&CODEC_UTF8)?CP_UTF8:embedsharedmem->codepage)); } strcpy((char*)data,astr.c_str()); *len=astr.size(); @@ -207,11 +202,14 @@ bool waitforevent(UINT32 timems,const ThreadParam& tp,const std::wstring &origin return false; } bool TextHook::waitfornotify(TextOutput_T* buffer,void*data ,size_t*len,ThreadParam tp){ - - auto origin=cast_a2w(hp,data,*len); + std::wstring origin; + if (auto t=commonparsestring(data,*len,&hp,embedsharedmem->codepage)) origin=t.value(); + else return false; if(origin.size()>1000)return false; - if(hp.newlineseperator)strReplace(origin,hp.newlineseperator,L"\n"); - cast_back(hp,data,len,origin,true); + if(hp.newlineseperator){ + strReplace(origin,hp.newlineseperator,L"\n"); + cast_back(hp,data,len,origin,true); + } TextOutput(tp, buffer, *len); std::wstring translate; diff --git a/LunaHook/engine32/CatSystem.cpp b/LunaHook/engine32/CatSystem.cpp index ba64da8..ff2890d 100644 --- a/LunaHook/engine32/CatSystem.cpp +++ b/LunaHook/engine32/CatSystem.cpp @@ -215,8 +215,7 @@ bool InsertCatSystem2Hook() HookParam hp; hp.address = addr; hp.offset=get_reg(regs::eax); - hp.codepage = 65001; - hp.type = USING_STRING; + hp.type = USING_STRING|CODEC_UTF8; ConsoleOutput("INSERT CatSystem2new"); return NewHook(hp, "CatSystem2new"); diff --git a/LunaHook/engines/python/python2.cpp b/LunaHook/engines/python/python2.cpp index 6072343..4f64354 100644 --- a/LunaHook/engines/python/python2.cpp +++ b/LunaHook/engines/python/python2.cpp @@ -53,6 +53,12 @@ namespace { auto fmtcnt = PyUnicode_GET_SIZE(uformat); return {fmt,fmtcnt}; } + + typedef PyObject* (*PyUnicode_FromUnicode_t)( + const Py_UNICODE *u, /* Unicode buffer */ + Py_ssize_t size /* size of buffer */ + ); + PyUnicode_FromUnicode_t PyUnicode_FromUnicode; } bool InsertRenpyHook(){ @@ -66,11 +72,26 @@ bool InsertRenpyHook(){ if (HMODULE module = GetModuleHandleW(name)) { PyUnicode_FromObject=(PyUnicode_FromObject_t)GetProcAddress(module, "PyUnicodeUCS2_FromObject"); + PyUnicode_FromUnicode=(PyUnicode_FromUnicode_t)GetProcAddress(module, "PyUnicodeUCS2_FromUnicode"); auto f1=[=](){ HookParam hp; hp.address = (uintptr_t)GetProcAddress(module, "PyUnicodeUCS2_Format"); if (!hp.address) return false; - + hp.hook_after=[](hook_stack* stack,void* data, size_t len) + { + #ifndef _WIN64 + auto format=(PyObject *)stack->stack[1]; + #else + auto format=(PyObject *)stack->rcx; + #endif + if(format==NULL)return; + #ifndef _WIN64 + stack->stack[1]= + #else + stack->rcx= + #endif + (uintptr_t)PyUnicode_FromUnicode((Py_UNICODE *)data,len/2); + }; hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len) { #ifndef _WIN64 @@ -87,6 +108,8 @@ bool InsertRenpyHook(){ }; hp.type = USING_STRING | CODEC_UTF16 | NO_CONTEXT; + if(PyUnicode_FromUnicode) + hp.type|=EMBED_ABLE|EMBED_BEFORE_SIMPLE; return NewHook(hp, "Ren'py"); }(); diff --git a/LunaHook/engines/python/python3.cpp b/LunaHook/engines/python/python3.cpp index 5700b7e..ca6b181 100644 --- a/LunaHook/engines/python/python3.cpp +++ b/LunaHook/engines/python/python3.cpp @@ -104,7 +104,12 @@ enum PyUnicode_Kind { ) \ )) - + typedef PyObject* (*PyUnicode_FromString_t)(const char *u); + PyUnicode_FromString_t PyUnicode_FromString; + typedef PyObject* (*PyUnicode_FromKindAndData_t)(int kind, + const void *buffer, + Py_ssize_t size); + PyUnicode_FromKindAndData_t PyUnicode_FromKindAndData; } #ifdef _WIN64 @@ -123,7 +128,20 @@ bool InsertRenpy3Hook() uintptr_t addr = (uintptr_t)GetProcAddress(module, "PyUnicode_Format"); if (addr) { HookParam hp; + PyUnicode_FromString=(PyUnicode_FromString_t)GetProcAddress(module, "PyUnicode_FromString"); + PyUnicode_FromKindAndData=(PyUnicode_FromKindAndData_t)GetProcAddress(module, "PyUnicode_FromKindAndData"); hp.address = addr; + if(PyUnicode_FromKindAndData) + { + hp.type=EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_CODEC_UTF16; + hp.hook_after=[](hook_stack* stack,void* data, size_t len) + { + auto format=(PyObject *)stack->rcx; + if (format == NULL ) + return; + stack->rcx=(uintptr_t)PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND,data,len/2); + }; + } hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len) { auto format=(PyObject *)stack->rcx; @@ -141,19 +159,21 @@ bool InsertRenpy3Hook() } *data=(uintptr_t)fmtdata; + if(PyUnicode_FromString) + hp->type=EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_CODEC_UTF16; switch (fmtkind) { case PyUnicode_WCHAR_KIND: case PyUnicode_2BYTE_KIND: - hp->type=CODEC_UTF16|USING_STRING|NO_CONTEXT; + hp->type|=CODEC_UTF16|USING_STRING|NO_CONTEXT; *len=fmtcnt*sizeof(Py_UCS2); break; case PyUnicode_1BYTE_KIND: - hp->type=CODEC_UTF8|USING_STRING|NO_CONTEXT; + hp->type|=CODEC_UTF8|USING_STRING|NO_CONTEXT; *len=fmtcnt*sizeof(Py_UCS1); break; case PyUnicode_4BYTE_KIND://Py_UCS4,utf32 - hp->type=CODEC_UTF32|USING_STRING|NO_CONTEXT; + hp->type|=CODEC_UTF32|USING_STRING|NO_CONTEXT; *len=fmtcnt*sizeof(Py_UCS4); } }; diff --git a/LunaHook/main.cc b/LunaHook/main.cc index 852b50f..60a0cae 100644 --- a/LunaHook/main.cc +++ b/LunaHook/main.cc @@ -172,7 +172,6 @@ bool NewHook(HookParam hp, LPCSTR lpname) ConsoleOutput(INSERTING_HOOK, hp.name); RemoveHook(hp.address, 0); - if (hp.type & CODEC_UTF8) hp.codepage = CP_UTF8; wcscpy_s(hp.hookcode,HOOKCODE_LEN,HookCode::Generate(hp, GetCurrentProcessId()).c_str()); if (!(*hooks)[currentHook].Insert(hp)) { diff --git a/LunaHook/texthook.cc b/LunaHook/texthook.cc index ad16a9c..709ec80 100644 --- a/LunaHook/texthook.cc +++ b/LunaHook/texthook.cc @@ -99,7 +99,6 @@ bool TextHook::Insert(HookParam hp) local_buffer=new BYTE[PIPE_BUFFER_SIZE]; { std::scoped_lock lock(viewMutex); - if (hp.type & CODEC_UTF8) hp.codepage = CP_UTF8; this->hp = hp; address = hp.address; } diff --git a/LunaHost/host.cpp b/LunaHost/host.cpp index 3e8f67c..b8b3701 100644 --- a/LunaHost/host.cpp +++ b/LunaHost/host.cpp @@ -175,14 +175,12 @@ namespace if(embedcallback){ auto & hp=thread->second.hp; if(hp.type&EMBED_ABLE){ - std::wstring text; - if (hp.type & CODEC_UTF16)text=(std::wstring((wchar_t*)data->data, length / sizeof(wchar_t))); - else if (auto converted = StringToWideString(std::string((char*)data->data, length), hp.codepage ? hp.codepage : Host::defaultCodepage))text=(converted.value()); - else text=L""; - if(text.size()){ - embedcallback(text,tp); - } - + if (auto t=commonparsestring(data->data,length,&hp,Host::defaultCodepage)){ + auto text=t.value(); + if(text.size()){ + embedcallback(text,tp); + } + } } } diff --git a/LunaHost/textthread.cpp b/LunaHost/textthread.cpp index b0912b9..a1528aa 100644 --- a/LunaHost/textthread.cpp +++ b/LunaHost/textthread.cpp @@ -58,9 +58,7 @@ void TextThread::Push(BYTE* data, int length) } if (hp.type & HEX_DUMP) for (int i = 0; i < length; i += sizeof(short)) buffer.append(FormatString(L"%04hX ", *(short*)(data + i))); - else if (hp.type & CODEC_UTF16) buffer.append((wchar_t*)data, length / sizeof(wchar_t)); - else if(hp.type&CODEC_UTF32)buffer.append(std::move(utf32_to_utf16(data,length))); - else if (auto converted = StringToWideString(std::string((char*)data, length), hp.codepage ? hp.codepage : Host::defaultCodepage)) buffer.append(converted.value()); + else if (auto converted = commonparsestring(data,length,&hp,Host::defaultCodepage)) buffer.append(converted.value()); else Host::AddConsoleOutput(INVALID_CODEPAGE); if (hp.type & FULL_STRING) buffer.push_back(L'\n'); lastPushTime = GetTickCount64(); diff --git a/include/const.h b/include/const.h index c6ebcc2..b17d60d 100644 --- a/include/const.h +++ b/include/const.h @@ -26,7 +26,7 @@ enum HostNotificationType { HOST_SETTEXTTHREADTYPE }; -enum HookParamType : unsigned +enum HookParamType : uint64_t { //默认为CODEC_ANSI_LE&USING_CHAR //若使用了text_fun|hook_before,会改为默认USING_STRING,这时若其实是USING_CHAR,需标明USING_STRING @@ -56,6 +56,7 @@ enum HookParamType : unsigned EMBED_BEFORE_SIMPLE=0x200000, EMBED_AFTER_NEW=0x400000, EMBED_AFTER_OVERWRITE=0x800000, + EMBED_CODEC_UTF16=0x4000000 }; diff --git a/include/stringutils.cpp b/include/stringutils.cpp index 33062e5..f178544 100644 --- a/include/stringutils.cpp +++ b/include/stringutils.cpp @@ -170,3 +170,13 @@ size_t u32strlen(uint32_t* data){ s++; return s; } + +#include"const.h" +#include"types.h" +std::optional commonparsestring(void* data,size_t length,void* php,DWORD df){ + auto hp=(HookParam*)php; + if (hp->type & CODEC_UTF16) return std::wstring((wchar_t*)data, length / sizeof(wchar_t)); + else if(hp->type&CODEC_UTF32)return (std::move(utf32_to_utf16(data,length))); + else if (auto converted = StringToWideString(std::string((char*)data, length), hp->codepage ? hp->codepage : ((hp->type&CODEC_UTF8)?CP_UTF8:df))) return (converted.value()); + else return {}; +} \ No newline at end of file diff --git a/include/stringutils.h b/include/stringutils.h index 20371cf..da82fd2 100644 --- a/include/stringutils.h +++ b/include/stringutils.h @@ -57,5 +57,7 @@ inline std::wstring FormatString(const wchar_t* format, const Args&... args) _swprintf(buffer.data(), format, FormatArg(args)...); return buffer; } + +std::optional commonparsestring(void*,size_t,void*,DWORD); #pragma warning(pop) #endif \ No newline at end of file diff --git a/include/types.h b/include/types.h index 2831bdb..e415ab7 100644 --- a/include/types.h +++ b/include/types.h @@ -80,7 +80,7 @@ struct HookParam wchar_t module[MAX_MODULE_SIZE]; char function[MAX_MODULE_SIZE]; - DWORD type; // flags + uint64_t type; // flags UINT codepage; // text encoding short length_offset; // index of the string length ALIGNPTR(uint64_t __1,uintptr_t padding); // padding before string @@ -184,6 +184,6 @@ struct HookInsertingNotif // From dll struct TextOutput_T { ThreadParam tp; - DWORD type; + uint64_t type; BYTE data[0]; }; \ No newline at end of file