mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-11-23 13:55:36 +08:00
rpcs3
1 rpcs3
This commit is contained in:
parent
a543d45a6f
commit
e666cb0e1b
@ -1,6 +1,6 @@
|
|||||||
include_directories(. util engines)
|
include_directories(. util engines)
|
||||||
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
|
||||||
set(enginessrc vita3k yuzusuyu TYPEMOON ENTERGRAM AGES7 mono Godot Renpy 5pb lucasystem LightVN V8 pchooks Artemis KiriKiri YOX PPSSPP CMVS Suika2 )
|
set(enginessrc vita3k rpcs3 yuzusuyu TYPEMOON ENTERGRAM AGES7 mono Godot Renpy 5pb lucasystem LightVN V8 pchooks Artemis KiriKiri YOX PPSSPP CMVS Suika2 )
|
||||||
set(enginepath "engine64")
|
set(enginepath "engine64")
|
||||||
set(collector "enginecollection64.cpp")
|
set(collector "enginecollection64.cpp")
|
||||||
else()
|
else()
|
||||||
|
268
LunaHook/engine64/rpcs3.cpp
Normal file
268
LunaHook/engine64/rpcs3.cpp
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
#include"rpcs3.h"
|
||||||
|
#include"engines/emujitarg.hpp"
|
||||||
|
namespace{
|
||||||
|
#if 0 //only support0.0.20-0.0.27
|
||||||
|
int emoffset;
|
||||||
|
int jitoffset;
|
||||||
|
uintptr_t getDoJitAddress_() {
|
||||||
|
auto installFunctionPatt1 = "0F8? ???????? 488D?? ?00?0000 E8 ???????? 4?83C? 68"; // MSVC
|
||||||
|
auto DoJitMatch = find_pattern(installFunctionPatt1,processStartAddress,processStopAddress);
|
||||||
|
if(DoJitMatch)return DoJitMatch;
|
||||||
|
|
||||||
|
auto installFunctionPatt2 = "660F 1F440000 488D?? ?00?0000 E8 ???????? 4?83C? 68"; // patched
|
||||||
|
DoJitMatch = find_pattern(installFunctionPatt2,processStartAddress,processStopAddress);
|
||||||
|
if(DoJitMatch)return DoJitMatch;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
uintptr_t getDoJitAddress() {
|
||||||
|
auto DoJitPtr=getDoJitAddress_();
|
||||||
|
|
||||||
|
ConsoleOutput("DoJitPtr %p",DoJitPtr);
|
||||||
|
if(!DoJitPtr)return 0;
|
||||||
|
//<--DoJitPtr
|
||||||
|
//0f85 1b050000 // jbe 0x00 ; long jump
|
||||||
|
//48 8d 8d 40020000 // lea r?x, ss:[rbp+0x1?0]
|
||||||
|
//e8 cc39acff //call
|
||||||
|
//48 83 c3 68 // add r?x, 0x68
|
||||||
|
auto checkaddr=DoJitPtr+0x6+7+5;
|
||||||
|
switch (*(BYTE*)checkaddr)
|
||||||
|
{
|
||||||
|
case 0x48:{
|
||||||
|
switch(*(BYTE*)(checkaddr+2)){
|
||||||
|
case 0xc0:emoffset=get_reg(regs::rax);break;
|
||||||
|
case 0xc3:emoffset=get_reg(regs::rbx);break;
|
||||||
|
case 0xc1:emoffset=get_reg(regs::rcx);break;
|
||||||
|
case 0xc2:emoffset=get_reg(regs::rdx);break;
|
||||||
|
case 0xc4:emoffset=get_reg(regs::rsp);break;
|
||||||
|
case 0xc5:emoffset=get_reg(regs::rbp);break;
|
||||||
|
case 0xc6:emoffset=get_reg(regs::rsi);break;
|
||||||
|
case 0xc7:emoffset=get_reg(regs::rdi);break;
|
||||||
|
default:emoffset=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x49:{
|
||||||
|
switch(*(BYTE*)(checkaddr+2)){
|
||||||
|
case 0xc0:emoffset=get_reg(regs::r8);break;
|
||||||
|
case 0xc1:emoffset=get_reg(regs::r9);break;
|
||||||
|
case 0xc2:emoffset=get_reg(regs::r10);break;
|
||||||
|
case 0xc3:emoffset=get_reg(regs::r11);break;
|
||||||
|
case 0xc4:emoffset=get_reg(regs::r12);break;
|
||||||
|
case 0xc5:emoffset=get_reg(regs::r13);break;
|
||||||
|
case 0xc6:emoffset=get_reg(regs::r14);break;
|
||||||
|
case 0xc7:emoffset=get_reg(regs::r15);break;
|
||||||
|
default:emoffset=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:emoffset=0;
|
||||||
|
}
|
||||||
|
ConsoleOutput("emoffset %d",emoffset);
|
||||||
|
if(emoffset==0)return 0;
|
||||||
|
|
||||||
|
auto isPPUDebugIfPtr = find_pattern("84C0 ???? 8B",DoJitPtr-0x40,DoJitPtr); // je
|
||||||
|
//84 c0 //test al,al
|
||||||
|
//74 21 //je
|
||||||
|
//8b 0b //mov ecx[rbx]
|
||||||
|
//48 8b 05 XX4 // mov rax[]
|
||||||
|
//4c 8d 34 48 //lea r14,[rax+rcx*2]
|
||||||
|
if(isPPUDebugIfPtr==0)return 0;
|
||||||
|
|
||||||
|
checkaddr= isPPUDebugIfPtr+2+2+2+7;
|
||||||
|
switch (*(BYTE*)checkaddr)
|
||||||
|
{
|
||||||
|
case 0x48:{
|
||||||
|
switch(*(BYTE*)(checkaddr+2)){
|
||||||
|
case 0x14:jitoffset=get_reg(regs::rdx);break;
|
||||||
|
case 0x04:jitoffset=get_reg(regs::rax);break;
|
||||||
|
case 0x1c:jitoffset=get_reg(regs::rbx);break;
|
||||||
|
case 0x0c:jitoffset=get_reg(regs::rcx);break;
|
||||||
|
case 0x24:jitoffset=get_reg(regs::rsp);break;
|
||||||
|
case 0x2c:jitoffset=get_reg(regs::rbp);break;
|
||||||
|
case 0x34:jitoffset=get_reg(regs::rsi);break;
|
||||||
|
case 0x3c:jitoffset=get_reg(regs::rdi);break;
|
||||||
|
default:jitoffset=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x4c:{
|
||||||
|
switch(*(BYTE*)(checkaddr+2)){
|
||||||
|
case 0x04:jitoffset=get_reg(regs::r8);break;
|
||||||
|
case 0x0c:jitoffset=get_reg(regs::r9);break;
|
||||||
|
case 0x14:jitoffset=get_reg(regs::r10);break;
|
||||||
|
case 0x1c:jitoffset=get_reg(regs::r11);break;
|
||||||
|
case 0x24:jitoffset=get_reg(regs::r12);break;
|
||||||
|
case 0x2c:jitoffset=get_reg(regs::r13);break;
|
||||||
|
case 0x34:jitoffset=get_reg(regs::r14);break;
|
||||||
|
case 0x3c:jitoffset=get_reg(regs::r15);break;
|
||||||
|
default:jitoffset=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:jitoffset=0;
|
||||||
|
}
|
||||||
|
ConsoleOutput("jitoffset %d",jitoffset);
|
||||||
|
if(jitoffset==0)return 0;
|
||||||
|
|
||||||
|
DWORD _;
|
||||||
|
BYTE bs1[]={0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00};
|
||||||
|
VirtualProtect((void*)DoJitPtr,sizeof(bs1),PAGE_EXECUTE_READWRITE,&_);
|
||||||
|
memcpy((void*)DoJitPtr,bs1,sizeof(bs1));
|
||||||
|
BYTE bs2[]={0x66, 0x90};
|
||||||
|
VirtualProtect((void*)(isPPUDebugIfPtr+2),sizeof(bs2),PAGE_EXECUTE_READWRITE,&_);
|
||||||
|
memcpy((void*)(isPPUDebugIfPtr+2),bs2,sizeof(bs2));
|
||||||
|
|
||||||
|
return DoJitPtr+6;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uintptr_t getDoJitAddress() {
|
||||||
|
//rpcs3/Emu/Cell/PPUThread.cpp
|
||||||
|
/*
|
||||||
|
extern void ppu_register_function_at(u32 addr, u32 size, ppu_intrp_func_t ptr = nullptr)
|
||||||
|
{
|
||||||
|
// Initialize specific function
|
||||||
|
if (ptr)
|
||||||
|
{
|
||||||
|
ppu_ref(addr) = reinterpret_cast<ppu_intrp_func_t>((reinterpret_cast<uptr>(ptr) & 0xffff'ffff'ffffu) | (uptr(ppu_ref(addr)) & ~0xffff'ffff'ffffu));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!size)
|
||||||
|
{
|
||||||
|
if (g_cfg.core.ppu_debug)
|
||||||
|
{
|
||||||
|
ppu_log.error("ppu_register_function_at(0x%x): empty range", addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
……
|
||||||
|
*/
|
||||||
|
char log[]="ppu_register_function_at(0x%x): empty range";
|
||||||
|
auto logstrptr=MemDbg::findBytes(log,sizeof(log),processStartAddress,processStopAddress);
|
||||||
|
ConsoleOutput("%p",logstrptr);
|
||||||
|
if(logstrptr==0)return 0;
|
||||||
|
auto addr=MemDbg::findleaaddr(logstrptr, processStartAddress, processStopAddress);
|
||||||
|
ConsoleOutput("%p",addr);
|
||||||
|
if(addr==0)return 0;
|
||||||
|
//ff cc cc cc,find不到。。
|
||||||
|
BYTE start[]={XX,0xCC,0xCC,0xCC};
|
||||||
|
addr=reverseFindBytes(start,sizeof(start),addr-0x200,addr,4,true);
|
||||||
|
ConsoleOutput("%p",addr);
|
||||||
|
return addr;
|
||||||
|
|
||||||
|
}
|
||||||
|
struct emfuncinfo{
|
||||||
|
uint64_t type;
|
||||||
|
int argidx;int padding;
|
||||||
|
void* hookfunc;
|
||||||
|
void* filterfun;
|
||||||
|
const char* _id;
|
||||||
|
};
|
||||||
|
std::unordered_map<uintptr_t,emfuncinfo>emfunctionhooks;
|
||||||
|
|
||||||
|
bool checkiscurrentgame(const emfuncinfo& em){
|
||||||
|
auto wininfos=get_proc_windows();
|
||||||
|
for(auto&& info:wininfos){
|
||||||
|
if(info.title.find(acastw(em._id))!=info.title.npos)return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::set<std::pair<uintptr_t,uintptr_t>> timeoutbreaks;
|
||||||
|
|
||||||
|
void dohookemaddr(uintptr_t em_address,uintptr_t ret){
|
||||||
|
jitaddraddr(em_address,ret,JITTYPE::RPCS3);
|
||||||
|
if(emfunctionhooks.find(em_address)==emfunctionhooks.end())return;
|
||||||
|
if(!(checkiscurrentgame(emfunctionhooks.at(em_address))))return;
|
||||||
|
timeoutbreaks.insert(std::make_pair(em_address,ret));
|
||||||
|
auto op=emfunctionhooks.at(em_address);
|
||||||
|
HookParam hpinternal;
|
||||||
|
hpinternal.address=ret;
|
||||||
|
hpinternal.emu_addr=em_address;//用于生成hcode
|
||||||
|
hpinternal.type=USING_STRING|NO_CONTEXT|BREAK_POINT|op.type;
|
||||||
|
hpinternal.text_fun=(decltype(hpinternal.text_fun))op.hookfunc;
|
||||||
|
hpinternal.filter_fun=(decltype(hpinternal.filter_fun))op.filterfun;
|
||||||
|
hpinternal.argidx=op.argidx;
|
||||||
|
hpinternal.padding=op.padding;
|
||||||
|
hpinternal.jittype=JITTYPE::RPCS3;
|
||||||
|
NewHook(hpinternal,op._id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool unsafeinithooks(){
|
||||||
|
//rpcs0.0.30,不知道为什么ppu_register_function_at不全。不过看代码得到映射表了,直接弄吧。
|
||||||
|
//rpcs3/Emu/Cell/PPUThread.cpp
|
||||||
|
// Get pointer to executable cache
|
||||||
|
/*
|
||||||
|
static inline u8* ppu_ptr(u32 addr)
|
||||||
|
{
|
||||||
|
return vm::g_exec_addr + u64{addr} * 2;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
HookParam hp;
|
||||||
|
hp.type=DIRECT_READ;
|
||||||
|
hp.address=0x500000000;
|
||||||
|
hp.text_fun=[](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len)
|
||||||
|
{
|
||||||
|
for(auto [addr,info]:emfunctionhooks){
|
||||||
|
auto table=addr*2+0x500000000;
|
||||||
|
if(IsBadReadPtr((void*)table,sizeof(uintptr_t)))continue;
|
||||||
|
auto funcaddr=*(uintptr_t*)table;
|
||||||
|
funcaddr&=0x0000ffffffffffff;
|
||||||
|
if(!funcaddr)continue;
|
||||||
|
auto p=std::make_pair(addr,funcaddr);
|
||||||
|
if(timeoutbreaks.find(p)!=timeoutbreaks.end())continue;
|
||||||
|
dohookemaddr(addr,funcaddr);
|
||||||
|
delayinsertNewHook(addr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return NewHook(hp,"g_exec_addr");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool rpcs3::attach_function()
|
||||||
|
{
|
||||||
|
ConsoleOutput("[Compatibility] RPCS3");
|
||||||
|
auto DoJitPtr=getDoJitAddress();
|
||||||
|
if(DoJitPtr==0)return false;
|
||||||
|
unsafeinithooks();
|
||||||
|
spDefault.jittype=JITTYPE::RPCS3;
|
||||||
|
spDefault.minAddress = 0;
|
||||||
|
spDefault.maxAddress = -1;
|
||||||
|
HookParam hp;
|
||||||
|
hp.address=DoJitPtr;
|
||||||
|
hp.text_fun=[](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
|
||||||
|
|
||||||
|
auto em_address =stack->rcx;// *(uint32_t*)*(uintptr_t*)(stack->base+emoffset);
|
||||||
|
auto entrypoint=stack->r8;//*(uintptr_t*)*(uintptr_t*)(stack->base+jitoffset)-0x0008000000000000;
|
||||||
|
if(!em_address||!entrypoint)return;
|
||||||
|
dohookemaddr(em_address,entrypoint);
|
||||||
|
delayinsertNewHook(em_address);
|
||||||
|
};
|
||||||
|
return NewHook(hp,"vita3kjit");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace{
|
||||||
|
|
||||||
|
bool FBLJM61131(void* data, size_t* len, HookParam* hp){
|
||||||
|
auto s = std::string((char*)data,*len);
|
||||||
|
std::regex pattern("\\[[^\\]]+.");
|
||||||
|
s = std::regex_replace(s, pattern, "");
|
||||||
|
s = std::regex_replace(s, std::regex("\\\\k|\\\\x|%C|%B"), "");
|
||||||
|
s = std::regex_replace(s, std::regex("\\%\\d+\\#[0-9a-fA-F]*\\;"), "");
|
||||||
|
s = std::regex_replace(s, std::regex("\\n+"), " ");
|
||||||
|
return write_string_overwrite(data,len,s);
|
||||||
|
}
|
||||||
|
auto _=[](){
|
||||||
|
emfunctionhooks={
|
||||||
|
//'&' -Sora no Mukou de Sakimasu you ni-
|
||||||
|
{0x46328,{CODEC_UTF8,1,0,0,FBLJM61131,"BLJM61131"}},
|
||||||
|
//Dunamis15
|
||||||
|
{0x42c90,{CODEC_UTF8,1,0,0,FBLJM61131,"BLJM60347"}},
|
||||||
|
|
||||||
|
};
|
||||||
|
return 1;
|
||||||
|
}();
|
||||||
|
}
|
13
LunaHook/engine64/rpcs3.h
Normal file
13
LunaHook/engine64/rpcs3.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include"engine.h"
|
||||||
|
|
||||||
|
class rpcs3:public ENGINE{
|
||||||
|
public:
|
||||||
|
rpcs3(){
|
||||||
|
|
||||||
|
check_by=CHECK_BY::FILE;
|
||||||
|
is_engine_certain=false;
|
||||||
|
check_by_target=L"rpcs3.exe";
|
||||||
|
};
|
||||||
|
bool attach_function();
|
||||||
|
};
|
||||||
|
|
@ -17,6 +17,7 @@
|
|||||||
#include"engine64/LightVN.h"
|
#include"engine64/LightVN.h"
|
||||||
#include"engine64/yuzusuyu.h"
|
#include"engine64/yuzusuyu.h"
|
||||||
#include"engine64/vita3k.h"
|
#include"engine64/vita3k.h"
|
||||||
|
#include"engine64/rpcs3.h"
|
||||||
std::vector<ENGINE*> ignore_engines(){ return{ }; }
|
std::vector<ENGINE*> ignore_engines(){ return{ }; }
|
||||||
std::vector<ENGINE*> unsafe_check_atlast(){ return{ }; }
|
std::vector<ENGINE*> unsafe_check_atlast(){ return{ }; }
|
||||||
|
|
||||||
@ -40,7 +41,8 @@ std::vector<ENGINE*> check_engines(){
|
|||||||
new ENTERGRAM,
|
new ENTERGRAM,
|
||||||
new yuzusuyu,
|
new yuzusuyu,
|
||||||
new PPSSPP,
|
new PPSSPP,
|
||||||
new vita3k
|
new vita3k,
|
||||||
|
new rpcs3
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
namespace RPCS3
|
||||||
|
{
|
||||||
|
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=(uintptr_t*)(stack->rbp+0x18+8*3);
|
||||||
|
return base+args[idx];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
namespace YUZU
|
namespace YUZU
|
||||||
{
|
{
|
||||||
class emu_arg{
|
class emu_arg{
|
||||||
|
@ -65,22 +65,6 @@ struct PPSSPPFunction
|
|||||||
const char *pattern; // debug string used within the function
|
const char *pattern; // debug string used within the function
|
||||||
};
|
};
|
||||||
|
|
||||||
uint64_t findleaaddr(uint64_t addr,uint64_t start,uint64_t end)
|
|
||||||
{
|
|
||||||
for(auto _addr=start;_addr<end;_addr+=1)
|
|
||||||
{
|
|
||||||
auto lea=(*(WORD*)_addr);
|
|
||||||
if(lea!=0x8d4c&&lea!=0x8d48)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
auto offset=*(DWORD*)(_addr+3);
|
|
||||||
auto refaddr=(offset)+_addr+7;
|
|
||||||
if(refaddr==addr)
|
|
||||||
return _addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InsertPPSSPPHLEHooks()
|
bool InsertPPSSPPHLEHooks()
|
||||||
{
|
{
|
||||||
@ -128,7 +112,7 @@ bool InsertPPSSPPHLEHooks()
|
|||||||
if(!addr)continue;
|
if(!addr)continue;
|
||||||
addr=SafeFindEnclosingAlignedFunction(addr, 0x200);
|
addr=SafeFindEnclosingAlignedFunction(addr, 0x200);
|
||||||
#else
|
#else
|
||||||
addr=findleaaddr(addr, processStartAddress, processStopAddress);
|
addr=MemDbg::findleaaddr(addr, processStartAddress, processStopAddress);
|
||||||
|
|
||||||
if(!addr)continue;
|
if(!addr)continue;
|
||||||
|
|
||||||
|
@ -198,6 +198,9 @@ void SafeSendJitVeh(hook_stack* stack,uintptr_t address,uintptr_t em_addr,JITTYP
|
|||||||
case JITTYPE::VITA3K:
|
case JITTYPE::VITA3K:
|
||||||
str=(char*)VITA3K::emu_arg(stack)[i];
|
str=(char*)VITA3K::emu_arg(stack)[i];
|
||||||
break;
|
break;
|
||||||
|
case JITTYPE::RPCS3:
|
||||||
|
str=(char*)RPCS3::emu_arg(stack)[i];
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case JITTYPE::PPSSPP:
|
case JITTYPE::PPSSPP:
|
||||||
str=(char*)PPSSPP::emu_arg(stack)[i];
|
str=(char*)PPSSPP::emu_arg(stack)[i];
|
||||||
|
@ -149,6 +149,8 @@ uintptr_t jitgetaddr(hook_stack* stack, HookParam* hp){
|
|||||||
switch (hp->jittype)
|
switch (hp->jittype)
|
||||||
{
|
{
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
case JITTYPE::RPCS3:
|
||||||
|
return RPCS3::emu_arg(stack)[hp->argidx];
|
||||||
case JITTYPE::VITA3K:
|
case JITTYPE::VITA3K:
|
||||||
return VITA3K::emu_arg(stack)[hp->argidx];
|
return VITA3K::emu_arg(stack)[hp->argidx];
|
||||||
case JITTYPE::YUZU:
|
case JITTYPE::YUZU:
|
||||||
@ -340,6 +342,13 @@ void TextHook::Read()
|
|||||||
auto pbData = buffer->data;
|
auto pbData = buffer->data;
|
||||||
buffer->type=hp.type;
|
buffer->type=hp.type;
|
||||||
__try
|
__try
|
||||||
|
{
|
||||||
|
if(hp.text_fun)
|
||||||
|
{
|
||||||
|
while (WaitForSingleObject(readerEvent, 500) == WAIT_TIMEOUT)
|
||||||
|
hp.text_fun(0,0,0,0,0);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
while (WaitForSingleObject(readerEvent, 500) == WAIT_TIMEOUT) if (location&&(memcmp(pbData, location, dataLen) != 0)) if (int currentLen = HookStrlen((BYTE*)location))
|
while (WaitForSingleObject(readerEvent, 500) == WAIT_TIMEOUT) if (location&&(memcmp(pbData, location, dataLen) != 0)) if (int currentLen = HookStrlen((BYTE*)location))
|
||||||
{
|
{
|
||||||
@ -350,6 +359,8 @@ void TextHook::Read()
|
|||||||
memcpy(pbData, location, dataLen);
|
memcpy(pbData, location, dataLen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
ConsoleOutput(READ_ERROR, hp.name);
|
ConsoleOutput(READ_ERROR, hp.name);
|
||||||
|
@ -478,6 +478,24 @@ DWORD findEnclosingFunctionAfterInt3(DWORD start, DWORD back_range, DWORD step)
|
|||||||
DWORD findEnclosingFunctionAfterNop(DWORD start, DWORD back_range, DWORD step)
|
DWORD findEnclosingFunctionAfterNop(DWORD start, DWORD back_range, DWORD step)
|
||||||
{ return findEnclosingFunctionAfterDword(0x90909090,start, back_range, step); }
|
{ return findEnclosingFunctionAfterDword(0x90909090,start, back_range, step); }
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
uint64_t findleaaddr(uint64_t addr,uint64_t start,uint64_t end)
|
||||||
|
{
|
||||||
|
for(auto _addr=start;_addr<end;_addr+=1)
|
||||||
|
{
|
||||||
|
auto lea=(*(WORD*)_addr);
|
||||||
|
if(lea!=0x8d4c&&lea!=0x8d48)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto offset=*(DWORD*)(_addr+3);
|
||||||
|
auto refaddr=(offset)+_addr+7;
|
||||||
|
if(refaddr==addr)
|
||||||
|
return _addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uintptr_t findCallerAddress(uintptr_t funcAddr, DWORD sig, uintptr_t lowerBound, uintptr_t upperBound, uintptr_t reverseLength,uintptr_t offset)
|
uintptr_t findCallerAddress(uintptr_t funcAddr, DWORD sig, uintptr_t lowerBound, uintptr_t upperBound, uintptr_t reverseLength,uintptr_t offset)
|
||||||
|
@ -132,6 +132,7 @@ dword_t findPushByteAddress(byte_t value, dword_t lowerBound, dword_t upperBound
|
|||||||
inline dword_t findPushAddress(dword_t value, dword_t lowerBound, dword_t upperBound)
|
inline dword_t findPushAddress(dword_t value, dword_t lowerBound, dword_t upperBound)
|
||||||
{ return findPushDwordAddress(value, lowerBound, upperBound); }
|
{ return findPushDwordAddress(value, lowerBound, upperBound); }
|
||||||
|
|
||||||
|
uint64_t findleaaddr(uint64_t addr,uint64_t start,uint64_t end);
|
||||||
/**
|
/**
|
||||||
* Return the enclosing function address outside the given address.
|
* Return the enclosing function address outside the given address.
|
||||||
* The same as ITH FindEntryAligned().
|
* The same as ITH FindEntryAligned().
|
||||||
|
@ -63,6 +63,8 @@ namespace
|
|||||||
hp.jittype=JITTYPE::PPSSPP;
|
hp.jittype=JITTYPE::PPSSPP;
|
||||||
else if(endWith(HCode,L":JIT:VITA3K"))
|
else if(endWith(HCode,L":JIT:VITA3K"))
|
||||||
hp.jittype=JITTYPE::VITA3K;
|
hp.jittype=JITTYPE::VITA3K;
|
||||||
|
else if(endWith(HCode,L":JIT:RPCS3"))
|
||||||
|
hp.jittype=JITTYPE::RPCS3;
|
||||||
|
|
||||||
// {A|B|W|H|S|Q|V|M}
|
// {A|B|W|H|S|Q|V|M}
|
||||||
switch (HCode[0])
|
switch (HCode[0])
|
||||||
@ -357,6 +359,9 @@ namespace
|
|||||||
case JITTYPE::VITA3K:
|
case JITTYPE::VITA3K:
|
||||||
HCode+=L":JIT:VITA3K";
|
HCode+=L":JIT:VITA3K";
|
||||||
break;
|
break;
|
||||||
|
case JITTYPE::RPCS3:
|
||||||
|
HCode+=L":JIT:RPCS3";
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,8 @@ enum class JITTYPE{
|
|||||||
PC,//not a jit
|
PC,//not a jit
|
||||||
YUZU,
|
YUZU,
|
||||||
PPSSPP,
|
PPSSPP,
|
||||||
VITA3K
|
VITA3K,
|
||||||
|
RPCS3
|
||||||
};
|
};
|
||||||
struct HookParam
|
struct HookParam
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user