This commit is contained in:
恍兮惚兮 2024-05-04 13:08:39 +08:00
parent 0df844a816
commit 892eccb17f
9 changed files with 87 additions and 145 deletions

View File

@ -76,8 +76,6 @@ bool _1f()
#undef ADD_FUN #undef ADD_FUN
return 0; return 0;
} }
extern bool DetourAttachedUserAddr;
extern bool hostconnected;
bool _1=_1f(); bool _1=_1f();
void ReplaceFunction(PVOID* oldf,PVOID newf){ void ReplaceFunction(PVOID* oldf,PVOID newf){
@ -121,7 +119,7 @@ void solvefont(HookParam hp){
if (auto current_patch_fun = patch_fun.exchange(nullptr)){ if (auto current_patch_fun = patch_fun.exchange(nullptr)){
current_patch_fun(); current_patch_fun();
DetourAttachedUserAddr=true; dont_detach=true;
} }
} }
static std::wstring alwaysInsertSpacesSTD(const std::wstring& text) static std::wstring alwaysInsertSpacesSTD(const std::wstring& text)
@ -187,7 +185,7 @@ bool check_is_thread_selected(const ThreadParam& tp){
return false; return false;
} }
bool check_embed_able(const ThreadParam& tp){ bool check_embed_able(const ThreadParam& tp){
return hostconnected&&check_is_thread_selected(tp)&&((isPauseKeyPressed()==false)?true:!embedsharedmem->fastskipignore); return host_connected&&check_is_thread_selected(tp)&&((isPauseKeyPressed()==false)?true:!embedsharedmem->fastskipignore);
} }
bool waitforevent(UINT32 timems,const ThreadParam& tp,const std::wstring &origin){ bool waitforevent(UINT32 timems,const ThreadParam& tp,const std::wstring &origin){
char eventname[1000]; char eventname[1000];

View File

@ -444,7 +444,7 @@ bool hookPPSSPPDoJit(){
auto em_address=*(uintptr_t*)(hp->user_value); auto em_address=*(uintptr_t*)(hp->user_value);
if(!IsValidAddress(em_address))return; if(!IsValidAddress(em_address))return;
[&](){ [&](){
auto ret=stack->RETADDR; auto ret=stack->LASTRETVAL;
if(breakpoints.find(ret)!=breakpoints.end())return; if(breakpoints.find(ret)!=breakpoints.end())return;
breakpoints.insert(ret); breakpoints.insert(ret);

View File

@ -23,11 +23,12 @@ PyRun_SimpleString_t PyRun_SimpleString;
PyGILState_Release_t PyGILState_Release; PyGILState_Release_t PyGILState_Release;
PyGILState_Ensure_t PyGILState_Ensure; PyGILState_Ensure_t PyGILState_Ensure;
void LoadPyRun(HMODULE module) bool LoadPyRun(HMODULE module)
{ {
PyGILState_Ensure=(PyGILState_Ensure_t)GetProcAddress(module, "PyGILState_Ensure"); PyGILState_Ensure=(PyGILState_Ensure_t)GetProcAddress(module, "PyGILState_Ensure");
PyGILState_Release=(PyGILState_Release_t)GetProcAddress(module, "PyGILState_Release"); PyGILState_Release=(PyGILState_Release_t)GetProcAddress(module, "PyGILState_Release");
PyRun_SimpleString=(PyRun_SimpleString_t)GetProcAddress(module, "PyRun_SimpleString"); PyRun_SimpleString=(PyRun_SimpleString_t)GetProcAddress(module, "PyRun_SimpleString");
return PyGILState_Ensure&&PyGILState_Release&&PyRun_SimpleString;
} }
void PyRunScript(const char* script) void PyRunScript(const char* script)
@ -254,10 +255,12 @@ extern "C" __declspec(dllexport) const wchar_t* internal_renpy_get_font(){
else return fontname2fontfile.at(embedsharedmem->fontFamily).c_str(); else return fontname2fontfile.at(embedsharedmem->fontFamily).c_str();
} }
} }
void hookrenpy(HMODULE module){ bool hookrenpy(HMODULE module){
LoadPyRun(module); if(!LoadPyRun(module))return false;
patch_fun=[](){ patch_fun=[](){
PyRunScript(LoadResData(L"renpy_hook_font",L"PYSOURCE").c_str()); PyRunScript(LoadResData(L"renpy_hook_font",L"PYSOURCE").c_str());
}; };
hook_internal_renpy_call_host(); hook_internal_renpy_call_host();
dont_detach=true;
return true;
} }

View File

@ -4,4 +4,4 @@ bool InsertRenpy3Hook();
bool InsertRenpyHook(); bool InsertRenpyHook();
void hookrenpy(HMODULE module); bool hookrenpy(HMODULE module);

View File

@ -39,21 +39,22 @@ namespace {
PyUnicode_FromObject_t PyUnicode_FromObject; PyUnicode_FromObject_t PyUnicode_FromObject;
inline std::pair<Py_UNICODE*,Py_ssize_t> GetPyUnicodeString(PyObject *object){ inline void GetPyUnicodeString(PyObject *object,uintptr_t* data, size_t* len){
if(PyUnicode_FromObject==NULL)
return {};
if (object == NULL) if (object == NULL)
return {}; return;
auto uformat = PyUnicode_FromObject(object); auto uformat = PyUnicode_FromObject(object);
if (uformat == NULL){ if (uformat == NULL){
return {}; return;
} }
auto fmt = PyUnicode_AS_UNICODE(uformat); auto fmt = PyUnicode_AS_UNICODE(uformat);
auto fmtcnt = PyUnicode_GET_SIZE(uformat); auto fmtcnt = PyUnicode_GET_SIZE(uformat);
return {fmt,fmtcnt}; *data=(uintptr_t)fmt;
if(wcschr(fmt, L'%') == nullptr)
*len=sizeof(wchar_t)*fmtcnt;
} }
typedef PyObject* (*PyUnicode_FromUnicode_t)( typedef PyObject* (*PyUnicode_FromUnicode_t)(
@ -74,25 +75,19 @@ bool InsertRenpyHook(){
*pos = L'0' + pythonMinorVersion; *pos = L'0' + pythonMinorVersion;
if (HMODULE module = GetModuleHandleW(name)) 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=[=](){ auto f1=[=](){
PyUnicode_FromObject=(PyUnicode_FromObject_t)GetProcAddress(module, "PyUnicodeUCS2_FromObject");
PyUnicode_FromUnicode=(PyUnicode_FromUnicode_t)GetProcAddress(module, "PyUnicodeUCS2_FromUnicode");
auto addr= (uintptr_t)GetProcAddress(module, "PyUnicodeUCS2_Format");
if (!addr||!PyUnicode_FromObject) return false;
HookParam hp; HookParam hp;
hp.address = (uintptr_t)GetProcAddress(module, "PyUnicodeUCS2_Format"); hp.address =addr;
if (!hp.address) return false; hp.type = USING_STRING | CODEC_UTF16 | NO_CONTEXT;
hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len) hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len)
{ {
auto format=(PyObject *)stack->ARG1; auto format=(PyObject *)stack->ARG1;
auto [strptr,strlen]=GetPyUnicodeString(format); GetPyUnicodeString(format,data,len);
*data=(uintptr_t)strptr;
*len=0;
if(wcschr(strptr, L'%') == nullptr)
*len=sizeof(wchar_t)*strlen;
}; };
hp.type = USING_STRING | CODEC_UTF16 | NO_CONTEXT;
if(PyUnicode_FromUnicode) if(PyUnicode_FromUnicode)
{ {
hp.type|=EMBED_ABLE|EMBED_BEFORE_SIMPLE; hp.type|=EMBED_ABLE|EMBED_BEFORE_SIMPLE;
@ -102,48 +97,12 @@ bool InsertRenpyHook(){
if(format==NULL)return; if(format==NULL)return;
stack->ARG1=(uintptr_t)PyUnicode_FromUnicode((Py_UNICODE *)data,len/2); stack->ARG1=(uintptr_t)PyUnicode_FromUnicode((Py_UNICODE *)data,len/2);
}; };
hookrenpy(module);
} }
return NewHook(hp, "Ren'py"); return NewHook(hp, "Ren'py");
}(); }();
auto f3=hookrenpy(module);
#if 0 return f1||f3;
auto f2=[=](){
HookParam hp;
hp.address = (uintptr_t)GetProcAddress(module, "PyUnicodeUCS2_Concat");
if (!hp.address) return false;
hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len)
{
auto left=(PyObject *)stack->stack[1];
auto right=(PyObject *)stack->stack[2];
auto [strptr,strlen]=GetPyUnicodeString(right);
*data=(uintptr_t)strptr;
*len=sizeof(wchar_t)*strlen;
};
hp.filter_fun = [](void* data, size_t* len, HookParam* hp)
{
auto str=std::wstring(reinterpret_cast<LPWSTR>(data),*len/2);
auto filterpath={
L".rpy",L".rpa",L".py",L".pyc",L".txt",
L".png",L".jpg",L".bmp",
L".mp3",L".ogg",
L".webm",L".mp4",
L".otf",L".ttf"
};
for(auto _ :filterpath)
if(str.find(_)!=str.npos)
return false;
return true;
};
hp.type = USING_STRING | CODEC_UTF16;
//hp.filter_fun = [](void* str, auto, auto, auto) { return *(wchar_t*)str != L'%'; };
return NewHook(hp, "Ren'py");
}();
#else
auto f2=false;
#endif
return f1||f2;
} }
} }
} }

