This commit is contained in:
恍兮惚兮 2024-12-03 16:26:37 +08:00
parent 60f86ef52b
commit 30258ef809
6 changed files with 181 additions and 110 deletions

View File

@ -5,28 +5,21 @@ namespace
auto idxDescriptor = isVirtual == true ? 2 : 1;
auto idxEntrypoint = idxDescriptor + 1;
std::string Vita3KGameID;
std::atomic<uintptr_t> unindexablehooks_near = 0;
uintptr_t getDoJitAddress()
{
auto RegisterBlockSig1 = "40 55 53 56 57 41 54 41 56 41 57 48 8D 6C 24 E9 48 81 EC 90 00 00 00 48 8B ?? ?? ?? ?? ?? 48 33 C4 48 89 45 07 4D 8B F1 49 8B F0 48 8B FA 48 8B D9 4C 8B 7D 77 48 8B 01 48 8D 55 C7 FF 50 10";
auto first = find_pattern(RegisterBlockSig1, processStartAddress, processStopAddress);
// Vita3K\external\dynarmic\src\dynarmic\backend\x64\emit_x64.h
// BlockDescriptor EmitX64::RegisterBlock(const IR::LocationDescriptor& location_descriptor, CodePtr entrypoint, size_t size);
BYTE RegisterBlockSig1[] = {0x40, 0x55, 0x53, 0x56, 0x57, 0x41, 0x54, 0x41, 0x56, 0x41, 0x57, 0x48, 0x8D, 0x6C, 0x24, 0xE9, 0x48, 0x81, 0xEC, 0x90, 0x00, 0x00, 0x00, 0x48, 0x8B, XX, XX, XX, XX, XX, 0x48, 0x33, 0xC4, 0x48, 0x89, 0x45, 0x07, 0x4D, 0x8B, 0xF1, 0x49, 0x8B, 0xF0, 0x48, 0x8B, 0xFA, 0x48, 0x8B, 0xD9, 0x4C, 0x8B, 0x7D, 0x77, 0x48, 0x8B, 0x01, 0x48, 0x8D, 0x55, 0xC7, 0xFF, 0x50, 0x10};
auto first = MemDbg::findBytes(RegisterBlockSig1, sizeof(RegisterBlockSig1), processStartAddress, processStopAddress);
if (first)
return first;
/*
// DebugSymbol: RegisterBlock
// ?RegisterBlock@EmitX64@X64@Backend@Dynarmic@@IEAA?AUBlockDescriptor@1234@AEBVLocationDescriptor@IR@4@PEBX_K@Z <- new
// ?RegisterBlock@EmitX64@X64@Backend@Dynarmic@@IEAA?AUBlockDescriptor@1234@AEBVLocationDescriptor@IR@4@PEBX1_K@Z
const symbols = DebugSymbol.findFunctionsMatching(
'Dynarmic::Backend::X64::EmitX64::RegisterBlock'
);
if (symbols.length !== 0) {
console.warn('Sym RegisterBlock');
return symbols[0];
}
*/
auto PatchBlockSig1 = "4C 8B DC 49 89 5B 10 49 89 6B 18 56 57 41 54 41 56 41 57";
first = find_pattern(PatchBlockSig1, processStartAddress, processStopAddress);
BYTE PatchBlockSig1[] = {0x4C, 0x8B, 0xDC, 0x49, 0x89, 0x5B, 0x10, 0x49, 0x89, 0x6B, 0x18, 0x56, 0x57, 0x41, 0x54, 0x41, 0x56, 0x41, 0x57};
BYTE PatchBlockSig2[] = {0x4C, 0x8B, 0xDC, 0x49, 0x89, 0x5B, XX, 0x49, 0x89, 0x6B, XX, 0x56, 0x57, 0x41, 0x54, 0x41, 0x56, 0x41, 0x57};
first = MemDbg::findBytes(PatchBlockSig1, sizeof(PatchBlockSig1), processStartAddress, processStopAddress);
if (!first)
first = find_pattern("4C 8B DC 49 89 5B ?? 49 89 6B ?? 56 57 41 54 41 56 41 57", processStartAddress, processStopAddress); // 0.1.9 3339
first = MemDbg::findBytes(PatchBlockSig2, sizeof(PatchBlockSig2), processStartAddress, processStopAddress); // 0.1.9 3339
if (first)
{
idxDescriptor = 1;
@ -45,7 +38,7 @@ namespace
const char *_id;
};
std::unordered_map<uintptr_t, emfuncinfo> emfunctionhooks;
std::unordered_map<std::string, std::function<bool(uintptr_t)>> unindexablehooks;
}
namespace
@ -86,7 +79,28 @@ namespace
return;
Vita3KGameID = wcasta(curr);
last = curr;
return HostInfo(HOSTINFO::EmuGameName, WideStringToString(game).c_str());
HostInfo(HOSTINFO::EmuGameName, WideStringToString(game).c_str());
for (auto &&[id, ptr] : unindexablehooks)
{
if (id == Vita3KGameID)
{
HookParam hp;
static int __fake = 0x10;
hp.address = __fake++;
hp.type = DIRECT_READ;
hp.user_value = (uintptr_t)&ptr;
hp.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
{
auto __ = unindexablehooks_near.load();
if (!__)
return;
if ((*((decltype(ptr) *)hp->user_value))(__))
hp->type |= HOOK_EMPTY;
};
NewHook(hp, (id + " Loader").c_str());
}
}
return;
}
};
hp.type = DIRECT_READ;
@ -109,6 +123,7 @@ bool vita3k::attach_function()
{
auto descriptor = *argidx(stack, idxDescriptor + 1); // r8
auto entrypoint = *argidx(stack, idxEntrypoint + 1); // r9
unindexablehooks_near.store(entrypoint);
auto em_address = *(uint32_t *)descriptor;
if (em_address < 0x80000000)
em_address += 0x80000000; // 0.1.9 3339
@ -504,8 +519,36 @@ namespace
return buffer->clear();
last = s;
}
bool PCSG00397(uintptr_t funcnear)
{
BYTE sig[] = {
0x41, 0x8b, 0x47, 0x10,
0x45, 0x0f, 0xb6, 0x74, 0x05, 0x00,
0x45, 0x0f, 0xbe, 0xf6,
0x45, 0x89, 0x37,
0x31, 0xc0,
0x41, 0x83, 0xfe, 0x00};
for (auto addr : Util::SearchMemory(sig, sizeof(sig), PAGE_EXECUTE_READWRITE, funcnear - 0x1000000, funcnear + 0x1000000))
{
HookParam hp;
hp.address = addr;
hp.type = CODEC_UTF8 | USING_STRING | BREAK_POINT;
hp.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split)
{
buffer->from((char *)VITA3K::emu_arg(stack)[4]);
};
return NewHook(hp, "PCSG00397");
}
return false;
}
auto _ = []()
{
unindexablehooks = {
// ニセコイ ヨメイリ!?
{"PCSG00397", PCSG00397},
};
emfunctionhooks = {
// 追放選挙
{0x8002e176, {0, 0, 0, 0, FPCSG01023, "PCSG01023"}}, // dialogue+name,sjis

View File

@ -63,7 +63,7 @@ struct PPSSPPFunction
const char *pattern; // debug string used within the function
};
namespace
namespace PPSSPP
{
uintptr_t findleapushalignfuncaddr(uintptr_t addr)
{
@ -148,7 +148,7 @@ bool InsertPPSSPPHLEHooks()
auto addr = MemDbg::findBytes(function.pattern, ::strlen(function.pattern), processStartAddress, processStopAddress);
if (!addr)
continue;
addr = findleapushalignfuncaddr(addr);
addr = PPSSPP::findleapushalignfuncaddr(addr);
if (!addr)
continue;
@ -488,7 +488,16 @@ namespace ppsspp
}
return true;
}
void LoadNativeHooks(const std::string &GameID)
{
for (auto &&[id, ptr] : nativehooks)
{
if (id == GameID)
{
ptr();
}
}
}
void Load_PSP_ISO_StringFromFormat()
{
/*
@ -529,6 +538,7 @@ namespace ppsspp
game_info.TITLE = (char *)stack->ARG4;
HostInfo(HOSTINFO::EmuGameName, "%s %s", stack->ARG3, stack->ARG4);
jitaddrclear();
LoadNativeHooks(game_info.DISC_ID);
};
NewHook(hp, "PPSSPPGameInfo");
}
@ -537,10 +547,14 @@ namespace ppsspp
auto wininfos = get_proc_windows();
for (auto &&info : wininfos)
{
if (info.title.find(L'-') != info.title.npos)
{
return HostInfo(HOSTINFO::EmuGameName, WideStringToString(info.title.substr(info.title.find(L'-') + 1)).c_str());
}
if (info.title.find(L'-') == info.title.npos)
continue;
auto title = WideStringToString(info.title.substr(info.title.find(L'-') + 2));
game_info.DISC_ID = title.substr(0, title.find(':') - 1);
game_info.TITLE = title.substr(title.find(':') + 2);
HostInfo(HOSTINFO::EmuGameName, "%s %s", game_info.DISC_ID.c_str(), game_info.TITLE.c_str());
LoadNativeHooks(game_info.DISC_ID);
return;
}
}
bool hookPPSSPPDoJit()
@ -588,90 +602,9 @@ namespace ppsspp
return NewHook(hp, "PPSSPPDoJit");
}
}
namespace
{
// ULJS00035 ULJS00149 流行り神
void *findGetPointer()
{
char GetPointer[] = "Unknown GetPointer %08x PC %08x LR %08x";
auto addr = MemDbg::findBytes(GetPointer, sizeof(GetPointer), processStartAddress, processStopAddress);
if (!addr)
return nullptr;
addr = findleapushalignfuncaddr(addr);
return (void *)addr;
}
bool Replace_memcpy()
{
// static int Replace_memcpy() {
// u32 destPtr = PARAM(0);
// u32 srcPtr = PARAM(1);
// u32 bytes = PARAM(2);
static auto GetPointer = (void *(*)(uintptr_t))findGetPointer();
if (!GetPointer)
return false;
ConsoleOutput("GetPointer %p", GetPointer);
char ReplaceMemcpy_VideoDecodeRange[] = "ReplaceMemcpy/VideoDecodeRange";
auto addr = MemDbg::findBytes(ReplaceMemcpy_VideoDecodeRange, sizeof(ReplaceMemcpy_VideoDecodeRange), processStartAddress, processStopAddress);
if (!addr)
return false;
ConsoleOutput("ReplaceMemcpy/VideoDecodeRange %p", addr);
#ifndef _WIN64
BYTE sig[] = {0xb9, XX4};
*(uintptr_t *)(sig + 1) = addr;
bool succ = false;
for (auto addr : Util::SearchMemory(sig, sizeof(sig), PAGE_EXECUTE, processStartAddress, processStopAddress))
{
BYTE sig1[] = {
0x55, 0x8b, 0xec,
0x81, 0xec, XX4,
0x8b, 0x0d, XX4};
addr = reverseFindBytes(sig1, sizeof(sig1), addr - 0x200, addr);
if (!addr)
continue;
DWORD off_106D180 = *(DWORD *)(addr + sizeof(sig1) - 4);
HookParam hp;
hp.user_value = *(DWORD *)off_106D180;
#else
bool succ = false;
for (auto addr : MemDbg::findleaaddr_all(addr, processStartAddress, processStopAddress))
{
BYTE sig1[] = {
0x48, 0x89, XX, 0x24, 0x18,
0x48, 0x89, XX, 0x24, 0x20,
0x57,
0x48, 0x81, 0xec, XX4,
0x48, 0x8b, XX, XX4};
addr = reverseFindBytes(sig1, sizeof(sig1), addr - 0x200, addr);
if (!addr)
continue;
DWORD off_140F4C810 = *(DWORD *)(addr + sizeof(sig1) - 4);
HookParam hp;
hp.user_value = *(uintptr_t *)(off_140F4C810 + addr + sizeof(sig1));
#endif
hp.address = addr;
hp.text_fun = [](hook_stack *stack, HookParam *hp, auto *buff, auto *split)
{
auto bytes = *((DWORD *)hp->user_value + 6);
auto srcPtr = GetPointer(*((DWORD *)hp->user_value + 5));
if (!IsShiftjisLeadByte(*(BYTE *)srcPtr))
return;
if (bytes != 2)
return;
if (bytes != strnlen((char *)srcPtr, TEXT_BUFFER_SIZE))
return;
buff->from(srcPtr, bytes);
};
succ |= NewHook(hp, "Replace_memcpy");
}
return succ;
}
}
bool InsertPPSSPPcommonhooks()
{
auto succ = ppsspp::hookPPSSPPDoJit();
succ |= InsertPPSSPPHLEHooks();
succ |= Replace_memcpy();
return succ;
}

View File

@ -1,6 +1,86 @@
#include <queue>
#include "emujitarg.hpp"
namespace PPSSPP
{
uintptr_t findleapushalignfuncaddr(uintptr_t addr);
// ULJS00035 ULJS00149 流行り神
void *findGetPointer()
{
char GetPointer[] = "Unknown GetPointer %08x PC %08x LR %08x";
auto addr = MemDbg::findBytes(GetPointer, sizeof(GetPointer), processStartAddress, processStopAddress);
if (!addr)
return nullptr;
addr = findleapushalignfuncaddr(addr);
return (void *)addr;
}
void Replace_memcpy()
{
// static int Replace_memcpy() {
// u32 destPtr = PARAM(0);
// u32 srcPtr = PARAM(1);
// u32 bytes = PARAM(2);
static auto GetPointer = (void *(*)(uintptr_t))findGetPointer();
if (!GetPointer)
return;
ConsoleOutput("GetPointer %p", GetPointer);
char ReplaceMemcpy_VideoDecodeRange[] = "ReplaceMemcpy/VideoDecodeRange";
auto addr = MemDbg::findBytes(ReplaceMemcpy_VideoDecodeRange, sizeof(ReplaceMemcpy_VideoDecodeRange), processStartAddress, processStopAddress);
if (!addr)
return;
ConsoleOutput("ReplaceMemcpy/VideoDecodeRange %p", addr);
#ifndef _WIN64
BYTE sig[] = {0xb9, XX4};
*(uintptr_t *)(sig + 1) = addr;
bool succ = ;
for (auto addr : Util::SearchMemory(sig, sizeof(sig), PAGE_EXECUTE, processStartAddress, processStopAddress))
{
BYTE sig1[] = {
0x55, 0x8b, 0xec,
0x81, 0xec, XX4,
0x8b, 0x0d, XX4};
addr = reverseFindBytes(sig1, sizeof(sig1), addr - 0x200, addr);
if (!addr)
continue;
DWORD off_106D180 = *(DWORD *)(addr + sizeof(sig1) - 4);
HookParam hp;
hp.user_value = *(DWORD *)off_106D180;
#else
for (auto addr : MemDbg::findleaaddr_all(addr, processStartAddress, processStopAddress))
{
BYTE sig1[] = {
0x48, 0x89, XX, 0x24, 0x18,
0x48, 0x89, XX, 0x24, 0x20,
0x57,
0x48, 0x81, 0xec, XX4,
0x48, 0x8b, XX, XX4};
addr = reverseFindBytes(sig1, sizeof(sig1), addr - 0x200, addr);
if (!addr)
continue;
DWORD off_140F4C810 = *(DWORD *)(addr + sizeof(sig1) - 4);
HookParam hp;
hp.user_value = *(uintptr_t *)(off_140F4C810 + addr + sizeof(sig1));
#endif
hp.address = addr;
hp.text_fun = [](hook_stack *stack, HookParam *hp, auto *buff, auto *split)
{
auto bytes = *((DWORD *)hp->user_value + 6);
auto srcPtr = GetPointer(*((DWORD *)hp->user_value + 5));
if (!IsShiftjisLeadByte(*(BYTE *)srcPtr))
return;
if (bytes != 2)
return;
if (bytes != strnlen((char *)srcPtr, TEXT_BUFFER_SIZE))
return;
buff->from(srcPtr, bytes);
};
NewHook(hp, "Replace_memcpy");
}
}
}
namespace ppsspp
{
void ULJS00403_filter(TextBuffer *buffer, HookParam *hp)
@ -710,6 +790,14 @@ namespace ppsspp
return buffer->clear();
}
}
std::unordered_map<std::string, std::function<void()>> nativehooks = {
// 流行り神PORTABLE
{"ULJS00035", PPSSPP::Replace_memcpy},
// 流行り神2PORTABLE
{"ULJS00149", PPSSPP::Replace_memcpy},
// 流行り神3
{"ULJS00204", PPSSPP::Replace_memcpy}, // 乱码太多
};
std::unordered_map<uintptr_t, emfuncinfo> emfunctionhooks = {
// 死神と少女
{0x883bf34, {0, 1, 0, 0, ULJS00403_filter, "ULJS00403"}},

View File

@ -472,6 +472,13 @@ void SearchForHooks(SearchParam spUser)
}
ConsoleOutput("%p %p",minemaddr,maxemaddr);
ConsoleOutput("%p %p",sp.minAddress,sp.maxAddress);
if(0){
auto f=fopen("1.txt","a");
for(auto addr:jitaddr2emuaddr){
fprintf(f,"%llx => %llx\n", addr.second.second ,addr.first);
}
fclose(f);
}
for(auto addr:jitaddr2emuaddr){
//ConsoleOutput("%llx => %p", addr.second.second ,addr.first);
if(addr.second.second>sp.maxAddress||addr.second.second<sp.minAddress)continue;

View File

@ -482,8 +482,8 @@ void TextHook::Read()
{
if (hp.text_fun)
{
while (WaitForSingleObject(readerEvent, 500) == WAIT_TIMEOUT)
hp.text_fun(0, 0, 0, 0);
while ((!(hp.type & HOOK_EMPTY)) && (WaitForSingleObject(readerEvent, 500) == WAIT_TIMEOUT))
hp.text_fun(0, &hp, 0, 0);
}
else
{

View File

@ -1,7 +1,7 @@
set(VERSION_MAJOR 6)
set(VERSION_MINOR 9)
set(VERSION_PATCH 6)
set(VERSION_PATCH 7)
set(VERSION_REVISION 0)
set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}")
add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp)