mirror of
https://github.com/HIllya51/LunaHook.git
synced 2025-01-11 20:39:34 +08:00
ppsspp
Update PPSSPP.cpp
This commit is contained in:
parent
45e584d8dd
commit
ca0087a563
@ -1,13 +1,12 @@
|
||||
#include"PPSSPP.h"
|
||||
|
||||
#include<queue>
|
||||
/** Artikash 6/7/2019
|
||||
* PPSSPP JIT code has pointers, but they are all added to an offset before being used.
|
||||
Find that offset so that hook searching works properly.
|
||||
To find the offset, find a page of mapped memory with size 0x1f00000, read and write permissions, take its address and subtract 0x8000000.
|
||||
The above is useful for emulating PSP hardware, so unlikely to change between versions.
|
||||
*/
|
||||
bool PPSSPP::attach_function()
|
||||
{
|
||||
bool PPSSPPinithooksearch(){
|
||||
bool found = false;
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetNativeSystemInfo(&systemInfo);
|
||||
@ -41,4 +40,208 @@ bool PPSSPP::attach_function()
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
namespace{
|
||||
uintptr_t getDoJitAddress() {
|
||||
auto DoJitSig1 = "C7 83 ?? 0? 00 00 11 00 00 00 F6 83 ?? 0? 00 00 01 C7 83 ?? 0? 00 00 E4 00 00 00";
|
||||
auto first=find_pattern(DoJitSig1,processStartAddress,processStopAddress);
|
||||
if (first) {
|
||||
auto beginSubSig1 = "55 41 ?? 41 ?? 41";
|
||||
auto lookbackSize = 0x400;
|
||||
auto address=first-lookbackSize;
|
||||
auto subs=find_pattern(beginSubSig1,address,address+lookbackSize);
|
||||
if(subs){
|
||||
return subs;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
template<class T>
|
||||
class lockedqueue{
|
||||
std::mutex lock;
|
||||
std::queue<T>data;
|
||||
HANDLE hsema;
|
||||
public:
|
||||
lockedqueue(){
|
||||
hsema=CreateSemaphore(NULL,0,65535,NULL);
|
||||
}
|
||||
~lockedqueue(){
|
||||
CloseHandle(hsema);
|
||||
}
|
||||
void push(T&& _){
|
||||
std::lock_guard _l(lock);
|
||||
data.push(std::move(_));
|
||||
ReleaseSemaphore(hsema,1,NULL);
|
||||
}
|
||||
T 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();
|
||||
}
|
||||
};
|
||||
class emu_arg{
|
||||
hook_stack* stack;
|
||||
public:
|
||||
emu_arg(hook_stack* stack_):stack(stack_){};
|
||||
uintptr_t operator [](int idx){
|
||||
auto base=stack->rbx;
|
||||
auto args=stack->r14;
|
||||
auto offR = -0x80;
|
||||
auto offset = offR + 0x10 + idx * 4;
|
||||
return base+*(uint32_t*)(args+offset);
|
||||
}
|
||||
};
|
||||
struct emfuncinfo{
|
||||
const char* hookname;
|
||||
void* hookfunc;
|
||||
const wchar_t* _id;
|
||||
};
|
||||
std::unordered_map<uintptr_t,emfuncinfo>emfunctionhooks;
|
||||
|
||||
}
|
||||
bool hookPPSSPPDoJit(){
|
||||
ConsoleOutput("[Compatibility]");
|
||||
ConsoleOutput("PPSSPP 1.12.3-867 -> v1.16.1-35");
|
||||
ConsoleOutput("[Mirror] Download: https://github.com/koukdw/emulators/releases");
|
||||
auto DoJitPtr=getDoJitAddress();
|
||||
if(DoJitPtr==0)return false;
|
||||
HookParam hp;
|
||||
hp.address=DoJitPtr;//Jit::DoJit
|
||||
ConsoleOutput("DoJitPtr %p",DoJitPtr);
|
||||
|
||||
static lockedqueue<std::pair<uintptr_t,emfuncinfo>> message;
|
||||
|
||||
hp.text_fun=[](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
|
||||
auto em_address=stack->ARG2;
|
||||
if(emfunctionhooks.find(em_address)==emfunctionhooks.end())return;
|
||||
auto op=emfunctionhooks.at(em_address);
|
||||
auto GetCodePtr=(*(__int64 (__fastcall **)(__int64))(*(uintptr_t *)stack->THISCALLTHIS + 8LL))(stack->THISCALLTHIS);
|
||||
GetCodePtr+=0x12;
|
||||
message.push({GetCodePtr,op});
|
||||
HookParam hpinternal;
|
||||
hpinternal.address=stack->retaddr;
|
||||
hpinternal.text_fun=[](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
|
||||
hp->text_fun=nullptr;hp->type=HOOK_EMPTY;
|
||||
auto [GetCodePtr,op]=message.pop();
|
||||
ConsoleOutput("%p",GetCodePtr);
|
||||
DWORD _;
|
||||
VirtualProtect((LPVOID)GetCodePtr,0x10,PAGE_EXECUTE_READWRITE,&_);
|
||||
HookParam hpinternal;
|
||||
hpinternal.address=GetCodePtr;
|
||||
hpinternal.type=CODEC_UTF16|USING_STRING|NO_CONTEXT;
|
||||
hpinternal.text_fun=(decltype(hpinternal.text_fun))op.hookfunc;
|
||||
NewHook(hpinternal,op.hookname);
|
||||
};
|
||||
NewHook(hpinternal,"doonce");//必须退出Dojit再newhook,否则无效,原因不明。
|
||||
};
|
||||
|
||||
return NewHook(hp,"PPSSPPDoJit");
|
||||
}
|
||||
|
||||
bool PPSSPP::attach_function()
|
||||
{
|
||||
return PPSSPPinithooksearch()| hookPPSSPPDoJit();
|
||||
}
|
||||
|
||||
// ==UserScript==
|
||||
// @name [ULJS00403] Shinigami to Shoujo
|
||||
// @version 0.1
|
||||
// @author [DC]
|
||||
// @description PPSSPP x64
|
||||
// * TAKUYO
|
||||
// * TAKUYO
|
||||
// *
|
||||
void ULJS00403(hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
|
||||
hp->type=USING_STRING|NO_CONTEXT;
|
||||
hp->codepage=932;
|
||||
auto address= emu_arg(stack)[1];
|
||||
*data=address;
|
||||
*len=strlen((char*)address);
|
||||
}
|
||||
|
||||
// ==UserScript==
|
||||
// @name [ULJS00339] Amagami
|
||||
// @version v1.02
|
||||
// @author [DC]
|
||||
// @description
|
||||
// * Kadokawa
|
||||
// * K2X_Script
|
||||
void ULJS00339(hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
|
||||
hp->type=USING_STRING|NO_CONTEXT;
|
||||
hp->codepage=932;
|
||||
auto base=stack->rbx;
|
||||
auto a2= emu_arg(stack)[0];
|
||||
|
||||
auto vm = *(DWORD*)(a2+(0x28));
|
||||
vm=*(DWORD*)(vm+base);
|
||||
vm=*(DWORD*)(vm+base+8);
|
||||
auto address=vm+base;
|
||||
auto len1=*(DWORD*)(address+4);
|
||||
auto p=address+0x20;
|
||||
if(len1>4 && *(WORD*)(p+2)==0){
|
||||
auto p1=*(DWORD*)(address+8);
|
||||
vm=*(DWORD*)(vm+base);
|
||||
vm=*(DWORD*)(vm+base+0xC);
|
||||
p=vm+base;
|
||||
}
|
||||
static int fm=0;
|
||||
static std::string pre;
|
||||
auto b=fm;
|
||||
auto s=[](uintptr_t address){
|
||||
auto frist = *(WORD*)address;
|
||||
auto lo = frist & 0xFF; // uppercase: 41->5A
|
||||
auto hi = frist >> 8;
|
||||
if (hi == 0 && (lo > 0x5a || lo < 0x41) /* T,W,? */) {
|
||||
return std::string();
|
||||
}
|
||||
std::string s ;int i = 0;WORD c;
|
||||
char buf[3]={0};
|
||||
while ((c = *(WORD*)(address+i)) != 0) {
|
||||
// reverse endian: ShiftJIS BE => LE
|
||||
buf[0] = c >> 8;
|
||||
buf[1] = c & 0xFF;
|
||||
|
||||
if (c == 0x815e /* / */) {
|
||||
s += ' '; // single line
|
||||
}
|
||||
else if (buf[0] == 0) {
|
||||
//// UTF16 LE turned BE: 5700=>0057, 3100, 3500
|
||||
//// 4e00 6d00=>PLAYER
|
||||
// do nothing
|
||||
if (buf[1] == 0x4e) {
|
||||
s += "PLAYER";
|
||||
fm++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
s+=buf;
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
return s;
|
||||
}(p);
|
||||
if(b>0){
|
||||
fm--;
|
||||
return;
|
||||
}
|
||||
if(s==pre)return ;
|
||||
pre=s;
|
||||
write_string_new(data,len,s);
|
||||
}
|
||||
|
||||
|
||||
namespace{
|
||||
auto _=[](){
|
||||
emfunctionhooks={
|
||||
{0x883bf34,{"Shinigami to Shoujo",ULJS00403,L"PCSG01282"}},
|
||||
{0x0886775c,{"Amagami",ULJS00339,L"ULJS00339"}},
|
||||
};
|
||||
return 1;
|
||||
}();
|
||||
}
|
@ -89,12 +89,16 @@ std::unordered_map<uintptr_t,emfuncinfo>emfunctionhooks;
|
||||
}
|
||||
bool yuzusuyu::attach_function()
|
||||
{
|
||||
|
||||
ConsoleOutput("[Compatibility]");
|
||||
ConsoleOutput("Yuzu 1616+");
|
||||
ConsoleOutput("[Mirror] Download: https://github.com/koukdw/emulators/releases");
|
||||
auto DoJitPtr=getDoJitAddress();
|
||||
if(DoJitPtr==0)return false;
|
||||
ConsoleOutput("DoJitPtr %p",DoJitPtr);
|
||||
HookParam hp;
|
||||
hp.address=DoJitPtr;
|
||||
hp.text_fun=[](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
|
||||
//hp->text_fun=nullptr;hp->type=HOOK_EMPTY;
|
||||
auto descriptor = *argidx(stack,idxDescriptor); // r8
|
||||
auto entrypoint = *argidx(stack,idxEntrypoint); // r9
|
||||
auto em_address = *(uintptr_t*)descriptor;
|
||||
@ -103,7 +107,6 @@ bool yuzusuyu::attach_function()
|
||||
|
||||
auto op=emfunctionhooks.at(em_address);
|
||||
|
||||
|
||||
DWORD _;
|
||||
VirtualProtect((LPVOID)entrypoint,0x10,PAGE_EXECUTE_READWRITE,&_);
|
||||
HookParam hpinternal;
|
||||
@ -126,10 +129,12 @@ void _0100978013276000(hook_stack* stack, HookParam* hp, uintptr_t* data, uintpt
|
||||
auto s=mages::readString(emu_arg(stack)[0],0);
|
||||
write_string_new(data,len,s);
|
||||
}
|
||||
namespace{
|
||||
auto _=[](){
|
||||
emfunctionhooks={
|
||||
{0x8003eeac - 0x80004000,{"Memories Off",_0100978013276000,L"0100978013276000",L"1.0.0"}},
|
||||
{0x8003eebc - 0x80004000,{"Memories Off",_0100978013276000,L"0100978013276000",L"1.0.1"}},
|
||||
};
|
||||
return 1;
|
||||
}();
|
||||
}();
|
||||
}
|
@ -21,7 +21,6 @@ std::vector<ENGINE*> unsafe_check_atlast(){ return{ }; }
|
||||
|
||||
std::vector<ENGINE*> check_engines(){
|
||||
return {
|
||||
new PPSSPP,
|
||||
new Godot,
|
||||
new V8,
|
||||
new Renpy,
|
||||
@ -38,7 +37,8 @@ std::vector<ENGINE*> check_engines(){
|
||||
new _5pb,
|
||||
new TYPEMOON,
|
||||
new ENTERGRAM,
|
||||
new yuzusuyu
|
||||
new yuzusuyu,
|
||||
new PPSSPP,
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user