View File

@ -118,7 +118,40 @@ enum PyUnicode_Kind {
} }
#ifdef _WIN64 #ifdef _WIN64
void DoReadPyString(PyObject* fmtstr,HookParam* hp,uintptr_t* data, size_t* len){
if (fmtstr == NULL )
return ;
auto fmtdata = PyUnicode_DATA(fmtstr);
auto fmtkind = PyUnicode_KIND(fmtstr);
auto fmtcnt = PyUnicode_GET_LENGTH(fmtstr);
for(auto i=0;i<fmtcnt;i++){
if(PyUnicode_READ(fmtkind,fmtdata,i)=='%')
return;
}
*data=(uintptr_t)fmtdata;
hp->type&=~CODEC_UTF8;
hp->type&=~CODEC_UTF16;
hp->type&=~CODEC_UTF32;
switch (fmtkind)
{
case PyUnicode_WCHAR_KIND:
case PyUnicode_2BYTE_KIND:
hp->type|=CODEC_UTF16;
*len=fmtcnt*sizeof(Py_UCS2);
break;
case PyUnicode_1BYTE_KIND:
hp->type|=CODEC_UTF8;
*len=fmtcnt*sizeof(Py_UCS1);
break;
case PyUnicode_4BYTE_KIND://Py_UCS4,utf32
hp->type|=CODEC_UTF32;
*len=fmtcnt*sizeof(Py_UCS4);
}
}
bool InsertRenpy3Hook() bool InsertRenpy3Hook()
{ {
wchar_t pythonf[] = L"python3%d.dll", libpython[] = L"libpython3.%d.dll"; wchar_t pythonf[] = L"python3%d.dll", libpython[] = L"libpython3.%d.dll";
@ -130,16 +163,23 @@ bool InsertRenpy3Hook()
wsprintf(python, pythonff, pythonMinorVersion); wsprintf(python, pythonff, pythonMinorVersion);
if (HMODULE module = GetModuleHandleW(python)) if (HMODULE module = GetModuleHandleW(python))
{ {
auto succ=false; auto f1=[=](){
uintptr_t addr = (uintptr_t)GetProcAddress(module, "PyUnicode_Format"); uintptr_t addr = (uintptr_t)GetProcAddress(module, "PyUnicode_Format");
if (addr) { //PyUnicode_FromString=(PyUnicode_FromString_t)GetProcAddress(module, "PyUnicode_FromString");
HookParam hp;
PyUnicode_FromString=(PyUnicode_FromString_t)GetProcAddress(module, "PyUnicode_FromString");
PyUnicode_FromKindAndData=(PyUnicode_FromKindAndData_t)GetProcAddress(module, "PyUnicode_FromKindAndData"); PyUnicode_FromKindAndData=(PyUnicode_FromKindAndData_t)GetProcAddress(module, "PyUnicode_FromKindAndData");
if(!addr)return false;
HookParam hp;
hp.address = addr; hp.address = addr;
hp.type=NO_CONTEXT|USING_STRING;
hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len)
{
auto fmtstr=(PyObject *)stack->rcx;
DoReadPyString(fmtstr,hp,data,len);
};
if(PyUnicode_FromKindAndData) if(PyUnicode_FromKindAndData)
{ {
hp.type=EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_CODEC_UTF16; hp.type|=EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_CODEC_UTF16;
hp.hook_after=[](hook_stack* stack,void* data, size_t len) hp.hook_after=[](hook_stack* stack,void* data, size_t len)
{ {
auto format=(PyObject *)stack->rcx; auto format=(PyObject *)stack->rcx;
@ -147,72 +187,12 @@ bool InsertRenpy3Hook()
return; return;
stack->rcx=(uintptr_t)PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND,data,len/2); stack->rcx=(uintptr_t)PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND,data,len/2);
}; };
hookrenpy(module);
}; };
hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len) return NewHook(hp, "python3");
{ }();
auto format=(PyObject *)stack->rcx;
if (format == NULL ) auto f2=hookrenpy(module);
return ; return f1||f2;
auto fmtstr=format;
auto fmtdata = PyUnicode_DATA(fmtstr);
auto fmtkind = PyUnicode_KIND(fmtstr);
auto fmtcnt = PyUnicode_GET_LENGTH(fmtstr);
for(auto i=0;i<fmtcnt;i++){
if(PyUnicode_READ(fmtkind,fmtdata,i)=='%')
return;
}
*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;
*len=fmtcnt*sizeof(Py_UCS2);
break;
case PyUnicode_1BYTE_KIND:
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;
*len=fmtcnt*sizeof(Py_UCS4);
}
};
succ|=NewHook(hp, "python3");
}
#if 0
addr = (uintptr_t)GetProcAddress(module, "PyUnicode_FromWideChar");
if (addr) {
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::rcx);
hp.type = USING_STRING | CODEC_UTF16 | NO_CONTEXT;
succ|=NewHook(hp, "python3");
}
addr = (uintptr_t)GetProcAddress(module, "PyUnicode_FromFormatV"); //ansi
if (addr) {
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::rcx);
hp.type = USING_STRING | NO_CONTEXT;
succ|=NewHook(hp, "python3");
}
addr = (uintptr_t)GetProcAddress(module, "PyUnicode_FromFormat");
if (addr) {
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::rcx);
hp.type = USING_STRING | NO_CONTEXT;
succ|=NewHook(hp, "python3");
}
#endif
return succ;
} }
} }
} }

