This commit is contained in:
恍兮惚兮 2024-12-14 14:21:41 +08:00
parent 927be11ee9
commit 1769bde333
3 changed files with 78 additions and 74 deletions

View File

@ -1,6 +1,5 @@
#include "VanillawareGC.h" #include "VanillawareGC.h"
/** jichi 7/20/2014 Vanillaware /** jichi 7/20/2014 Vanillaware
* Tested game: * Tested game:
* *
@ -101,21 +100,23 @@
* 16094306 ^e9 91f8ffff jmp 16093b9c * 16094306 ^e9 91f8ffff jmp 16093b9c
* 1609430b cc int3 * 1609430b cc int3
*/ */
namespace { // unnamed namespace
{ // unnamed
// Return true if the text is a garbage character // Return true if the text is a garbage character
inline bool _vanillawaregarbage_ch(char c) inline bool _vanillawaregarbage_ch(char c)
{ {
return c == ' ' || c == '.' || c == '/' return c == ' ' || c == '.' || c == '/' || c >= '0' && c <= '9' || c >= 'A' && c <= 'z' // also ignore ASCII 91-96: [ \ ] ^ _ `
|| c >= '0' && c <= '9'
|| c >= 'A' && c <= 'z' // also ignore ASCII 91-96: [ \ ] ^ _ `
; ;
} }
// Return true if the text is full of garbage characters // Return true if the text is full of garbage characters
bool _vanillawaregarbage(LPCSTR p) bool _vanillawaregarbage(LPCSTR p)
{ {
enum { MAX_LENGTH = VNR_TEXT_CAPACITY }; enum
{
MAX_LENGTH = VNR_TEXT_CAPACITY
};
for (int count = 0; *p && count < MAX_LENGTH; count++, p++) for (int count = 0; *p && count < MAX_LENGTH; count++, p++)
if (!_vanillawaregarbage_ch(*p)) if (!_vanillawaregarbage_ch(*p))
return false; return false;
@ -128,7 +129,8 @@ static void SpecialGCHookVanillaware(hook_context *context, HookParam *hp, TextB
DWORD eax = context->eax; DWORD eax = context->eax;
LPCSTR text = LPCSTR(eax + hp->user_value); LPCSTR text = LPCSTR(eax + hp->user_value);
static LPCSTR lasttext; static LPCSTR lasttext;
if (lasttext != text && *text && !_vanillawaregarbage(text)) { if (lasttext != text && *text && !_vanillawaregarbage(text))
{
lasttext = text; lasttext = text;
*split = context->ecx; *split = context->ecx;
buffer->from(text); buffer->from(text);
@ -136,6 +138,27 @@ static void SpecialGCHookVanillaware(hook_context *context, HookParam *hp, TextB
} }
} }
// jichi 7/17/2014: Search mapped memory for emulators
ULONG _SafeMatchBytesInMappedMemory(LPCVOID pattern, DWORD patternSize, BYTE wildcard,
ULONG start, ULONG stop, ULONG step)
{
for (ULONG i = start; i < stop; i += step) // + patternSize to avoid overlap
if (ULONG r = SafeFindBytes(pattern, patternSize, i, i + step + patternSize + 1))
return r;
return 0;
}
ULONG SafeMatchBytesInGCMemory(LPCVOID pattern, DWORD patternSize)
{
enum : ULONG
{
start = MemDbg::MappedMemoryStartAddress // 0x01000000
,
stop = MemDbg::MemoryStopAddress // 0x7ffeffff
,
step = start
};
return _SafeMatchBytesInMappedMemory(pattern, patternSize, XX, start, stop, step);
}
bool InsertVanillawareGCHook() bool InsertVanillawareGCHook()
{ {
ConsoleOutput("Vanillaware GC: enter"); ConsoleOutput("Vanillaware GC: enter");
@ -157,14 +180,21 @@ bool InsertVanillawareGCHook()
// 0xc6,05 0cfb6701 02 // 160941d3 c605 0cfb6701 02 mov byte ptr ds:[0x167fb0c],0x2 // 0xc6,05 0cfb6701 02 // 160941d3 c605 0cfb6701 02 mov byte ptr ds:[0x167fb0c],0x2
// 0xeb, 26 // 160941da eb 26 jmp short 16094202 // 0xeb, 26 // 160941da eb 26 jmp short 16094202
}; };
enum { memory_offset = 3 }; // 160941a0 0fb680 00000810 movzx eax,byte ptr ds:[eax+0x10080000] enum
enum { addr_offset = 0x160941a0 - 0x16094193 }; {
memory_offset = 3
}; // 160941a0 0fb680 00000810 movzx eax,byte ptr ds:[eax+0x10080000]
enum
{
addr_offset = 0x160941a0 - 0x16094193
};
DWORD addr = SafeMatchBytesInGCMemory(bytes, sizeof(bytes)); DWORD addr = SafeMatchBytesInGCMemory(bytes, sizeof(bytes));
auto succ = false; auto succ = false;
if (!addr) if (!addr)
ConsoleOutput("Vanillaware GC: pattern not found"); ConsoleOutput("Vanillaware GC: pattern not found");
else { else
{
HookParam hp; HookParam hp;
hp.address = addr + addr_offset; hp.address = addr + addr_offset;
hp.user_value = *(DWORD *)(hp.address + memory_offset); hp.user_value = *(DWORD *)(hp.address + memory_offset);
@ -187,6 +217,7 @@ bool InsertGCHooks()
// return false; // return false;
} }
bool VanillawareGC::attach_function() { bool VanillawareGC::attach_function()
{
return InsertGCHooks(); return InsertGCHooks();
} }

View File

@ -392,30 +392,6 @@ uintptr_t SafeFindBytes(LPCVOID pattern, size_t patternSize, uintptr_t lowerBoun
} }
return r; return r;
} }
#ifndef _WIN64
// jichi 7/17/2014: Search mapped memory for emulators
ULONG _SafeMatchBytesInMappedMemory(LPCVOID pattern, DWORD patternSize, BYTE wildcard,
ULONG start, ULONG stop, ULONG step)
{
for (ULONG i = start; i < stop; i += step) // + patternSize to avoid overlap
if (ULONG r = SafeFindBytes(pattern, patternSize, i, i + step + patternSize + 1))
return r;
return 0;
}
ULONG SafeMatchBytesInGCMemory(LPCVOID pattern, DWORD patternSize)
{
enum : ULONG
{
start = MemDbg::MappedMemoryStartAddress // 0x01000000
,
stop = MemDbg::MemoryStopAddress // 0x7ffeffff
,
step = start
};
return _SafeMatchBytesInMappedMemory(pattern, patternSize, XX, start, stop, step);
}
#endif
#ifndef _WIN64 #ifndef _WIN64

View File

@ -55,9 +55,6 @@ uintptr_t SafeFindEnclosingAlignedFunction(uintptr_t addr, uintptr_t range);
uintptr_t SafeFindBytes(LPCVOID pattern, size_t patternSize, uintptr_t lowerBound, uintptr_t upperBound); uintptr_t SafeFindBytes(LPCVOID pattern, size_t patternSize, uintptr_t lowerBound, uintptr_t upperBound);
#ifndef _WIN64 #ifndef _WIN64
ULONG _SafeMatchBytesInMappedMemory(LPCVOID pattern, DWORD patternSize, BYTE wildcard,
ULONG start, ULONG stop, ULONG step);
ULONG SafeMatchBytesInGCMemory(LPCVOID pattern, DWORD patternSize);
std::vector<DWORD> findrelativecall(const BYTE *pattern, int length, DWORD calladdress, DWORD start, DWORD end); std::vector<DWORD> findrelativecall(const BYTE *pattern, int length, DWORD calladdress, DWORD start, DWORD end);
uintptr_t finddllfunctioncall(uintptr_t funcptr, uintptr_t start, uintptr_t end, WORD sig = 0x15ff, bool reverse = false); uintptr_t finddllfunctioncall(uintptr_t funcptr, uintptr_t start, uintptr_t end, WORD sig = 0x15ff, bool reverse = false);