View File

@ -24,8 +24,6 @@ namespace
TextHook(*hooks)[MAX_HOOK]; TextHook(*hooks)[MAX_HOOK];
int currentHook = 0; int currentHook = 0;
} }
bool DetourAttachedUserAddr=false;
bool hostconnected=false;
DWORD WINAPI Pipe(LPVOID) DWORD WINAPI Pipe(LPVOID)
{ {
for (bool running = true; running; hookPipe = INVALID_HANDLE_VALUE) for (bool running = true; running; hookPipe = INVALID_HANDLE_VALUE)
@ -50,7 +48,7 @@ DWORD WINAPI Pipe(LPVOID)
ConsoleOutput(PIPE_CONNECTED); ConsoleOutput(PIPE_CONNECTED);
Hijack(); Hijack();
hostconnected=true; host_connected=true;
while (running && ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE, &count, nullptr)) while (running && ReadFile(hostPipe, buffer, PIPE_BUFFER_SIZE, &count, nullptr))
switch (*(HostCommandType*)buffer) switch (*(HostCommandType*)buffer)
{ {
@ -82,8 +80,8 @@ DWORD WINAPI Pipe(LPVOID)
} }
} }
if(DetourAttachedUserAddr){ if(dont_detach){
hostconnected=false; host_connected=false;
return Pipe(0); return Pipe(0);
}else{ }else{

View File

@ -28,4 +28,8 @@ void context_set(hook_stack*,PCONTEXT);
inline std::map<uintptr_t,std::pair<std::string,HookParam>>delayinserthook; inline std::map<uintptr_t,std::pair<std::string,HookParam>>delayinserthook;
void delayinsertadd(HookParam,std::string); void delayinsertadd(HookParam,std::string);
void delayinsertNewHook(uintptr_t); void delayinsertNewHook(uintptr_t);
inline bool dont_detach=false;
inline bool host_connected=false;

View File

@ -87,7 +87,7 @@ inline uintptr_t regof(regs reg,hook_stack* stack){
#define ARG1 stack[1] #define ARG1 stack[1]
#define ARG2 stack[2] #define ARG2 stack[2]
#define ARG3 stack[3] #define ARG3 stack[3]
#define RETADDR eax #define LASTRETVAL eax
#define THISCALL __thiscall #define THISCALL __thiscall
#define THISCALLTHIS ecx #define THISCALLTHIS ecx
#define THISCALLARG1 stack[1] #define THISCALLARG1 stack[1]
@ -99,7 +99,7 @@ inline uintptr_t regof(regs reg,hook_stack* stack){
#define ARG1 rcx #define ARG1 rcx
#define ARG2 rdx #define ARG2 rdx
#define ARG3 r8 #define ARG3 r8
#define RETADDR rax #define LASTRETVAL rax
#define THISCALLTHIS rcx #define THISCALLTHIS rcx
#define THISCALLARG1 rdx #define THISCALLARG1 rdx
#define THISCALL #define THISCALL