This commit is contained in:
恍兮惚兮 2024-11-02 15:49:09 +08:00
parent bd62f89e9b
commit edc5efec99
71 changed files with 2135 additions and 2020 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,23 +1,26 @@
class _5pb:public ENGINE{
public:
_5pb(){
is_engine_certain=false;
check_by=CHECK_BY::FILE_ANY;
check_by_target=check_by_list{ L"data\\*.cpk",L"*.cpk",L"*.mpk",L"USRDIR\\*.mpk"};
class _5pb : public ENGINE
{
public:
_5pb()
{
is_engine_certain = false;
check_by = CHECK_BY::FILE_ANY;
check_by_target = check_by_list{L"data\\*.cpk", L"*.cpk", L"*.mpk", L"USRDIR\\*.mpk"};
};
bool attach_function();
bool attach_function();
};
class _5pb_2:public ENGINE{
public:
_5pb_2(){
check_by=CHECK_BY::FILE;
check_by_target=L"windata/script_body.bin";
is_engine_certain=false;
class _5pb_2 : public ENGINE
{
public:
_5pb_2()
{
check_by = CHECK_BY::FILE;
check_by_target = L"windata/script_body.bin";
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -1,24 +1,29 @@
#include"A98SYS.h"
bool A98SYS::attach_function() {
//https://vndb.org/v6447
//Rainy Blue 6月の雨
#include "A98SYS.h"
auto addrs=findiatcallormov_all((DWORD)::ExtTextOutA, processStartAddress,processStartAddress, processStopAddress,PAGE_EXECUTE);
if(addrs.size()!=2)return false;
auto addr=addrs[1];
addr=MemDbg::findEnclosingAlignedFunction(addr);
if(!addr)return false;
auto addrs1=findxref_reverse_checkcallop(addr,processStartAddress, processStopAddress,0xe8);
if(!addrs1.size())return false;
addr=addrs1[0];
addr=MemDbg::findEnclosingAlignedFunction(addr);
if (!addr) return false;
bool A98SYS::attach_function()
{
// https://vndb.org/v6447
// Rainy Blue 6月の雨
auto addrs = findiatcallormov_all((DWORD)::ExtTextOutA, processStartAddress, processStartAddress, processStopAddress, PAGE_EXECUTE);
if (addrs.size() != 2)
return false;
auto addr = addrs[1];
addr = MemDbg::findEnclosingAlignedFunction(addr);
if (!addr)
return false;
auto addrs1 = findxref_reverse_checkcallop(addr, processStartAddress, processStopAddress, 0xe8);
if (!addrs1.size())
return false;
addr = addrs1[0];
addr = MemDbg::findEnclosingAlignedFunction(addr);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.type = USING_STRING|EMBED_ABLE|EMBED_AFTER_NEW|EMBED_BEFORE_SIMPLE|EMBED_DYNA_SJIS;
hp.hook_font=F_ExtTextOutA;
hp.offset = get_stack(1);
hp.type = USING_STRING | EMBED_ABLE | EMBED_AFTER_NEW | EMBED_BEFORE_SIMPLE | EMBED_DYNA_SJIS;
hp.hook_font = F_ExtTextOutA;
return NewHook(hp, "A98SYS");
}
}

View File

@ -1,11 +1,13 @@
class A98SYS:public ENGINE{
public:
A98SYS(){
check_by=CHECK_BY::FILE;
check_by_target=L"A98SYS.PAK";//STREAM.PAK
class A98SYS : public ENGINE
{
public:
A98SYS()
{
check_by = CHECK_BY::FILE;
check_by_target = L"A98SYS.PAK"; // STREAM.PAK
};
bool attach_function();
bool attach_function();
};

View File

@ -1,4 +1,4 @@
#include"AB2Try.h"
#include "AB2Try.h"
/********************************************************************************************
AkabeiSoft2Try hook:
@ -18,65 +18,58 @@ AkabeiSoft2Try hook:
So if you are in title screen this approach will fail.
********************************************************************************************/
namespace { // unnamed
namespace
{ // unnamed
typedef struct _NSTRING
{
PVOID vfTable;
DWORD lenWithNull;
DWORD lenWithoutNull;
WCHAR str[1];
} NSTRING;
typedef struct _NSTRING
{
PVOID vfTable;
DWORD lenWithNull;
DWORD lenWithoutNull;
WCHAR str[1];
} NSTRING;
// qsort correctly identifies overflow.
int cmp(const void * a, const void * b)
{ return *(int*)a - *(int*)b; }
void SpecialHookAB2Try(hook_stack* stack, HookParam *, uintptr_t *data, uintptr_t *split, size_t *len)
{
//DWORD test = *(DWORD*)(esp_base - 0x10);
DWORD edx = stack->edx;
if (edx != 0)
return;
//NSTRING *s = *(NSTRING **)(esp_base - 8);
if (const NSTRING *s = (NSTRING *)stack->eax) {
*len = s->lenWithoutNull << 1;
*data = (DWORD)s->str;
//*split = 0;
*split = FIXED_SPLIT_VALUE; // 8/3/2014 jichi: change to single threads
// qsort correctly identifies overflow.
int cmp(const void *a, const void *b)
{
return *(int *)a - *(int *)b;
}
}
bool FindCharacteristInstruction()
{
const BYTE bytes[] = { 0x0F, 0xB7, 0x44, 0x50, 0x0C, 0x89 };
for (auto addr : Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE_READWRITE))
{
//GROWL_DWORD(addr);
HookParam hp;
hp.address = addr;
hp.text_fun = SpecialHookAB2Try;
hp.type = USING_STRING | NO_CONTEXT | CODEC_UTF16;
ConsoleOutput("INSERT AB2Try");
//ConsoleOutput("Please adjust text speed to fastest/immediate.");
//RegisterEngineType(ENGINE_AB2T);
return NewHook(hp, "AB2Try");
}
return false;
}
void SpecialHookAB2Try(hook_stack *stack, HookParam *, uintptr_t *data, uintptr_t *split, size_t *len)
{
// DWORD test = *(DWORD*)(esp_base - 0x10);
DWORD edx = stack->edx;
if (edx != 0)
return;
// NSTRING *s = *(NSTRING **)(esp_base - 8);
if (const NSTRING *s = (NSTRING *)stack->eax)
{
*len = s->lenWithoutNull << 1;
*data = (DWORD)s->str;
//*split = 0;
*split = FIXED_SPLIT_VALUE; // 8/3/2014 jichi: change to single threads
}
}
bool FindCharacteristInstruction()
{
const BYTE bytes[] = {0x0F, 0xB7, 0x44, 0x50, 0x0C, 0x89};
for (auto addr : Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE_READWRITE))
{
// GROWL_DWORD(addr);
HookParam hp;
hp.address = addr;
hp.text_fun = SpecialHookAB2Try;
hp.type = USING_STRING | NO_CONTEXT | CODEC_UTF16;
// ConsoleOutput("Please adjust text speed to fastest/immediate.");
// RegisterEngineType(ENGINE_AB2T);
return NewHook(hp, "AB2Try");
}
return false;
}
} // unnamed namespace
bool InsertAB2TryHook()
bool AB2Try::attach_function()
{
bool ret = FindCharacteristInstruction();
if (ret)
ConsoleOutput("AB2Try: found characteristic sequence");
else
ConsoleOutput("AB2Try: cannot find characteristic sequence. Make sure you have start the game and have seen some text on the screen.");
return ret;
}
bool AB2Try::attach_function() {
return InsertAB2TryHook();
}
return FindCharacteristInstruction();
}

View File

@ -1,11 +1,13 @@
class AB2Try:public ENGINE{
public:
AB2Try(){
check_by=CHECK_BY::FILE;
check_by_target=L"Yanesdk.dll";
class AB2Try : public ENGINE
{
public:
AB2Try()
{
check_by = CHECK_BY::FILE;
check_by_target = L"Yanesdk.dll";
};
bool attach_function();
bool attach_function();
};

View File

@ -1,25 +1,28 @@
#include"ACTGS.h"
bool ACTGS::attach_function() {
const BYTE bytes[] = {
0x0F,0xBE,0xD0,
0x83,0xFA,0x20,
0x74,XX,
0x83,0xfa,0x09,
0x75,XX
#include "ACTGS.h"
};
bool ACTGS::attach_function()
{
const BYTE bytes[] = {
0x0F, 0xBE, 0xD0,
0x83, 0xFA, 0x20,
0x74, XX,
0x83, 0xfa, 0x09,
0x75, XX
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) return false;
if (!addr)
return false;
addr = findfuncstart(addr);
if (!addr) return false;
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(2);
hp.type = USING_STRING;
hp.offset = get_stack(2);
hp.type = USING_STRING;
hp.filter_fun = all_ascii_Filter;
return NewHook(hp, "ACTGS");
}
}

View File

@ -1,11 +1,13 @@
class ACTGS:public ENGINE{
public:
ACTGS(){
check_by=CHECK_BY::RESOURCE_STR;
check_by_target=L"ACTRESS Game System";
class ACTGS : public ENGINE
{
public:
ACTGS()
{
check_by = CHECK_BY::RESOURCE_STR;
check_by_target = L"ACTRESS Game System";
};
bool attach_function();
bool attach_function();
};

View File

@ -11,7 +11,6 @@ namespace
// 未破解
// v8 = _mbsnextc(String);
BYTE sig[] = {
//clang-format off
0x8b, 0x4c, 0x24, 0x04,
0x33, 0xd2,
0x0f, 0xb6, 0x01,
@ -22,9 +21,7 @@ namespace
0x41,
0x0f, 0xb6, 0x01,
0x03, 0xc2,
0xc3
//clang-format on
};
0xc3};
addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (!addr)
return 0;

View File

@ -37,17 +37,17 @@ FILESUBTYPE 0x0
class AGE_System : public ENGINE
{
public:
AGE_System()
{
AGE_System()
{
check_by = CHECK_BY::CUSTOM;
check_by_target = []()
{
auto s = check_by_list{L"Agrd.pac", L"vic.pac", L"se.pac", L"mus.pac"};
return Util::SearchResourceString(L"AGE_System") // 已破解
|| std::all_of(s.begin(), s.end(), [](auto f)
{ return Util::CheckFile_exits(f, true); }); // 未破解
};
check_by = CHECK_BY::CUSTOM;
check_by_target = []()
{
auto s = check_by_list{L"Agrd.pac", L"vic.pac", L"se.pac", L"mus.pac"};
return Util::SearchResourceString(L"AGE_System") // 已破解
|| std::all_of(s.begin(), s.end(), [](auto f)
{ return Util::CheckFile_exits(f, true); }); // 未破解
};
bool attach_function();
};
bool attach_function();
};

View File

@ -1,85 +1,91 @@
#include"AGS.h"
#include "AGS.h"
bool InsertAGSHook()
{
const BYTE bytes1[] = {
/*.text:0043E3A0 55 push ebp
.text : 0043E3A1 8B EC mov ebp, esp
.text : 0043E3A3 83 EC 38 sub esp, 38h
.text : 0043E3A6 53 push ebx
.text : 0043E3A7 56 push esi
.text : 0043E3A8 8B F1 mov esi, ecx*/
0x55,
0x8b,0xec,
0x83,0xec,0x38,0x53,0x56,0x8b,0xf1
};
ULONG addr = MemDbg::findBytes(bytes1, sizeof(bytes1), processStartAddress, processStopAddress);
if (!addr) {
/*.text:0043E3A0 55 push ebp
.text : 0043E3A1 8B EC mov ebp, esp
.text : 0043E3A3 83 EC 38 sub esp, 38h
.text : 0043E3A6 53 push ebx
.text : 0043E3A7 56 push esi
.text : 0043E3A8 8B F1 mov esi, ecx*/
0x55,
0x8b, 0xec,
0x83, 0xec, 0x38, 0x53, 0x56, 0x8b, 0xf1};
ULONG addr = MemDbg::findBytes(bytes1, sizeof(bytes1), processStartAddress, processStopAddress);
if (!addr)
{
return false;
}
}
const BYTE bytes2[] = {
/* .text:0043E95E FF 75 08 push[ebp + arg_0]
.text:0043E961 8B CE mov ecx, esi
.text : 0043E963 E8 38 FA FF FF call sub_43E3A0*/
0xff,0x75,0x08,
0x8b,0xce
};
/* .text:0043E95E FF 75 08 push[ebp + arg_0]
.text:0043E961 8B CE mov ecx, esi
.text : 0043E963 E8 38 FA FF FF call sub_43E3A0*/
0xff, 0x75, 0x08,
0x8b, 0xce};
bool ok = false;
auto addrs = findrelativecall(bytes2, sizeof(bytes2), addr, processStartAddress, processStopAddress);
for(auto addr :addrs){
for (auto addr : addrs)
{
addr = findfuncstart(addr);
if (!addr)continue;
if (!addr)
continue;
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::eax);
hp.offset = get_reg(regs::eax);
hp.type = USING_STRING;
ConsoleOutput("INSERT HOOK_AGS %p",addr);
ok |= NewHook(hp, "HOOK_AGS");
}
return ok;
ConsoleOutput("INSERT HOOK_AGS %p", addr);
ok |= NewHook(hp, "HOOK_AGS");
}
return ok;
}
namespace{
bool hook2(){
//誘惑女教師~熟れた蜜の味~
for (auto addr : findiatcallormov_all((DWORD)TextOutA,processStartAddress,processStartAddress,processStopAddress,PAGE_EXECUTE)) {
auto funcaddr = findfuncstart(addr,0x1000);
ConsoleOutput("funcaddr %p",funcaddr);
if (!funcaddr) continue;
BYTE sig1[]={0x68,0x00,0x80,0x00,0x00,0x6a,0x00};
BYTE sig2[]={0x2D,0xC0,0x00,0x00,0x00,0xC1,0xE0,0x08};
BYTE sig3[]={0x83,0xC0,0x80,0xC1,0xE0,0x08};
BYTE sig4[]={0x3C,0xA0,0x0F,0xB6,0xC0};
int found=0;
for(auto sigsz:std::vector<std::pair<BYTE*,int>>{{sig1,sizeof(sig1)},{sig2,sizeof(sig2)},{sig3,sizeof(sig3)},{sig4,sizeof(sig4)}}){
auto fd= MemDbg::findBytes(sigsz.first, sigsz.second, funcaddr, addr);
ConsoleOutput("%p",fd);
if(fd)found+=1;
namespace
{
bool hook2()
{
// 誘惑女教師~熟れた蜜の味~
for (auto addr : findiatcallormov_all((DWORD)TextOutA, processStartAddress, processStartAddress, processStopAddress, PAGE_EXECUTE))
{
auto funcaddr = findfuncstart(addr, 0x1000);
ConsoleOutput("funcaddr %p", funcaddr);
if (!funcaddr)
continue;
BYTE sig1[] = {0x68, 0x00, 0x80, 0x00, 0x00, 0x6a, 0x00};
BYTE sig2[] = {0x2D, 0xC0, 0x00, 0x00, 0x00, 0xC1, 0xE0, 0x08};
BYTE sig3[] = {0x83, 0xC0, 0x80, 0xC1, 0xE0, 0x08};
BYTE sig4[] = {0x3C, 0xA0, 0x0F, 0xB6, 0xC0};
int found = 0;
for (auto sigsz : std::vector<std::pair<BYTE *, int>>{{sig1, sizeof(sig1)}, {sig2, sizeof(sig2)}, {sig3, sizeof(sig3)}, {sig4, sizeof(sig4)}})
{
auto fd = MemDbg::findBytes(sigsz.first, sigsz.second, funcaddr, addr);
ConsoleOutput("%p", fd);
if (fd)
found += 1;
}
if(found==4){
HookParam hp;
hp.address = funcaddr;
hp.type = DATA_INDIRECT;
hp.offset=get_stack(1);
hp.index=0;
return NewHook(hp, "AGS");
if (found == 4)
{
HookParam hp;
hp.address = funcaddr;
hp.type = DATA_INDIRECT;
hp.offset = get_stack(1);
hp.index = 0;
return NewHook(hp, "AGS");
}
}
return false;
}
}
bool AGS::attach_function() {
return InsertAGSHook()||hook2();
}
bool AGS::attach_function()
{
return InsertAGSHook() || hook2();
}

View File

@ -1,12 +1,14 @@
class AGS:public ENGINE{
public:
AGS(){
check_by=CHECK_BY::FILE_ANY;
check_by_target=check_by_list{L"voice/*.pk",L"sound/*.pk",L"misc/*.pk"};
is_engine_certain=false;
class AGS : public ENGINE
{
public:
AGS()
{
check_by = CHECK_BY::FILE_ANY;
check_by_target = check_by_list{L"voice/*.pk", L"sound/*.pk", L"misc/*.pk"};
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -1,58 +1,63 @@
#include"AIL2.h"
bool InsertAIL2Hook() {
auto findalign = [](uintptr_t addr1) {
const BYTE pattern[] = { 0x90,0x90,0x83,0xec };
#include "AIL2.h"
bool InsertAIL2Hook()
{
auto findalign = [](uintptr_t addr1)
{
const BYTE pattern[] = {0x90, 0x90, 0x83, 0xec};
return reverseFindBytes(pattern, sizeof(pattern), processStartAddress, addr1) + 2;
};
bool succ=false;
bool succ = false;
BYTE bytes1[] = {
// .text:0042E5DF 3C 66 cmp al, 66h; 'f'
//.text:0042E5E1 74 57 jz short loc_42E63A
//.text : 0042E5E1
//.text : 0042E5E3 3C 70 cmp al, 70h; 'p'
//.text:0042E5E5 74 4C jz short loc_42E633
//.text : 0042E5E5
//.text : 0042E5E7 3C 73 cmp al, 73h; 's'
//.text:0042E5E9 74 37 jz short loc_42E622
0x3c,0x66,
0x74,XX,
0x3c,0x70,
0x74,XX,
0x3c,0x73,
0x74,XX
};
// .text:0042E5DF 3C 66 cmp al, 66h; 'f'
//.text:0042E5E1 74 57 jz short loc_42E63A
//.text : 0042E5E1
//.text : 0042E5E3 3C 70 cmp al, 70h; 'p'
//.text:0042E5E5 74 4C jz short loc_42E633
//.text : 0042E5E5
//.text : 0042E5E7 3C 73 cmp al, 73h; 's'
//.text:0042E5E9 74 37 jz short loc_42E622
0x3c, 0x66,
0x74, XX,
0x3c, 0x70,
0x74, XX,
0x3c, 0x73,
0x74, XX};
auto addr1 = MemDbg::findBytes(bytes1, sizeof(bytes1), processStartAddress, processStopAddress);
if (addr1 == 0) return false;
if (addr1 == 0)
return false;
addr1 = findalign(addr1);
if (addr1 == 0) return false;
if (addr1 == 0)
return false;
ConsoleOutput("AIL1 %p", addr1);
HookParam hp;
hp.address = addr1;
hp.codepage = 932;
hp.offset=get_stack(3);
hp.offset = get_stack(3);
hp.type = USING_STRING;
succ|=NewHook(hp, "AIL1");
BYTE bytes[] = { //if ( v12 != 32 && v12 != 33088 )
0x3d,0x40,0x81,0x00,0x00,0x0f
};
succ |= NewHook(hp, "AIL1");
BYTE bytes[] = {// if ( v12 != 32 && v12 != 33088 )
0x3d, 0x40, 0x81, 0x00, 0x00, 0x0f};
addr1 = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (addr1 == 0) return succ;
if (addr1 == 0)
return succ;
addr1 = MemDbg::findEnclosingAlignedFunction(addr1);
if (addr1 == 0) return succ;
if (addr1 == 0)
return succ;
hp = {};
hp.address = addr1;
hp.codepage = 932;
hp.offset=get_stack(4);
hp.offset = get_stack(4);
hp.type = USING_STRING | USING_SPLIT;
hp.split_index = 0;
succ|=NewHook(hp, "AIL2");
succ |= NewHook(hp, "AIL2");
return succ;
}
bool AIL2::attach_function() {
//アイル
bool AIL2::attach_function()
{
// アイル
return InsertAIL2Hook();
}
return InsertAIL2Hook();
}

View File

@ -1,11 +1,13 @@
class AIL2:public ENGINE{
public:
AIL2(){
check_by=CHECK_BY::FILE;
check_by_target=L"Gall*.dat";
class AIL2 : public ENGINE
{
public:
AIL2()
{
check_by = CHECK_BY::FILE;
check_by_target = L"Gall*.dat";
};
bool attach_function();
bool attach_function();
};

View File

@ -1,4 +1,4 @@
#include"AOS.h"
#include "AOS.h"
/**
* jichi 4/1/2014: Insert AOS hook
@ -65,7 +65,7 @@ bool InsertAOS1Hook()
// jichi 4/2/2014: The starting of this function is different from ヂ<>ツキ
// So, use a pattern in the middle of the function instead.
//
//const BYTE bytes[] = {
// const BYTE bytes[] = {
// 0x51, // 00e3c2f0 /$ 51 push ecx ; jichi: hook here, function begins
// 0xa1, 0x0c,0x64,0xeb,0x00, // 00e3c2f1 |. a1 0c64eb00 mov eax,dword ptr ds:[0xeb640c]
// 0x8b,0x0d, 0x78,0x46,0xeb,0x00, // 00e3c2f6 |. 8b0d 7846eb00 mov ecx,dword ptr ds:[0xeb4678]
@ -78,118 +78,144 @@ bool InsertAOS1Hook()
// 0x0f,0xb6,0x3d, 0xc7,0x46,0xeb,0x00, // 00e3c30a |. 0fb63d c746eb00 movzx edi,byte ptr ds:[0xeb46c7]
// 0x81,0xe6, 0xff,0xff,0xff,0x00 // 00e3c311 |. 81e6 ffffff00 and esi,0xffffff
//};
//enum { addr_offset = 0 };
// enum { addr_offset = 0 };
const BYTE bytes[] = {
0x0f,0xbf,0x55, 0x1c, // 00e3c33c |> 0fbf55 1c movsx edx,word ptr ss:[ebp+0x1c]
0x0f,0xbf,0x45, 0x0a, // 00e3c340 |. 0fbf45 0a movsx eax,word ptr ss:[ebp+0xa]
0x0f,0xbf,0x75, 0x1a, // 00e3c344 |. 0fbf75 1a movsx esi,word ptr ss:[ebp+0x1a]
0x03,0xd7, // 00e3c348 |. 03d7 add edx,edi
0x03,0xc2, // 00e3c34a |. 03c2 add eax,edx
0x0f,0xbf,0x55, 0x08, // 00e3c34c |. 0fbf55 08 movsx edx,word ptr ss:[ebp+0x8]
0x03,0xf7, // 00e3c350 |. 03f7 add esi,edi
0x03,0xd6, // 00e3c352 |. 03d6 add edx,esi
0x85,0xc9 // 00e3c354 |. 85c9 test ecx,ecx
0x0f, 0xbf, 0x55, 0x1c, // 00e3c33c |> 0fbf55 1c movsx edx,word ptr ss:[ebp+0x1c]
0x0f, 0xbf, 0x45, 0x0a, // 00e3c340 |. 0fbf45 0a movsx eax,word ptr ss:[ebp+0xa]
0x0f, 0xbf, 0x75, 0x1a, // 00e3c344 |. 0fbf75 1a movsx esi,word ptr ss:[ebp+0x1a]
0x03, 0xd7, // 00e3c348 |. 03d7 add edx,edi
0x03, 0xc2, // 00e3c34a |. 03c2 add eax,edx
0x0f, 0xbf, 0x55, 0x08, // 00e3c34c |. 0fbf55 08 movsx edx,word ptr ss:[ebp+0x8]
0x03, 0xf7, // 00e3c350 |. 03f7 add esi,edi
0x03, 0xd6, // 00e3c352 |. 03d6 add edx,esi
0x85, 0xc9 // 00e3c354 |. 85c9 test ecx,ecx
};
enum { addr_offset = 0x00e3c2f0 - 0x00e3c33c }; // distance to the beginning of the function, which is 0x51 (push ecx)
enum
{
addr_offset = 0x00e3c2f0 - 0x00e3c33c
}; // distance to the beginning of the function, which is 0x51 (push ecx)
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
//GROWL(reladdr);
if (!addr) {
// GROWL(reladdr);
if (!addr)
{
ConsoleOutput("AOS1: pattern not found");
return false;
}
addr += addr_offset;
//GROWL(addr);
enum { push_ecx = 0x51 }; // beginning of the function
if (*(BYTE *)addr != push_ecx) {
// GROWL(addr);
enum
{
push_ecx = 0x51
}; // beginning of the function
if (*(BYTE *)addr != push_ecx)
{
ConsoleOutput("AOS1: beginning of the function not found");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_stack(2);
hp.offset = get_stack(2);
hp.type = DATA_INDIRECT;
ConsoleOutput("INSERT AOS1");
return NewHook(hp, "AOS1");
return NewHook(hp, "AOS1");
}
bool InsertAOS2Hook()
{
const BYTE bytes[] = {
0x51, // 00C4E7E0 /$ 51 PUSH ECX ; mireado: hook here, function begins
0x33,0xc0, // 00C4E7E1 |. 33C0 XOR EAX,EAX
0x53, // 00C4E7E3 |. 53 PUSH EBX
0x55, // 00C4E7E4 |. 55 PUSH EBP
0x8b,0x2d//, XX4, // 00C4E7E5 |. 8B2D 40A3CF00 MOV EBP,DWORD PTR DS:[0CFA340] ; mireado: some time changing 40A3CF00 => 40A3C000
//0x89,0x07, // 00C4E7EB |. 8907 MOV DWORD PTR DS:[EDI],EAX
//0x89,0x47, 0x04 // 00C4E7ED |. 8947 04 MOV DWORD PTR DS:[EDI+4],EAX
//0x56, // 00C4E7F0 |. 56 PUSH ESI
//0x8b,0x75, 0x44 // 00C4E7F1 |. 8B75 44 MOV ESI,DWORD PTR SS:[EBP+44]
0x51, // 00C4E7E0 /$ 51 PUSH ECX ; mireado: hook here, function begins
0x33, 0xc0, // 00C4E7E1 |. 33C0 XOR EAX,EAX
0x53, // 00C4E7E3 |. 53 PUSH EBX
0x55, // 00C4E7E4 |. 55 PUSH EBP
0x8b, 0x2d //, XX4, // 00C4E7E5 |. 8B2D 40A3CF00 MOV EBP,DWORD PTR DS:[0CFA340] ; mireado: some time changing 40A3CF00 => 40A3C000
// 0x89,0x07, // 00C4E7EB |. 8907 MOV DWORD PTR DS:[EDI],EAX
// 0x89,0x47, 0x04 // 00C4E7ED |. 8947 04 MOV DWORD PTR DS:[EDI+4],EAX
// 0x56, // 00C4E7F0 |. 56 PUSH ESI
// 0x8b,0x75, 0x44 // 00C4E7F1 |. 8B75 44 MOV ESI,DWORD PTR SS:[EBP+44]
};
enum { addr_offset = 0 }; // distance to the beginning of the function, which is 0x51 (push ecx)
enum
{
addr_offset = 0
}; // distance to the beginning of the function, which is 0x51 (push ecx)
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
//GROWL(reladdr);
if (!addr) {
// GROWL(reladdr);
if (!addr)
{
ConsoleOutput("AOS2: pattern not found");
return false;
}
addr += addr_offset;
//GROWL(addr);
enum { push_ecx = 0x51 }; // beginning of the function
if (*(BYTE *)addr != push_ecx) {
// GROWL(addr);
enum
{
push_ecx = 0x51
}; // beginning of the function
if (*(BYTE *)addr != push_ecx)
{
ConsoleOutput("AOS2: beginning of the function not found");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_stack(2);
hp.offset = get_stack(2);
hp.type = DATA_INDIRECT;
ConsoleOutput("INSERT AOS2");
return NewHook(hp, "AOS2");
}
bool InsertAOSHook()
{ return InsertAOS1Hook() || InsertAOS2Hook();}
namespace{
DWORD calladdr(DWORD addr){
if(addr==0)return 0;
BYTE callop[] = { 0xe8 };
addr = reverseFindBytes(callop, sizeof(callop), addr - 0x20, addr);
if (addr == 0)return 0;
auto calladdr = *(int*)((char*)addr + 1);
ConsoleOutput("calladdr %p", calladdr);
addr = calladdr + addr + 5;
ConsoleOutput("funcaddr %p", addr);
if (*(BYTE*)((BYTE*)addr - 1) != 0xcc)return 0;
return addr;
{
return InsertAOS1Hook() || InsertAOS2Hook();
}
DWORD lastcall(){
auto addr = findiatcallormov((DWORD)TextOutA,processStartAddress,processStartAddress, processStopAddress,true);
if(addr==0)return 0;
addr = MemDbg::findEnclosingAlignedFunction(addr);
return addr;
}
namespace
{
DWORD calladdr(DWORD addr)
{
if (addr == 0)
return 0;
BYTE callop[] = {0xe8};
addr = reverseFindBytes(callop, sizeof(callop), addr - 0x20, addr);
if (addr == 0)
return 0;
auto calladdr = *(int *)((char *)addr + 1);
ConsoleOutput("calladdr %p", calladdr);
addr = calladdr + addr + 5;
ConsoleOutput("funcaddr %p", addr);
if (*(BYTE *)((BYTE *)addr - 1) != 0xcc)
return 0;
return addr;
}
DWORD lastcall()
{
auto addr = findiatcallormov((DWORD)TextOutA, processStartAddress, processStartAddress, processStopAddress, true);
if (addr == 0)
return 0;
addr = MemDbg::findEnclosingAlignedFunction(addr);
return addr;
}
}
regs mov_reg_ebpoffset(int reg) {
switch (reg) {
regs mov_reg_ebpoffset(int reg)
{
switch (reg)
{
case 0x4B:
return regs::ebx;
return regs::ebx;
case 0x48:
return regs::eax;
case 0x49:
return regs::ecx;
return regs::ecx;
case 0x4a:
return regs::edx;
case 0x4c:
@ -204,71 +230,78 @@ regs mov_reg_ebpoffset(int reg) {
return regs::invalid;
}
}
bool AOS_EX() {
BYTE aos_shared_bytes1[] = {
0x3c,XX,
0x74,XX,
0x3c,XX,
0x74,XX,
0x3c,XX,
0x74,XX,
0x3c,XX,
0x74,XX,
0x3c,XX,
0x74,XX,
};
BYTE aos_shared_bytes2[] = {
0x80,0xfb,XX,
0x74,XX,
0x80,0xfb,XX,
0x74,XX,
0x80,0xfb,XX,
0x74,XX,
0x80,0xfb,XX,
0x74,XX
};
std::vector<DWORD>addrs;
bool AOS_EX()
{
BYTE aos_shared_bytes1[] = {
0x3c, XX,
0x74, XX,
0x3c, XX,
0x74, XX,
0x3c, XX,
0x74, XX,
0x3c, XX,
0x74, XX,
0x3c, XX,
0x74, XX};
BYTE aos_shared_bytes2[] = {
0x80, 0xfb, XX,
0x74, XX,
0x80, 0xfb, XX,
0x74, XX,
0x80, 0xfb, XX,
0x74, XX,
0x80, 0xfb, XX,
0x74, XX};
std::vector<DWORD> addrs;
addrs.push_back(calladdr(MemDbg::findBytes(aos_shared_bytes1, sizeof(aos_shared_bytes1), processStartAddress, processStopAddress)));
addrs.push_back(calladdr(MemDbg::findBytes(aos_shared_bytes2, sizeof(aos_shared_bytes2), processStartAddress, processStopAddress)));
addrs.push_back(lastcall());
for(auto addr: addrs){
if (addr == 0)continue;
auto reg = mov_reg_ebpoffset(*(BYTE*)((BYTE*)addr + 5));
int off;
if (reg!=regs::invalid){
//usercall
off=get_reg(reg);
}
else if(((*(WORD*)addr))==0xec83) {
//姫様LOVEライフ
//也是usercall但是第二个参数是栈上。
off=get_stack(1);
}
else{
//螺旋遡行のディストピア -The infinite set of alternative version- 官方中文
BYTE sig[]={0x89,0x55,0xFC};
if(MemDbg::findBytes(sig, sizeof(sig), addr, addr+0x20)){
off=get_reg(regs::edx);
}
else{
//cdecl;
off=get_stack(2);
}
}
HookParam hp;
hp.address = addr;
hp.offset = off;
hp.type = NO_CONTEXT | DATA_INDIRECT;
hp.index = 0;
return NewHook(hp, "AOS_EX");
for (auto addr : addrs)
{
if (addr == 0)
continue;
auto reg = mov_reg_ebpoffset(*(BYTE *)((BYTE *)addr + 5));
int off;
if (reg != regs::invalid)
{
// usercall
off = get_reg(reg);
}
else if (((*(WORD *)addr)) == 0xec83)
{
// 姫様LOVEライフ
// 也是usercall但是第二个参数是栈上。
off = get_stack(1);
}
else
{
// 螺旋遡行のディストピア -The infinite set of alternative version- 官方中文
BYTE sig[] = {0x89, 0x55, 0xFC};
if (MemDbg::findBytes(sig, sizeof(sig), addr, addr + 0x20))
{
off = get_reg(regs::edx);
}
else
{
// cdecl;
off = get_stack(2);
}
}
HookParam hp;
hp.address = addr;
hp.offset = off;
hp.type = NO_CONTEXT | DATA_INDIRECT;
hp.index = 0;
return NewHook(hp, "AOS_EX");
}
return false;
}
bool AOS::attach_function() {
bool b1=InsertAOSHook();
bool b3=AOS_EX();
return b1||b3;
}
bool AOS::attach_function()
{
bool b1 = InsertAOSHook();
bool b3 = AOS_EX();
return b1 || b3;
}

View File

@ -1,11 +1,13 @@
class AOS:public ENGINE{
public:
AOS(){
check_by=CHECK_BY::FILE;
check_by_target=L"*.aos";
class AOS : public ENGINE
{
public:
AOS()
{
check_by = CHECK_BY::FILE;
check_by_target = L"*.aos";
};
bool attach_function();
bool attach_function();
};

View File

@ -1,46 +1,50 @@
#include"AXL.h"
bool InsertAXLHook() {
//キミの声がきこえる
#include "AXL.h"
bool InsertAXLHook()
{
// キミの声がきこえる
BYTE bytes[] = {
0x0f,0x95,0xc2,0x33,0xc0,0xB9,0x41,0x00,0x00,0x00
};
0x0f, 0x95, 0xc2, 0x33, 0xc0, 0xB9, 0x41, 0x00, 0x00, 0x00};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (addr == 0)return false;
addr = findfuncstart(addr,0x1000);
if (addr == 0)return false;
if (addr == 0)
return false;
addr = findfuncstart(addr, 0x1000);
if (addr == 0)
return false;
HookParam hp;
hp.address = addr ;
hp.address = addr;
hp.offset = get_stack(4);
hp.type = USING_STRING;
return NewHook(hp, "AXL");
return NewHook(hp, "AXL");
}
namespace{
bool hook2(){
//剣乙女ノア
//Maria天使のキスと悪魔の花嫁
namespace
{
bool hook2()
{
// 剣乙女ノア
// Maria天使のキスと悪魔の花嫁
BYTE bytes[] = {
0x55,0x8b,0xec,
0x56,
0x8b,0xf0,
0x3b,0x9e,0x8c,0xf8,0x00,0x00,
0x57
};
0x55, 0x8b, 0xec,
0x56,
0x8b, 0xf0,
0x3b, 0x9e, 0x8c, 0xf8, 0x00, 0x00,
0x57};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (addr == 0)return false;
if (addr == 0)
return false;
HookParam hp;
hp.address = addr ;
hp.offset=get_stack(1);
hp.split=get_reg(regs::eax);
hp.type=USING_SPLIT;
hp.address = addr;
hp.offset = get_stack(1);
hp.split = get_reg(regs::eax);
hp.type = USING_SPLIT;
return NewHook(hp, "TAILWIND");
}
}
bool AXL::attach_function() {
return InsertAXLHook()||hook2();
}
bool AXL::attach_function()
{
return InsertAXLHook() || hook2();
}

View File

@ -1,12 +1,14 @@
class AXL:public ENGINE{
public:
AXL(){
check_by=CHECK_BY::FILE;
check_by_target=L"script.arc";
is_engine_certain=false;
class AXL : public ENGINE
{
public:
AXL()
{
check_by = CHECK_BY::FILE;
check_by_target = L"script.arc";
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -1,21 +1,23 @@
#include"Abalone.h"
#include "Abalone.h"
bool AbaloneHook() {
bool AbaloneHook()
{
BYTE bytes[] = {
0x8B,0x44,0x24,XX,
0x80,0x38,0x00,
0x74
};
0x8B, 0x44, 0x24, XX,
0x80, 0x38, 0x00,
0x74};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
ConsoleOutput("AbaloneHook %p", addr);
if (addr == 0)return false;
if (addr == 0)
return false;
HookParam hp;
hp.address = addr+4;
hp.offset=get_reg(regs::eax);
hp.type = DATA_INDIRECT;
hp.address = addr + 4;
hp.offset = get_reg(regs::eax);
hp.type = DATA_INDIRECT;
hp.index = 0;
return NewHook(hp, "AbaloneHook");
}
bool Abalone::attach_function() {
return AbaloneHook();
}
}
bool Abalone::attach_function()
{
return AbaloneHook();
}

View File

@ -1,12 +1,14 @@
class Abalone:public ENGINE{
public:
Abalone(){
check_by=CHECK_BY::FILE;
check_by_target=L"Archive.dat";
is_engine_certain=false;
class Abalone : public ENGINE
{
public:
Abalone()
{
check_by = CHECK_BY::FILE;
check_by_target = L"Archive.dat";
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -1,5 +1,5 @@
#include"Abel.h"
#include "Abel.h"
/********************************************************************************************
AbelSoftware hook:
The game folder usually is made up many no extended name files(file name doesn't have '.').
@ -399,18 +399,16 @@ bool InsertAbelHook()
// 004413DB 894424 58 MOV DWORD PTR SS:[ESP+0x58],EAX
const DWORD character[] = {0xc981d48a, 0xffffff00};
if (DWORD j = SearchPattern(processStartAddress, processStopAddress - processStartAddress, character, sizeof(character))) {
if (DWORD j = SearchPattern(processStartAddress, processStopAddress - processStartAddress, character, sizeof(character)))
{
j += processStartAddress;
for (DWORD i = j - 0x100; j > i; j--)
if (*(WORD *)j == 0xff6a) {
if (*(WORD *)j == 0xff6a)
{
HookParam hp;
hp.address = j;
hp.offset=get_stack(1);
hp.type = USING_STRING|NO_CONTEXT;
ConsoleOutput("INSERT Abel");
//GROWL_DWORD(hp.address);
//RegisterEngineType(ENGINE_ABEL);
hp.offset = get_stack(1);
hp.type = USING_STRING | NO_CONTEXT;
return NewHook(hp, "Abel");
}
}
@ -418,7 +416,8 @@ bool InsertAbelHook()
return false;
}
bool Abel::attach_function() {
return InsertAbelHook();
}
bool Abel::attach_function()
{
return InsertAbelHook();
}

View File

@ -1,54 +1,55 @@
class Abel:public ENGINE{
public:
Abel(){
check_by=CHECK_BY::CUSTOM;
check_by_target=[](){
class Abel : public ENGINE
{
public:
Abel()
{
// jichi 8/24/2013: Move into functions
// Artikash 6/15/2018: Removed this detection for Abel Software games. IthGetFileInfo no longer works correctly
//static BYTE static_file_info[0x1000];
//if (IthGetFileInfo(L"*01", static_file_info))
// if (*(DWORD*)static_file_info == 0) {
// STATUS_INFO_LENGTH_MISMATCH;
// static WCHAR static_search_name[MAX_PATH];
// LPWSTR name=(LPWSTR)(static_file_info+0x5E);
// int len = wcslen(name);
// name[len-2] = L'.';
// name[len-1] = L'e';
// name[len] = L'x';
// name[len+1] = L'e';
// name[len+2] = 0;
// if (Util::CheckFile(name)) {
// sizeof(FILE_BOTH_DIR_INFORMATION);
// name[len-2] = L'*';
// name[len-1] = 0;
// wcscpy(static_search_name,name);
// IthGetFileInfo(static_search_name,static_file_info);
// union {
// FILE_BOTH_DIR_INFORMATION *both_info;
// DWORD addr;
// };
// both_info = (FILE_BOTH_DIR_INFORMATION *)static_file_info;
// //BYTE* ptr=static_file_info;
// len=0;
// while (both_info->NextEntryOffset) {
// addr += both_info->NextEntryOffset;
// len++;
// }
// if (len > 3) {
// InsertAbelHook();
// return true;
// }
// }
// }
check_by = CHECK_BY::CUSTOM;
check_by_target = []()
{
// jichi 8/24/2013: Move into functions
// Artikash 6/15/2018: Removed this detection for Abel Software games. IthGetFileInfo no longer works correctly
// static BYTE static_file_info[0x1000];
// if (IthGetFileInfo(L"*01", static_file_info))
// if (*(DWORD*)static_file_info == 0) {
// STATUS_INFO_LENGTH_MISMATCH;
// static WCHAR static_search_name[MAX_PATH];
// LPWSTR name=(LPWSTR)(static_file_info+0x5E);
// int len = wcslen(name);
// name[len-2] = L'.';
// name[len-1] = L'e';
// name[len] = L'x';
// name[len+1] = L'e';
// name[len+2] = 0;
// if (Util::CheckFile(name)) {
// sizeof(FILE_BOTH_DIR_INFORMATION);
// name[len-2] = L'*';
// name[len-1] = 0;
// wcscpy(static_search_name,name);
// IthGetFileInfo(static_search_name,static_file_info);
// union {
// FILE_BOTH_DIR_INFORMATION *both_info;
// DWORD addr;
// };
// both_info = (FILE_BOTH_DIR_INFORMATION *)static_file_info;
// //BYTE* ptr=static_file_info;
// len=0;
// while (both_info->NextEntryOffset) {
// addr += both_info->NextEntryOffset;
// len++;
// }
// if (len > 3) {
// InsertAbelHook();
// return true;
// }
// }
// }
return (Util::CheckFile(L"system") && Util::CheckFile(L"system.dat")) || Util::CheckFile(L"*01");
};
is_engine_certain=false;
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -1,5 +1,5 @@
#include"AdobeAir.h"
#include "AdobeAir.h"
/**
* jichi 4/15/2014: Insert Adobe AIR hook
* Sample games:
@ -66,160 +66,179 @@
bool InsertAdobeAirHook()
{
DWORD base = (DWORD)GetModuleHandleW(L"Adobe AIR.dll");
if (!base) {
if (!base)
{
ConsoleOutput("Adobe AIR: module not found");
return false;
}
//ULONG processStartAddress, processStopAddress;
//if (!NtInspect::getModuleMemoryRange(L"Adobe AIR.dll", &startAddress, &stopAddress)) {
// ConsoleOutput("Adobe AIR: module not found");
// return false;
//}
// ULONG processStartAddress, processStopAddress;
// if (!NtInspect::getModuleMemoryRange(L"Adobe AIR.dll", &startAddress, &stopAddress)) {
// ConsoleOutput("Adobe AIR: module not found");
// return false;
// }
const BYTE bytes[] = {
0x0f,0xb7,0x0a, // 0f8f04b2 |> 0fb70a /movzx ecx,word ptr ds:[edx]
0x8b,0xd8, // 0f8f04b5 |. 8bd8 |mov ebx,eax ; jichi: hook here
0x4f, // 0f8f04b7 |. 4f |dec edi
0x66,0x3b,0xcb, // 0f8f04b8 |. 66:3bcb |cmp cx,bx
0x73, 0x05, // 0f8f04bb |. 73 05 |jnb short adobe_ai.0f8f04c2
0xff,0x45, 0xfc, // 0f8f04bd |. ff45 fc |inc dword ptr ss:[ebp-0x4]
0xeb, 0x3a // 0f8f04c0 |. eb 3a |jmp short adobe_ai.0f8f04fc
0x0f, 0xb7, 0x0a, // 0f8f04b2 |> 0fb70a /movzx ecx,word ptr ds:[edx]
0x8b, 0xd8, // 0f8f04b5 |. 8bd8 |mov ebx,eax ; jichi: hook here
0x4f, // 0f8f04b7 |. 4f |dec edi
0x66, 0x3b, 0xcb, // 0f8f04b8 |. 66:3bcb |cmp cx,bx
0x73, 0x05, // 0f8f04bb |. 73 05 |jnb short adobe_ai.0f8f04c2
0xff, 0x45, 0xfc, // 0f8f04bd |. ff45 fc |inc dword ptr ss:[ebp-0x4]
0xeb, 0x3a // 0f8f04c0 |. eb 3a |jmp short adobe_ai.0f8f04fc
};
enum { addr_offset = 0x0f8f04b5 - 0x0f8f04b2 }; // = 3. 0 also works.
enum { range = 0x600000 }; // larger than relative addresses
enum
{
addr_offset = 0x0f8f04b5 - 0x0f8f04b2
}; // = 3. 0 also works.
enum
{
range = 0x600000
}; // larger than relative addresses
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), base, base + range);
//GROWL(reladdr);
if (!addr) {
// GROWL(reladdr);
if (!addr)
{
ConsoleOutput("Adobe AIR: pattern not found");
return false;
}
HookParam hp;
hp.address = addr + addr_offset;
//hp.module = module;
hp.offset=get_reg(regs::edx);
// hp.module = module;
hp.offset = get_reg(regs::edx);
hp.split = 0xd8;
//hp.type = USING_SPLIT|MODULE_OFFSET|CODEC_UTF16|DATA_INDIRECT; // 0x5a;
hp.type = USING_SPLIT|CODEC_UTF16|DATA_INDIRECT;
// hp.type = USING_SPLIT|MODULE_OFFSET|CODEC_UTF16|DATA_INDIRECT; // 0x5a;
hp.type = USING_SPLIT | CODEC_UTF16 | DATA_INDIRECT;
ConsoleOutput("INSERT Adobe AIR");
return NewHook(hp, "Adobe AIR");
}
bool AdobeAIRhook2() {
auto hmodule =(DWORD) GetModuleHandle(L"Adobe AIR.dll");
if (hmodule == 0)return false;
enum { range = 0x600000 }; // larger than relative addresses
auto [minAddress, maxAddress] = std::make_pair(hmodule,hmodule+range);
bool AdobeAIRhook2()
{
auto hmodule = (DWORD)GetModuleHandle(L"Adobe AIR.dll");
if (hmodule == 0)
return false;
enum
{
range = 0x600000
}; // larger than relative addresses
auto [minAddress, maxAddress] = std::make_pair(hmodule, hmodule + range);
const BYTE bs[] = {
//トリック・オア・アリス
0x66,0x83,0xF8,0x19,
0x77,XX,
0x81,0xC7,0xE0,0xFF,0x00,0x00
};
// トリック・オア・アリス
0x66, 0x83, 0xF8, 0x19,
0x77, XX,
0x81, 0xC7, 0xE0, 0xFF, 0x00, 0x00};
auto addr = MemDbg::findBytes(bs, sizeof(bs), minAddress, maxAddress);
ConsoleOutput("%p", addr);
if (addr == 0)return false;
const BYTE start[] = { 0xC2,0x10,0x00 };// retn 10h+3
if (addr == 0)
return false;
const BYTE start[] = {0xC2, 0x10, 0x00}; // retn 10h+3
addr = reverseFindBytes(start, 3, addr - 0x1000, addr);
ConsoleOutput("%p", addr);
if (addr == 0)return false;
if (addr == 0)
return false;
HookParam hp;
hp.address = addr+3;
hp.offset=get_stack(1);
hp.type = USING_STRING|CODEC_UTF16;
return NewHook(hp, "AdobeAIR");
}
hp.address = addr + 3;
hp.offset = get_stack(1);
hp.type = USING_STRING | CODEC_UTF16;
return NewHook(hp, "AdobeAIR");
}
/**
* Artikash 12/8/2018: Update AIRNovel hook for version 31.0.0.96
* Sample game: https://vndb.org/v22252: /HQ4*8:4*4@12FF9A:Adobe AIR.dll
* This function is called from Adobe AIR.FREGetObjectAsUTF8+5A
* First function parameter points to a struct containing a pointer to the text along with info about the type of text
* wchar_t* at offset 8
*/
* Artikash 12/8/2018: Update AIRNovel hook for version 31.0.0.96
* Sample game: https://vndb.org/v22252: /HQ4*8:4*4@12FF9A:Adobe AIR.dll
* This function is called from Adobe AIR.FREGetObjectAsUTF8+5A
* First function parameter points to a struct containing a pointer to the text along with info about the type of text
* wchar_t* at offset 8
*/
bool InsertAIRNovelHook()
{
wcscpy_s(spDefault.boundaryModule, L"Adobe AIR.dll");
if (DWORD FREGetObjectAsUTF8 = (DWORD)GetProcAddress(GetModuleHandleW(L"Adobe AIR.dll"), "FREGetObjectAsUTF8"))
{
DWORD func = FREGetObjectAsUTF8 + 0x5a + 5 + *(int*)(FREGetObjectAsUTF8 + 0x5b);
HookParam hp;
hp.address = func;
hp.type = CODEC_UTF16|USING_STRING/*|USING_SPLIT|SPLIT_INDIRECT*/|DATA_INDIRECT; // Artikash 12/14/2018: doesn't seem to be a good split anymore
hp.offset=get_stack(1);
hp.split =get_stack(1);
hp.index = 0x8;
hp.split_index = 0x4;
//hp.filter_fun = [](void* str, DWORD* len, HookParam* hp, BYTE index) // removes some of the garbage threads
//{
// return *len < 4 &&
// *(char*)str != '[' &&
// *(char*)str != ';' &&
// *(char*)str != '&' &&
// *(char*)str != '*' &&
// *(char*)str != '\n' &&
// *(char*)str != '\t' &&
// memcmp((char*)str, "app:/", 5);
//};
wcscpy_s(spDefault.boundaryModule, L"Adobe AIR.dll");
if (DWORD FREGetObjectAsUTF8 = (DWORD)GetProcAddress(GetModuleHandleW(L"Adobe AIR.dll"), "FREGetObjectAsUTF8"))
{
DWORD func = FREGetObjectAsUTF8 + 0x5a + 5 + *(int *)(FREGetObjectAsUTF8 + 0x5b);
HookParam hp;
hp.address = func;
hp.type = CODEC_UTF16 | USING_STRING /*|USING_SPLIT|SPLIT_INDIRECT*/ | DATA_INDIRECT; // Artikash 12/14/2018: doesn't seem to be a good split anymore
hp.offset = get_stack(1);
hp.split = get_stack(1);
hp.index = 0x8;
hp.split_index = 0x4;
// hp.filter_fun = [](void* str, DWORD* len, HookParam* hp, BYTE index) // removes some of the garbage threads
//{
// return *len < 4 &&
// *(char*)str != '[' &&
// *(char*)str != ';' &&
// *(char*)str != '&' &&
// *(char*)str != '*' &&
// *(char*)str != '\n' &&
// *(char*)str != '\t' &&
// memcmp((char*)str, "app:/", 5);
// };
ConsoleOutput("INSERT AIRNovel");
return NewHook(hp, "AIRNovel");
}
return false;
ConsoleOutput("INSERT AIRNovel");
return NewHook(hp, "AIRNovel");
}
return false;
}
bool adobelair3(){
//虚構英雄ジンガイアVol3
bool adobelair3()
{
// 虚構英雄ジンガイアVol3
DWORD base = (DWORD)GetModuleHandleW(L"Adobe AIR.dll");
if (!base)return false;
BYTE sig[]={
0x8b,0x85,XX4,
0x8B,0x4E,0x04,
0x85,0xC9,
0x0F,0x85,XX4,
0xFF,0x70,0x14,
0x8B,0x78,0x0c,
0x8b,0xcf,
0x68,0xb8,0x00,0x00,0x00,
0xff,0x15,XX4,
0xff,0xd7,
0x8b,0xc8,
0x83,0xc4,0x08,
0x85,0xc9,
0x0f,0x85,XX4
};
enum { range = 0x600000 }; // larger than relative addresses
auto [minAddress, maxAddress] = std::make_pair(base,base+range);
auto addr=MemDbg::findBytes(sig,sizeof(sig),minAddress,maxAddress);
if (!base)
return false;
BYTE sig[] = {
0x8b, 0x85, XX4,
0x8B, 0x4E, 0x04,
0x85, 0xC9,
0x0F, 0x85, XX4,
0xFF, 0x70, 0x14,
0x8B, 0x78, 0x0c,
0x8b, 0xcf,
0x68, 0xb8, 0x00, 0x00, 0x00,
0xff, 0x15, XX4,
0xff, 0xd7,
0x8b, 0xc8,
0x83, 0xc4, 0x08,
0x85, 0xc9,
0x0f, 0x85, XX4};
enum
{
range = 0x600000
}; // larger than relative addresses
auto [minAddress, maxAddress] = std::make_pair(base, base + range);
auto addr = MemDbg::findBytes(sig, sizeof(sig), minAddress, maxAddress);
HookParam hp;
hp.address = addr;
hp.type = CODEC_UTF8|USING_STRING|NO_CONTEXT;
hp.offset=get_stack(1);
hp.filter_fun=[](void* data, size_t* len, HookParam* hp){
//若当前还有5个字符则这个句子会显示5次然后substr(1,len-1)直到结束总共显示5+4+3+2+1次
auto ws=StringToWideString(std::string((char*)data,*len));
static int leng=0;
if(ws.length()<=leng){
leng=ws.length();
hp.type = CODEC_UTF8 | USING_STRING | NO_CONTEXT;
hp.offset = get_stack(1);
hp.filter_fun = [](void *data, size_t *len, HookParam *hp)
{
// 若当前还有5个字符则这个句子会显示5次然后substr(1,len-1)直到结束总共显示5+4+3+2+1次
auto ws = StringToWideString(std::string((char *)data, *len));
static int leng = 0;
if (ws.length() <= leng)
{
leng = ws.length();
return false;
}
leng=ws.length();
leng = ws.length();
return true;
};
return NewHook(hp, "AIRNovel");
}
bool AdobeAir::attach_function() {
bool b1= InsertAdobeAirHook();
b1|=AdobeAIRhook2();
b1|=adobelair3();
b1=b1||InsertAIRNovelHook();//乱码太多了这个
return b1;
}
bool AdobeAir::attach_function()
{
bool b1 = InsertAdobeAirHook();
b1 |= AdobeAIRhook2();
b1 |= adobelair3();
b1 = b1 || InsertAIRNovelHook(); // 乱码太多了这个
return b1;
}

View File

@ -1,13 +1,16 @@
class AdobeAir:public ENGINE{
public:
AdobeAir(){
check_by=CHECK_BY::CUSTOM;
check_by_target=[](){
return Util::CheckFile(L"Adobe AIR\\Versions\\1.0\\Adobe AIR.dll")||GetModuleHandle(L"Adobe AIR.dll")||Util::CheckFile(L"*.swf");
class AdobeAir : public ENGINE
{
public:
AdobeAir()
{
check_by = CHECK_BY::CUSTOM;
check_by_target = []()
{
return Util::CheckFile(L"Adobe AIR\\Versions\\1.0\\Adobe AIR.dll") || GetModuleHandle(L"Adobe AIR.dll") || Util::CheckFile(L"*.swf");
};
};
bool attach_function();
bool attach_function();
};

View File

@ -1,5 +1,4 @@
#include"AdobeFlash10.h"
#include "AdobeFlash10.h"
/** jichi 10/31/2014 Adobe Flash Player v10
*
@ -229,58 +228,61 @@ static bool AdobeFlashFilter(LPVOID data, size_t *size, HookParam *)
bool InsertAdobeFlash10Hook()
{
const BYTE bytes[] = {
0x8b,0x4c,0x24, 0x0c, // 01612940 8b4c24 0c mov ecx,dword ptr ss:[esp+0xc] ; jichi: hook here
0x53, // 01612944 53 push ebx
0x55, // 01612945 55 push ebp
0x56, // 01612946 56 push esi
0x57, // 01612947 57 push edi
0x33,0xff, // 01612948 33ff xor edi,edi
0x85,0xc9, // 0161294a 85c9 test ecx,ecx
0x0f,0x84 //, 5f010000 // 0161294c 0f84 5f010000 je ron2.01612ab1
0x8b, 0x4c, 0x24, 0x0c, // 01612940 8b4c24 0c mov ecx,dword ptr ss:[esp+0xc] ; jichi: hook here
0x53, // 01612944 53 push ebx
0x55, // 01612945 55 push ebp
0x56, // 01612946 56 push esi
0x57, // 01612947 57 push edi
0x33, 0xff, // 01612948 33ff xor edi,edi
0x85, 0xc9, // 0161294a 85c9 test ecx,ecx
0x0f, 0x84 //, 5f010000 // 0161294c 0f84 5f010000 je ron2.01612ab1
};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
//addr = 0x01612940;
//addr = 0x01612AC0;
if (!addr) {
// addr = 0x01612940;
// addr = 0x01612AC0;
if (!addr)
{
ConsoleOutput("AdobeFlash10: pattern not found");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
//hp.length_offset = 2 * 4; // arg2 might be the length
hp.type = CODEC_UTF16|USING_STRING;
hp.offset = get_stack(1);
// hp.length_offset = 2 * 4; // arg2 might be the length
hp.type = CODEC_UTF16 | USING_STRING;
hp.filter_fun = AdobeFlashFilter;
ConsoleOutput("INSERT Adobe Flash 10");
ConsoleOutput("AdobeFlash10: disable GDI hooks");
return NewHook(hp, "Adobe Flash 10");
}
namespace{
bool __(){
namespace
{
bool __()
{
//[yosino] ANCIENT
//https://ci-en.dlsite.com/creator/5059/
// https://ci-en.dlsite.com/creator/5059/
const BYTE bytes[] = {
0x55,0x8b,0xec,
0x51,0x51,0x8b,0x45,0x10,
0x53,0x8b,0xd9,0x89,0x43,0x08,
0x8a,0x45,0x0c
};
0x55, 0x8b, 0xec,
0x51, 0x51, 0x8b, 0x45, 0x10,
0x53, 0x8b, 0xd9, 0x89, 0x43, 0x08,
0x8a, 0x45, 0x0c};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr) return false;
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(4);
hp.type = CODEC_UTF16|USING_STRING;
hp.offset = get_stack(4);
hp.type = CODEC_UTF16 | USING_STRING;
return NewHook(hp, "Adobe Flash 11");
}
}
bool AdobeFlash10::attach_function() {
return InsertAdobeFlash10Hook()|__();
}
bool AdobeFlash10::attach_function()
{
return InsertAdobeFlash10Hook() | __();
}

View File

@ -1,11 +1,13 @@
class AdobeFlash10:public ENGINE{
public:
AdobeFlash10(){
check_by=CHECK_BY::RESOURCE_STR;
check_by_target=L"Adobe Flash Player 10";
class AdobeFlash10 : public ENGINE
{
public:
AdobeFlash10()
{
check_by = CHECK_BY::RESOURCE_STR;
check_by_target = L"Adobe Flash Player 10";
};
bool attach_function();
bool attach_function();
};

View File

@ -1,38 +1,41 @@
#include"Ages3ResT.h"
#include "Ages3ResT.h"
bool Ages3ResTHook() {
bool Ages3ResTHook()
{
const BYTE bytes[] = {
0x8d,0x4f,XX,
0xff,0x15,XX4,
XX,
0x8d,0x8f,XX4,
0xff,0x15,XX4,
0x8d,XX,XX4,
XX,
0x8d,0x8f,XX4,
0xff,0x15,XX4,
0x8b,XX,
0xff,0x15,XX4,
};
0x8d, 0x4f, XX,
0xff, 0x15, XX4,
XX,
0x8d, 0x8f, XX4,
0xff, 0x15, XX4,
0x8d, XX, XX4,
XX,
0x8d, 0x8f, XX4,
0xff, 0x15, XX4,
0x8b, XX,
0xff, 0x15, XX4};
auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress);
bool succ=false;
for (auto addr : addrs) {
bool succ = false;
for (auto addr : addrs)
{
ConsoleOutput("Ages3ResT %p", addr);
if (addr == 0)return false;
if (addr == 0)
return false;
addr = findfuncstart(addr);
ConsoleOutput("Ages3ResT %p", addr);
if (addr == 0)return false;
if (addr == 0)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(3);
hp.offset = get_stack(3);
hp.type = CODEC_UTF16 | USING_STRING;
succ|=NewHook(hp, "Ages3ResT");
succ |= NewHook(hp, "Ages3ResT");
}
return succ;
}
bool Ages3ResT::attach_function() {
return Ages3ResTHook();
}
bool Ages3ResT::attach_function()
{
return Ages3ResTHook();
}

View File

@ -1,11 +1,13 @@
class Ages3ResT:public ENGINE{
public:
Ages3ResT(){
check_by=CHECK_BY::FILE;
check_by_target=L"Ages3ResT.dll";
class Ages3ResT : public ENGINE
{
public:
Ages3ResT()
{
check_by = CHECK_BY::FILE;
check_by_target = L"Ages3ResT.dll";
};
bool attach_function();
bool attach_function();
};

View File

@ -1,62 +1,66 @@
#include"Aksys.h"
#include "Aksys.h"
namespace
{
bool _Aksys() {
//https://vndb.org/v25385
//Spirit Hunter: NG
/*
int __usercall sub_4CDD70@<eax>(const char *a1@<edx>, int a2, _DWORD *a3, int *a4)
bool _Aksys()
{
int result; // eax
const char *v6; // [esp+Ch] [ebp-8h] BYREF
*a3 = strlen(a1);
if ( *a1 && a2 )
// https://vndb.org/v25385
// Spirit Hunter: NG
/*
int __usercall sub_4CDD70@<eax>(const char *a1@<edx>, int a2, _DWORD *a3, int *a4)
{
v6 = a1;
if ( (unsigned __int8)sub_4CAEB0(&v6) )
int result; // eax
const char *v6; // [esp+Ch] [ebp-8h] BYREF
*a3 = strlen(a1);
if ( *a1 && a2 )
{
*a4 = sub_4CAF70(0, 0, 0x3A4u, (const unsigned __int16 *)a1, 0xFDE9u);
return 0;
v6 = a1;
if ( (unsigned __int8)sub_4CAEB0(&v6) )
{
*a4 = sub_4CAF70(0, 0, 0x3A4u, (const unsigned __int16 *)a1, 0xFDE9u);
return 0;
}
else
{
return -2141454316;
}
}
else
{
return -2141454316;
result = 0;
*a4 = 0;
}
return result;
}
else
*/
BYTE bytes[] = {
0x68, 0xe9, 0xfd, 0, 0,
0x56,
0x68, 0xa4, 0x03, 0, 0,
0x33, XX,
0x33, XX,
0xe8};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;
addr = findfuncstart(addr);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset = get_reg(regs::edx);
hp.split = get_reg(regs::edx);
hp.type = USING_STRING | USING_SPLIT;
hp.filter_fun = [](LPVOID data, size_t *size, HookParam *)
{
result = 0;
*a4 = 0;
}
return result;
StringFilter((char *)data, size, "@1r", 3);
StringFilter((char *)data, size, "@-1r", 4);
return (StringToWideString(std::string((char *)data, *size), 932).has_value());
};
return NewHook(hp, "Aksys");
}
*/
BYTE bytes[] = {
0x68,0xe9,0xfd,0,0,
0x56,
0x68,0xa4,0x03,0,0,
0x33,XX,
0x33,XX,
0xe8
};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr) return false;
addr = findfuncstart(addr);
if (!addr) return false;
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::edx);
hp.split=get_reg(regs::edx);
hp.type = USING_STRING|USING_SPLIT;
hp.filter_fun = [](LPVOID data, size_t* size, HookParam*) {
StringFilter((char*)data, size, "@1r", 3);
StringFilter((char*)data, size, "@-1r", 4);
return (StringToWideString(std::string((char*)data,*size),932).has_value());
};
return NewHook(hp, "Aksys");
}
}
bool Aksys::attach_function() {
return _Aksys();
}
bool Aksys::attach_function()
{
return _Aksys();
}

View File

@ -1,12 +1,14 @@
class Aksys:public ENGINE{
public:
Aksys(){
check_by=CHECK_BY::FILE;
check_by_target=L"System.bra";
is_engine_certain=false;
class Aksys : public ENGINE
{
public:
Aksys()
{
check_by = CHECK_BY::FILE;
check_by_target = L"System.bra";
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -41,7 +41,6 @@ bool AksysGames::attach_function()
.text:004BCB9E cmp cl, 0FCh
.text:004BCBA1 ja short loc_4BCBC3
*/
//clang-format off
0x8a, 0x08,
0x80, 0xf9, 0x80,
0x0f, 0x84, XX4,
@ -58,9 +57,7 @@ bool AksysGames::attach_function()
0x80, 0xf9, 0xe0,
0x72, XX,
0x80, 0xf9, 0xfc,
0x77, XX,
//clang-format on
};
0x77, XX};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);

View File

@ -31,12 +31,12 @@ FILESUBTYPE 0x0
class AksysGames : public ENGINE
{
public:
AksysGames()
{
AksysGames()
{
check_by = CHECK_BY::RESOURCE_STR;
check_by_target = L"Aksys Games";
is_engine_certain = false;
};
bool attach_function();
check_by = CHECK_BY::RESOURCE_STR;
check_by_target = L"Aksys Games";
is_engine_certain = false;
};
bool attach_function();
};

View File

@ -1,6 +1,4 @@
#include"Alice.h"
#include "Alice.h"
/********************************************************************************************
System40 hook:
@ -31,48 +29,52 @@ System40 hook:
static bool InsertAliceHook1(DWORD addr)
{
if (!addr) {
if (!addr)
{
ConsoleOutput("AliceHook1: failed");
return false;
}
for (DWORD i = addr, s = addr; i < s + 0x100; i++)
if (*(BYTE *)i == 0xe8) { // Find the first relative call.
if (*(BYTE *)i == 0xe8)
{ // Find the first relative call.
DWORD j = i + 5 + *(DWORD *)(i + 1);
while (true) { // Find the first register push onto stack.
DWORD c = ::disasm((BYTE *)s);
if (c == 1)
break;
s += c;
}
DWORD c = *(BYTE *)s;
HookParam hp;
hp.address = j;
hp.offset=get_reg(regs::eax);
hp.split = -8 -((c & 0xf) << 2);
hp.type = USING_STRING|USING_SPLIT;
//if (s>j) hp.type^=USING_SPLIT;
ConsoleOutput("INSERT AliceHook1");
//RegisterEngineType(ENGINE_SYS40);
return NewHook(hp, "System40");
while (true)
{ // Find the first register push onto stack.
DWORD c = ::disasm((BYTE *)s);
if (c == 1)
break;
s += c;
}
DWORD c = *(BYTE *)s;
HookParam hp;
hp.address = j;
hp.offset = get_reg(regs::eax);
hp.split = -8 - ((c & 0xf) << 2);
hp.type = USING_STRING | USING_SPLIT;
// if (s>j) hp.type^=USING_SPLIT;
ConsoleOutput("INSERT AliceHook1");
// RegisterEngineType(ENGINE_SYS40);
return NewHook(hp, "System40");
}
ConsoleOutput("AliceHook1: failed");
return false;
}
static bool InsertAliceHook2(DWORD addr)
{
if (!addr) {
if (!addr)
{
ConsoleOutput("AliceHook2: failed");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::eax);
hp.offset = get_reg(regs::eax);
hp.index = 0x8;
hp.type = DATA_INDIRECT;
ConsoleOutput("INSERT AliceHook2");
return NewHook(hp, "System40");
//RegisterEngineType(ENGINE_SYS40);
// RegisterEngineType(ENGINE_SYS40);
}
// jichi 8/23/2013 Move here from engine.cc
@ -80,25 +82,27 @@ static bool InsertAliceHook2(DWORD addr)
// jichi 5/13/2015: Looking for function entries in StoatSpriteEngine.dll
bool InsertAliceHook()
{
bool ok=false;
if (auto addr = Util::FindFunction("SP_TextDraw")) {
ok|= InsertAliceHook1(addr);
bool ok = false;
if (auto addr = Util::FindFunction("SP_TextDraw"))
{
ok |= InsertAliceHook1(addr);
}
//if (GetFunctionAddr("SP_SetTextSprite", &addr, &low, &high, 0) && addr) {
// InsertAliceHook2(addr);
// return true;
// if (GetFunctionAddr("SP_SetTextSprite", &addr, &low, &high, 0) && addr) {
// InsertAliceHook2(addr);
// return true;
//}
if (auto addr = Util::FindFunction("SP_SetTextSprite")) { // Artikash 6/27/2018 not sure if this works
ok|= InsertAliceHook2(addr);
if (auto addr = Util::FindFunction("SP_SetTextSprite"))
{ // Artikash 6/27/2018 not sure if this works
ok |= InsertAliceHook2(addr);
}
//ConsoleOutput("AliceHook: failed");
// ConsoleOutput("AliceHook: failed");
return ok;
}
bool Alice::attach_function()
{
bool Alice::attach_function() {
return InsertAliceHook();
}
return InsertAliceHook();
}

View File

@ -1,10 +1,12 @@
class Alice:public ENGINE{
public:
Alice(){
check_by=CHECK_BY::ALL_TRUE;
class Alice : public ENGINE
{
public:
Alice()
{
check_by = CHECK_BY::ALL_TRUE;
};
bool attach_function();
bool attach_function();
};

View File

@ -1,100 +1,105 @@
#include"Anex86.h"
#include "Anex86.h"
namespace
{ // unnamed, for Anex86
BYTE JIS_tableH[0x80] = {
0x00, 0x81, 0x81, 0x82, 0x82, 0x83, 0x83, 0x84,
0x84, 0x85, 0x85, 0x86, 0x86, 0x87, 0x87, 0x88,
0x88, 0x89, 0x89, 0x8a, 0x8a, 0x8b, 0x8b, 0x8c,
0x8c, 0x8d, 0x8d, 0x8e, 0x8e, 0x8f, 0x8f, 0x90,
0x90, 0x91, 0x91, 0x92, 0x92, 0x93, 0x93, 0x94,
0x94, 0x95, 0x95, 0x96, 0x96, 0x97, 0x97, 0x98,
0x98, 0x99, 0x99, 0x9a, 0x9a, 0x9b, 0x9b, 0x9c,
0x9c, 0x9d, 0x9d, 0x9e, 0x9e, 0xdf, 0xdf, 0xe0,
0xe0, 0xe1, 0xe1, 0xe2, 0xe2, 0xe3, 0xe3, 0xe4,
0xe4, 0xe5, 0xe5, 0xe6, 0xe6, 0xe7, 0xe7, 0xe8,
0xe8, 0xe9, 0xe9, 0xea, 0xea, 0xeb, 0xeb, 0xec,
0xec, 0xed, 0xed, 0xee, 0xee, 0xef, 0xef, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
BYTE JIS_tableL[0x80] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e,
0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56,
0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e,
0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e,
0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x00};
namespace { // unnamed, for Anex86
BYTE JIS_tableH[0x80] = {
0x00,0x81,0x81,0x82,0x82,0x83,0x83,0x84,
0x84,0x85,0x85,0x86,0x86,0x87,0x87,0x88,
0x88,0x89,0x89,0x8a,0x8a,0x8b,0x8b,0x8c,
0x8c,0x8d,0x8d,0x8e,0x8e,0x8f,0x8f,0x90,
0x90,0x91,0x91,0x92,0x92,0x93,0x93,0x94,
0x94,0x95,0x95,0x96,0x96,0x97,0x97,0x98,
0x98,0x99,0x99,0x9a,0x9a,0x9b,0x9b,0x9c,
0x9c,0x9d,0x9d,0x9e,0x9e,0xdf,0xdf,0xe0,
0xe0,0xe1,0xe1,0xe2,0xe2,0xe3,0xe3,0xe4,
0xe4,0xe5,0xe5,0xe6,0xe6,0xe7,0xe7,0xe8,
0xe8,0xe9,0xe9,0xea,0xea,0xeb,0xeb,0xec,
0xec,0xed,0xed,0xee,0xee,0xef,0xef,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
void SpecialHookAnex86(hook_stack *stack, HookParam *, uintptr_t *data, uintptr_t *split, size_t *len)
{
auto ecx = stack->ecx;
if (*(BYTE *)(ecx + 0xe) != 0)
return;
auto lb = *(BYTE *)(ecx + 0xc);
auto hb = *(BYTE *)(ecx + 0xd);
if (hb == 0)
{
*data = lb;
*len = 1;
}
else
{
if (hb <= 0x7e && lb <= 0x7e)
{
BYTE JIS_tableL[0x80] = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,
0x4f,0x50,0x51,0x52,0x53,0x54,0x55,0x56,
0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,
0x5f,0x60,0x61,0x62,0x63,0x64,0x65,0x66,
0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,
0x6f,0x70,0x71,0x72,0x73,0x74,0x75,0x76,
0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x00,
};
void SpecialHookAnex86(hook_stack* stack, HookParam*, uintptr_t *data, uintptr_t *split, size_t *len)
{
auto ecx=stack->ecx;
if(*(BYTE*)(ecx+0xe)!=0)return;
auto lb=*(BYTE*)(ecx+0xc);
auto hb=*(BYTE*)(ecx+0xd);
if(hb==0){
*data=lb;
*len=1;
}
else{
if(hb<=0x7e&&lb<=0x7e){
*len=2;
BYTE low;
if ((hb & 1)== 0)
*len = 2;
BYTE low;
if ((hb & 1) == 0)
low = lb + 0x7E;
else
else
low = JIS_tableL[lb];
auto chr=low|(JIS_tableH[hb]<<8);
*data=_byteswap_ushort(chr);
auto chr = low | (JIS_tableH[hb] << 8);
*data = _byteswap_ushort(chr);
}
}
}
}
} // unnamed namespace
bool InsertAnex86Hook()
{
const BYTE bytes[] = {
0x8a, XX, 0x0c, // mov ??,[ecx+0C]
0x8a, XX, 0x0d // mov ??,[ecx+0D]
};
bool found = false;
for (auto addr : Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress)) {
//const DWORD dwords[] = {0x618ac033,0x0d418a0c}; // jichi 12/25/2013: Remove static keyword
//for (DWORD i = processStartAddress + 0x1000; i < processStopAddress - 8; i++)
//if (*(DWORD *)i == dwords[0])
//if (*(DWORD *)(i + 4) == dwords[1]) {
HookParam hp;
if (*(BYTE*)(addr - 2) == 0x33 || *(BYTE*)(addr - 2) == 0x31) addr = addr - 2;
hp.address = addr;
hp.offset=get_reg(regs::ecx);
hp.type=USING_CHAR;
hp.text_fun = SpecialHookAnex86;
//hp.type = EXTERN_HOOK;
ConsoleOutput("INSERT Anex86");
found |=NewHook(hp, "Anex86");
}
if (found) return true;
const BYTE bytes[] = {
0x8a, XX, 0x0c, // mov ??,[ecx+0C]
0x8a, XX, 0x0d // mov ??,[ecx+0D]
};
bool found = false;
for (auto addr : Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress))
{
// const DWORD dwords[] = {0x618ac033,0x0d418a0c}; // jichi 12/25/2013: Remove static keyword
// for (DWORD i = processStartAddress + 0x1000; i < processStopAddress - 8; i++)
// if (*(DWORD *)i == dwords[0])
// if (*(DWORD *)(i + 4) == dwords[1]) {
HookParam hp;
if (*(BYTE *)(addr - 2) == 0x33 || *(BYTE *)(addr - 2) == 0x31)
addr = addr - 2;
hp.address = addr;
hp.offset = get_reg(regs::ecx);
hp.type = USING_CHAR;
hp.text_fun = SpecialHookAnex86;
// hp.type = EXTERN_HOOK;
ConsoleOutput("INSERT Anex86");
found |= NewHook(hp, "Anex86");
}
if (found)
return true;
ConsoleOutput("Anex86: failed");
return false;
}
bool Anex86::attach_function() {
return InsertAnex86Hook();
}
bool Anex86::attach_function()
{
return InsertAnex86Hook();
}

View File

@ -1,14 +1,16 @@
class Anex86:public ENGINE{
public:
Anex86(){
check_by=CHECK_BY::CUSTOM;
check_by_target=[](){
class Anex86 : public ENGINE
{
public:
Anex86()
{
check_by = CHECK_BY::CUSTOM;
check_by_target = []()
{
return (wcsstr(processName_lower, L"anex86") || Util::CheckFile(L"anex86.exe"));
};
};
bool attach_function();
bool attach_function();
};

View File

@ -1,106 +1,113 @@
#include"Anim.h"
#include "Anim.h"
bool InsertAnimHook() {
const BYTE bytes[] = { 0xC7,0x45,0xFC,0x01,0x00,0x00,0x00,0x8B,0x4D,0x10,0x51,0x8D,0x8D,0x40,0x7E,0xFF,0xFF };
bool InsertAnimHook()
{
const BYTE bytes[] = {0xC7, 0x45, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x8B, 0x4D, 0x10, 0x51, 0x8D, 0x8D, 0x40, 0x7E, 0xFF, 0xFF};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Anim: pattern not found");
return false;
}
HookParam myhp;
myhp.address = addr+10;
myhp.address = addr + 10;
myhp.type = USING_STRING| NO_CONTEXT|EMBED_ABLE|EMBED_AFTER_OVERWRITE|EMBED_BEFORE_SIMPLE|EMBED_DYNA_SJIS; // /HQ 不使用上下文区分 把所有线程的文本都提取
myhp.hook_font=F_GetGlyphOutlineA;
myhp.type = USING_STRING | NO_CONTEXT | EMBED_ABLE | EMBED_AFTER_OVERWRITE | EMBED_BEFORE_SIMPLE | EMBED_DYNA_SJIS; // /HQ 不使用上下文区分 把所有线程的文本都提取
myhp.hook_font = F_GetGlyphOutlineA;
// data_offset
myhp.offset=get_reg(regs::ecx);
myhp.offset = get_reg(regs::ecx);
char nameForUser[HOOK_NAME_SIZE] = "Anim";
return NewHook(myhp, nameForUser);
}
bool InsertAnim2Hook() {
const BYTE bytes[] = { 0xC7,0x45,0xFC,0x01,0x00,0x00,0x00,0x8B,0x45,0x10,0x50,0x8D,0x8D,0xAC,0x7E,0xFF,0xFF };
bool InsertAnim2Hook()
{
const BYTE bytes[] = {0xC7, 0x45, 0xFC, 0x01, 0x00, 0x00, 0x00, 0x8B, 0x45, 0x10, 0x50, 0x8D, 0x8D, 0xAC, 0x7E, 0xFF, 0xFF};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Anim2: pattern not found");
return false;
}
HookParam myhp;
myhp.address = addr + 10;
myhp.hook_font=F_GetGlyphOutlineA;
//メスつまみ3
//そんな俺に声をかけてきたのは、近所のスーパーで働いている主婦の、@n『@[赤羽:あかばね]@[千晶:ちあき]』さんだ。
myhp.filter_fun=[](void* data, size_t* len, HookParam* hp){
myhp.hook_font = F_GetGlyphOutlineA;
// メスつまみ3
// そんな俺に声をかけてきたのは、近所のスーパーで働いている主婦の、@n『@[赤羽:あかばね]@[千晶:ちあき]』さんだ。
myhp.filter_fun = [](void *data, size_t *len, HookParam *hp)
{
static const std::regex rx("@\\[(.*?):(.*?)\\]", std::regex_constants::icase);
std::string result = std::string((char*)data,*len);
std::string result = std::string((char *)data, *len);
result = std::regex_replace(result, rx, "$1");
return write_string_overwrite(data,len,result);
return write_string_overwrite(data, len, result);
};
myhp.newlineseperator=L"@n";
myhp.type = USING_STRING | NO_CONTEXT|EMBED_ABLE|EMBED_AFTER_OVERWRITE|EMBED_BEFORE_SIMPLE|EMBED_DYNA_SJIS;
//僕がいない間に変貌えられた妻の秘肉 ~ラブラブ新婚妻は他の男に抱かれ淫らに喘ぐ夢を見るか~ 体験版
myhp.newlineseperator = L"@n";
myhp.type = USING_STRING | NO_CONTEXT | EMBED_ABLE | EMBED_AFTER_OVERWRITE | EMBED_BEFORE_SIMPLE | EMBED_DYNA_SJIS;
// 僕がいない間に変貌えられた妻の秘肉 ~ラブラブ新婚妻は他の男に抱かれ淫らに喘ぐ夢を見るか~ 体験版
// data_offset
myhp.offset=get_reg(regs::eax);
myhp.offset = get_reg(regs::eax);
return NewHook(myhp, "Anim2");
}
namespace{
namespace
{
bool Anim3Filter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
StringFilterBetween(text, len, "\x81\x40", 2, "@m", 2); // @r(2,はと)
StringFilterBetween(text, len, "\x81\x40", 2, "@n", 2); // @r(2,はと)
StringCharReplacer(text, len, "@b", 2, ' ');
StringCharReplacer(text, len, "\x81\x42", 2, '.');
StringCharReplacer(text, len, "\x81\x48", 2, '?');
StringCharReplacer(text, len, "\x81\x49", 2, '!');
StringFilterBetween(text, len, "\x81\x40", 2, "@m", 2); // @r(2,はと)
StringFilterBetween(text, len, "\x81\x40", 2, "@n", 2); // @r(2,はと)
StringCharReplacer(text, len, "@b", 2, ' ');
StringCharReplacer(text, len, "\x81\x42", 2, '.');
StringCharReplacer(text, len, "\x81\x48", 2, '?');
StringCharReplacer(text, len, "\x81\x49", 2, '!');
return true;
return true;
}
bool InsertAnim3Hook()
{
/*
* Sample games:
* https://vndb.org/v17427
* https://vndb.org/v18837
*/
const BYTE bytes[] = {
0xCC, // int 3
0x55, // push ebp << hook here
0x8B, 0xEC, // mov ebp,esp
0x81, 0xEC, XX4, // sub esp,00000830
0xA1, XX4, // mov eax,[musu_mama.exe+A91F0]
0x33, 0xC5, // xor eax,ebp
0x89, 0x45, 0xE8 // mov [ebp-18],eax
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
ConsoleOutput("Anim3: pattern not found");
return false;
}
/*
* Sample games:
* https://vndb.org/v17427
* https://vndb.org/v18837
*/
const BYTE bytes[] = {
0xCC, // int 3
0x55, // push ebp << hook here
0x8B, 0xEC, // mov ebp,esp
0x81, 0xEC, XX4, // sub esp,00000830
0xA1, XX4, // mov eax,[musu_mama.exe+A91F0]
0x33, 0xC5, // xor eax,ebp
0x89, 0x45, 0xE8 // mov [ebp-18],eax
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr)
{
ConsoleOutput("Anim3: pattern not found");
return false;
}
HookParam hp;
hp.address = addr + 1;
hp.offset=get_reg(regs::edx);
hp.type = USING_STRING;
hp.filter_fun = Anim3Filter;
ConsoleOutput("INSERT Anim3");
HookParam hp;
hp.address = addr + 1;
hp.offset = get_reg(regs::edx);
hp.type = USING_STRING;
hp.filter_fun = Anim3Filter;
ConsoleOutput("INSERT Anim3");
return NewHook(hp, "Anim3");
return NewHook(hp, "Anim3");
}
}
bool Anim::attach_function() {
auto b1= InsertAnimHook() || InsertAnim2Hook();
b1=InsertAnim3Hook()||b1;
bool Anim::attach_function()
{
auto b1 = InsertAnimHook() || InsertAnim2Hook();
b1 = InsertAnim3Hook() || b1;
return b1;
}
}

View File

@ -1,12 +1,14 @@
class Anim:public ENGINE{
public:
Anim(){
check_by=CHECK_BY::FILE;
check_by_target=L"voice\\*.pck";
is_engine_certain=false;
class Anim : public ENGINE
{
public:
Anim()
{
check_by = CHECK_BY::FILE;
check_by_target = L"voice\\*.pck";
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -1,23 +1,24 @@
#include"Anisetta.h"
bool Anisetta::attach_function() {
//https://vndb.org/v4068
//12+
const BYTE bytes[] = {
0xF7 ,0xD8,
0x1B ,0xC0,
0x25 ,0x58 ,0x02 ,0x00 ,0x00,
0x05 ,0x90 ,0x01 ,0x00 ,0x00,
};
auto addr=MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if(addr==0)return false;
addr=MemDbg::findEnclosingAlignedFunction(addr);
if(addr==0)return false;
#include "Anisetta.h"
bool Anisetta::attach_function()
{
// https://vndb.org/v4068
// 12+
const BYTE bytes[] = {
0xF7, 0xD8,
0x1B, 0xC0,
0x25, 0x58, 0x02, 0x00, 0x00,
0x05, 0x90, 0x01, 0x00, 0x00};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (addr == 0)
return false;
addr = MemDbg::findEnclosingAlignedFunction(addr);
if (addr == 0)
return false;
HookParam hp;
hp.address = addr ;
hp.address = addr;
hp.type = CODEC_ANSI_BE;
hp.offset=get_stack(5);
return NewHook(hp, "Anisetta");
}
hp.offset = get_stack(5);
return NewHook(hp, "Anisetta");
}

View File

@ -1,12 +1,14 @@
class Anisetta:public ENGINE{
public:
Anisetta(){
check_by=CHECK_BY::FILE_ANY;
check_by_target=check_by_list{L"*.pd",L".pb"};
is_engine_certain=false;
class Anisetta : public ENGINE
{
public:
Anisetta()
{
check_by = CHECK_BY::FILE_ANY;
check_by_target = check_by_list{L"*.pd", L".pb"};
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -1,4 +1,4 @@
#include"ApricoT.h"
#include "ApricoT.h"
/********************************************************************************************
Apricot hook:
@ -63,7 +63,7 @@ Apricot hook:
* 001aec68 ffffffff
* 001aec6c 00cb9f40 return to .00cb9f40 from .00cc8030 ; jichi: split here
*/
static void SpecialHookApricoT(hook_stack* stack, HookParam *, uintptr_t *data, uintptr_t *split, size_t *len)
static void SpecialHookApricoT(hook_stack *stack, HookParam *, uintptr_t *data, uintptr_t *split, size_t *len)
{
DWORD reg_esi = stack->esi;
DWORD base = *(DWORD *)(reg_esi + 0x24);
@ -71,48 +71,60 @@ static void SpecialHookApricoT(hook_stack* stack, HookParam *, uintptr_t *data,
DWORD *script = (DWORD *)(base + index * 4);
// jichi 2/14/2015
// Change reg_esp to the return address
//DWORD reg_esp = regof(esp, esp_base);
// DWORD reg_esp = regof(esp, esp_base);
//*split = reg_esp;
//*split = regof(esp, esp_base);
DWORD arg = stack->stack[16]; // return address
DWORD arg = stack->stack[16]; // return address
*split = arg > processStartAddress ? arg - processStartAddress : arg; // use relative split value
//*split = argof(1, esp_base);
if (script[0] == L'<') {
if (script[0] == L'<')
{
DWORD *end;
for (end = script; *end != L'>'; end++); // jichi 2/14/2015: i.e. = ::wcschr(script) or script
switch (script[1]) {
for (end = script; *end != L'>'; end++)
; // jichi 2/14/2015: i.e. = ::wcschr(script) or script
switch (script[1])
{
case L'N':
if (script[2] == L'a' && script[3] == L'm' && script[4] == L'e') {
if (script[2] == L'a' && script[3] == L'm' && script[4] == L'e')
{
buffer_index = 0;
for (script += 5; script < end; script++)
if (*script > 0x20)
wc_buffer[buffer_index++] = *script & 0xFFFF;
*len = buffer_index<<1;
*len = buffer_index << 1;
*data = (DWORD)wc_buffer;
// jichi 1/4/2014: The way I save subconext is not able to distinguish the split value
// Change to shift 16
//*split |= 1 << 31;
*split |= 1 << 16; // jichi: differentiate name and text script
} break;
}
break;
case L'T':
if (script[2] == L'e' && script[3] == L'x' && script[4] == L't') {
if (script[2] == L'e' && script[3] == L'x' && script[4] == L't')
{
buffer_index = 0;
for (script += 5; script < end; script++) {
if (*script > 0x40) {
while (*script == L'{') {
for (script += 5; script < end; script++)
{
if (*script > 0x40)
{
while (*script == L'{')
{
script++;
while (*script!=L'\\') {
while (*script != L'\\')
{
wc_buffer[buffer_index++] = *script & 0xffff;
script++;
}
while (*script++!=L'}');
while (*script++ != L'}')
;
}
wc_buffer[buffer_index++] = *script & 0xffff;
}
}
*len = buffer_index << 1;
*data = (DWORD)wc_buffer;
} break;
}
break;
}
}
}
@ -120,20 +132,21 @@ static void SpecialHookApricoT(hook_stack* stack, HookParam *, uintptr_t *data,
bool InsertApricoTHook()
{
for (DWORD i = processStartAddress + 0x1000; i < processStopAddress - 4; i++)
if ((*(DWORD *)i & 0xfff8fc) == 0x3cf880) // cmp reg,0x3c
if ((*(DWORD *)i & 0xfff8fc) == 0x3cf880) // cmp reg,0x3c
for (DWORD j = i + 3, k = i + 0x100; j < k; j++)
if ((*(DWORD *)j & 0xffffff) == 0x4c2) { // retn 4
if ((*(DWORD *)j & 0xffffff) == 0x4c2)
{ // retn 4
HookParam hp;
hp.address = j + 3;
hp.text_fun = SpecialHookApricoT;
hp.type = USING_STRING|NO_CONTEXT|CODEC_UTF16;
hp.type = USING_STRING | NO_CONTEXT | CODEC_UTF16;
ConsoleOutput("INSERT ApricoT");
//GROWL_DWORD3(hp.address, processStartAddress, processStopAddress);
//RegisterEngineType(ENGINE_APRICOT);
// jichi 2/14/2015: disable cached GDI functions
// GROWL_DWORD3(hp.address, processStartAddress, processStopAddress);
// RegisterEngineType(ENGINE_APRICOT);
// jichi 2/14/2015: disable cached GDI functions
ConsoleOutput("ApRicoT: disable GDI hooks");
return NewHook(hp, "ApRicoT");
}
@ -141,7 +154,8 @@ bool InsertApricoTHook()
return false;
}
bool ApricoT::attach_function() {
return InsertApricoTHook();
}
bool ApricoT::attach_function()
{
return InsertApricoTHook();
}

View File

@ -1,21 +1,25 @@
class ApricoT:public ENGINE{
public:
ApricoT(){
check_by=CHECK_BY::FILE;
check_by_target=L"arc.a*";
class ApricoT : public ENGINE
{
public:
ApricoT()
{
check_by = CHECK_BY::FILE;
check_by_target = L"arc.a*";
};
bool attach_function();
bool attach_function();
};
class ApricoTlast:public ApricoT{
public:
ApricoTlast(){
check_by=CHECK_BY::FILE;
check_by_target=L"arc.dat";
is_engine_certain=false;
};
class ApricoTlast : public ApricoT
{
public:
ApricoTlast()
{
check_by = CHECK_BY::FILE;
check_by_target = L"arc.dat";
is_engine_certain = false;
};
};

View File

@ -1,4 +1,4 @@
#include"Artemis.h"
#include "Artemis.h"
/**
* jichi 10/1/2013: Artemis Engine
@ -59,180 +59,203 @@
bool InsertArtemis1Hook()
{
const BYTE bytes[] = {
0x83,0xc4, 0x0c, // add esp,0xc ; hook here
0x0f,0xb6,0xc0, // movzx eax,al
0x85,0xc0, // test eax,eax
0x75, 0x0e // jnz XXOO ; it must be 0xe, or there will be duplication
0x83, 0xc4, 0x0c, // add esp,0xc ; hook here
0x0f, 0xb6, 0xc0, // movzx eax,al
0x85, 0xc0, // test eax,eax
0x75, 0x0e // jnz XXOO ; it must be 0xe, or there will be duplication
};
//enum { addr_offset = 0 };
// enum { addr_offset = 0 };
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
//GROWL_DWORD3(reladdr, processStartAddress, range);
if (!addr) {
// GROWL_DWORD3(reladdr, processStartAddress, range);
if (!addr)
{
ConsoleOutput("Artemis1: pattern not exist");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::ecx);
hp.offset = get_reg(regs::ecx);
hp.split = get_stack(5);
hp.type = NO_CONTEXT|DATA_INDIRECT|USING_SPLIT; // 0x418
hp.type = NO_CONTEXT | DATA_INDIRECT | USING_SPLIT; // 0x418
//hp.address = 0x650a2f;
//GROWL_DWORD(hp.address);
// hp.address = 0x650a2f;
// GROWL_DWORD(hp.address);
ConsoleOutput("INSERT Artemis1");
//ConsoleOutput("Artemis1");
// ConsoleOutput("Artemis1");
return NewHook(hp, "Artemis1");
}
bool InsertArtemis2Hook()
{
const BYTE bytes[] = {
// 0054461F | CC | int3 |
0x55, // 00544620 | 55 | push ebp |
0x8B, 0xEC, // 00544621 | 8B EC | mov ebp,esp |
0x83, 0xE4, 0xF8, // 00544623 | 83 E4 F8 | and esp,FFFFFFF8 |
0x6A, 0xFF, // 00544626 | 6A FF | push FFFFFFFF |
0x68, XX4, // 00544628 | 68 68 7C 6A 00 | push 空のつくりかた体験版_ver3.0.6A7C68 |
0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, // 0054462D | 64 A1 00 00 00 00 | mov eax,dword ptr fs:[0] |
0x50, // 00544633 | 50 | push eax |
0x83, 0xEC, XX, // 00544634 | 83 EC 28 | sub esp,28 |
0xA1, XX4, // 00544637 | A1 F0 57 81 00 | mov eax,dword ptr ds:[8157F0] |
0x33, 0xC4, // 0054463C | 33 C4 | xor eax,esp |
0x89, 0x44, 0x24, XX, // 0054463E | 89 44 24 20 | mov dword ptr ss:[esp+20],eax |
0x53, // 00544642 | 53 | push ebx |
0x56, // 00544643 | 56 | push esi |
0x57, // 00544644 | 57 | push edi |
0xA1, XX4, // 00544645 | A1 F0 57 81 00 | mov eax,dword ptr ds:[8157F0] |
0x33, 0xC4, // 0054464A | 33 C4 | xor eax,esp |
0x50, // 0054464C | 50 | push eax |
0x8D, 0x44, 0x24, XX, // 0054464D | 8D 44 24 38 | lea eax,dword ptr ss:[esp+38] | [esp+38]:BaseThreadInitThunk
0x64, 0xA3, 0x00, 0x00, 0x00, 0x00, // 00544651 | 64 A3 00 00 00 00 | mov dword ptr fs:[0],eax |
0x8B, 0xF1, // 00544657 | 8B F1 | mov esi,ecx |
0x8B, 0x5D, 0x08, // 00544659 | 8B 5D 08 | mov ebx,dword ptr ss:[ebp+8] |
0x8B, 0x4D, 0x0C // 0054465C | 8B 4D 0C | mov ecx,dword ptr ss:[ebp+C] | ecx:DbgUiRemoteBreakin, [ebp+C]:BaseThreadInitThunk
// 0054461F | CC | int3 |
0x55, // 00544620 | 55 | push ebp |
0x8B, 0xEC, // 00544621 | 8B EC | mov ebp,esp |
0x83, 0xE4, 0xF8, // 00544623 | 83 E4 F8 | and esp,FFFFFFF8 |
0x6A, 0xFF, // 00544626 | 6A FF | push FFFFFFFF |
0x68, XX4, // 00544628 | 68 68 7C 6A 00 | push 空のつくりかた体験版_ver3.0.6A7C68 |
0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, // 0054462D | 64 A1 00 00 00 00 | mov eax,dword ptr fs:[0] |
0x50, // 00544633 | 50 | push eax |
0x83, 0xEC, XX, // 00544634 | 83 EC 28 | sub esp,28 |
0xA1, XX4, // 00544637 | A1 F0 57 81 00 | mov eax,dword ptr ds:[8157F0] |
0x33, 0xC4, // 0054463C | 33 C4 | xor eax,esp |
0x89, 0x44, 0x24, XX, // 0054463E | 89 44 24 20 | mov dword ptr ss:[esp+20],eax |
0x53, // 00544642 | 53 | push ebx |
0x56, // 00544643 | 56 | push esi |
0x57, // 00544644 | 57 | push edi |
0xA1, XX4, // 00544645 | A1 F0 57 81 00 | mov eax,dword ptr ds:[8157F0] |
0x33, 0xC4, // 0054464A | 33 C4 | xor eax,esp |
0x50, // 0054464C | 50 | push eax |
0x8D, 0x44, 0x24, XX, // 0054464D | 8D 44 24 38 | lea eax,dword ptr ss:[esp+38] | [esp+38]:BaseThreadInitThunk
0x64, 0xA3, 0x00, 0x00, 0x00, 0x00, // 00544651 | 64 A3 00 00 00 00 | mov dword ptr fs:[0],eax |
0x8B, 0xF1, // 00544657 | 8B F1 | mov esi,ecx |
0x8B, 0x5D, 0x08, // 00544659 | 8B 5D 08 | mov ebx,dword ptr ss:[ebp+8] |
0x8B, 0x4D, 0x0C // 0054465C | 8B 4D 0C | mov ecx,dword ptr ss:[ebp+C] | ecx:DbgUiRemoteBreakin, [ebp+C]:BaseThreadInitThunk
};
enum { addr_offset = 0 }; // distance to the beginning of the function, which is 0x55 (push ebp)
enum
{
addr_offset = 0
}; // distance to the beginning of the function, which is 0x55 (push ebp)
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Artemis2: pattern not found");
return false;
}
addr += addr_offset;
enum { push_ebp = 0x55 }; // beginning of the function
if (*(BYTE *)addr != push_ebp) {
enum
{
push_ebp = 0x55
}; // beginning of the function
if (*(BYTE *)addr != push_ebp)
{
ConsoleOutput("Artemis2: beginning of the function not found");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.type = USING_STRING|NO_CONTEXT;
hp.offset = get_stack(1);
hp.type = USING_STRING | NO_CONTEXT;
ConsoleOutput("INSERT Artemis2");
bool succ=NewHook(hp, "Artemis2");
bool succ = NewHook(hp, "Artemis2");
// Artikash 1/1/2019: Recent games seem to use utf8 encoding instead, other than that the hook is identical.
// Not sure how to differentiate which games are sjis/utf8 so insert both
hp.address = addr + 6;
hp.offset=get_reg(regs::ebp);
hp.offset = get_reg(regs::ebp);
hp.index = 8; // ebp was also pushed
hp.type = CODEC_UTF8 | USING_STRING | DATA_INDIRECT ;
succ|=NewHook(hp, "Artemis2");
//ConsoleOutput("Artemis2");
hp.type = CODEC_UTF8 | USING_STRING | DATA_INDIRECT;
succ |= NewHook(hp, "Artemis2");
// ConsoleOutput("Artemis2");
return succ;
}
bool InsertArtemis3Hook()
{
const BYTE bytes[] = {
0x55, // 005FD780 | 55 | push ebp |
0x8B, 0xEC, // 005FD781 | 8BEC | mov ebp,esp |
0x83, 0xE4, 0xF8, // 005FD783 | 83E4 F8 | and esp,FFFFFFF8 |
0x83, 0xEC, 0x3C, // 005FD786 | 83EC 3C | sub esp,3C |
0xA1, XX4, // 005FD789 | A1 6C908600 | mov eax,dword ptr ds:[86906C] |
0x33, 0xC4, // 005FD78E | 33C4 | xor eax,esp |
0x89, 0x44, 0x24, 0x38, // 005FD790 | 894424 38 | mov dword ptr ss:[esp+38],eax |
0x53, // 005FD794 | 53 | push ebx |
0x56, // 005FD795 | 56 | push esi |
0x8B, 0xC1, // 005FD796 | 8BC1 | mov eax,ecx |
0xC7, 0x44, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00, // 005FD798 | C74424 14 00000000 | mov dword ptr ss:[esp+14],0 |
0x8B, 0x4D, 0x0C, // 005FD7A0 | 8B4D 0C | mov ecx,dword ptr ss:[ebp+C] |
0x33, 0xF6, // 005FD7A3 | 33F6 | xor esi,esi |
0x57, // 005FD7A5 | 57 | push edi |
0x8B, 0x7D, 0x08, // 005FD7A6 | 8B7D 08 | mov edi,dword ptr ss:[ebp+8] |
0x89, 0x44, 0x24, 0x14, // 005FD7A9 | 894424 14 | mov dword ptr ss:[esp+14],eax |
0x89, 0x4C, 0x24, 0x28, // 005FD7AD | 894C24 28 | mov dword ptr ss:[esp+28],ecx |
0x80, 0x3F, 0x00, // 005FD7B1 | 803F 00 | cmp byte ptr ds:[edi],0 |
0x0F, 0x84, XX4, // 005FD7B4 | 0F84 88040000 | je ヘンタイ・プリズンsplit 1.5FDC42 |
0x83, 0xB8, XX4, 0x00, // 005FD7BA | 83B8 74030000 00 | cmp dword ptr ds:[eax+374],0 |
0x8B, 0xDF, // 005FD7C1 | 8BDF | mov ebx,edi |
0x55, // 005FD780 | 55 | push ebp |
0x8B, 0xEC, // 005FD781 | 8BEC | mov ebp,esp |
0x83, 0xE4, 0xF8, // 005FD783 | 83E4 F8 | and esp,FFFFFFF8 |
0x83, 0xEC, 0x3C, // 005FD786 | 83EC 3C | sub esp,3C |
0xA1, XX4, // 005FD789 | A1 6C908600 | mov eax,dword ptr ds:[86906C] |
0x33, 0xC4, // 005FD78E | 33C4 | xor eax,esp |
0x89, 0x44, 0x24, 0x38, // 005FD790 | 894424 38 | mov dword ptr ss:[esp+38],eax |
0x53, // 005FD794 | 53 | push ebx |
0x56, // 005FD795 | 56 | push esi |
0x8B, 0xC1, // 005FD796 | 8BC1 | mov eax,ecx |
0xC7, 0x44, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00, // 005FD798 | C74424 14 00000000 | mov dword ptr ss:[esp+14],0 |
0x8B, 0x4D, 0x0C, // 005FD7A0 | 8B4D 0C | mov ecx,dword ptr ss:[ebp+C] |
0x33, 0xF6, // 005FD7A3 | 33F6 | xor esi,esi |
0x57, // 005FD7A5 | 57 | push edi |
0x8B, 0x7D, 0x08, // 005FD7A6 | 8B7D 08 | mov edi,dword ptr ss:[ebp+8] |
0x89, 0x44, 0x24, 0x14, // 005FD7A9 | 894424 14 | mov dword ptr ss:[esp+14],eax |
0x89, 0x4C, 0x24, 0x28, // 005FD7AD | 894C24 28 | mov dword ptr ss:[esp+28],ecx |
0x80, 0x3F, 0x00, // 005FD7B1 | 803F 00 | cmp byte ptr ds:[edi],0 |
0x0F, 0x84, XX4, // 005FD7B4 | 0F84 88040000 | je ヘンタイ・プリズンsplit 1.5FDC42 |
0x83, 0xB8, XX4, 0x00, // 005FD7BA | 83B8 74030000 00 | cmp dword ptr ds:[eax+374],0 |
0x8B, 0xDF, // 005FD7C1 | 8BDF | mov ebx,edi |
};
enum { addr_offset = 0 }; // distance to the beginning of the function, which is 0x55 (push ebp)
enum
{
addr_offset = 0
}; // distance to the beginning of the function, which is 0x55 (push ebp)
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Artemis3: pattern not found");
return false;
}
addr += addr_offset;
enum { push_ebp = 0x55 }; // beginning of the function
if (*(BYTE *)addr != push_ebp) {
enum
{
push_ebp = 0x55
}; // beginning of the function
if (*(BYTE *)addr != push_ebp)
{
ConsoleOutput("Artemis3: beginning of the function not found");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.type = USING_STRING| EMBED_ABLE|CODEC_UTF8|EMBED_BEFORE_SIMPLE|EMBED_AFTER_NEW;
hp.offset = get_stack(1);
hp.type = USING_STRING | EMBED_ABLE | CODEC_UTF8 | EMBED_BEFORE_SIMPLE | EMBED_AFTER_NEW;
return NewHook(hp, "EmbedArtemis");
return NewHook(hp, "EmbedArtemis");
}
namespace{
bool a4(){
//高慢な奥さんは好きですか?~傲慢人妻教師の堕とし方~
namespace
{
bool a4()
{
// 高慢な奥さんは好きですか?~傲慢人妻教師の堕とし方~
std::vector<uint64_t> addrs;
for(DWORD func:{(DWORD)GetGlyphOutlineA,(DWORD)GetGlyphOutlineW})
for (DWORD func : {(DWORD)GetGlyphOutlineA, (DWORD)GetGlyphOutlineW})
{
auto addrs_ = findiatcallormov_all(func,processStartAddress,processStartAddress,processStopAddress,PAGE_EXECUTE);
auto addrs_ = findiatcallormov_all(func, processStartAddress, processStartAddress, processStopAddress, PAGE_EXECUTE);
addrs.insert(addrs.end(), addrs_.begin(), addrs_.end());
}
bool ok=false;
for (auto addr : addrs) {
bool ok = false;
for (auto addr : addrs)
{
auto funcaddr = MemDbg::findEnclosingAlignedFunction(addr);
if (!funcaddr) continue;
BYTE sig1[]={0x81,XX,0x00,0x00,0x10,0x00};
BYTE sig2[]={0x68,0x00,0x02,0x00,0x00,0x68,0x00,0x02,0x00,0x00};
BYTE sig3[]={XX,0x80,0x00,0x00,0x00,0x0f,0x95,0xc1};
BYTE sig4[]={0xC1,XX,0x18};
int found=0;
for(auto sigsz:std::vector<std::pair<BYTE*,int>>{{sig1,sizeof(sig1)},{sig2,sizeof(sig2)},{sig3,sizeof(sig3)},{sig4,sizeof(sig4)}}){
auto fd= MemDbg::findBytes(sigsz.first, sigsz.second, funcaddr, addr);
if(fd)found+=1;
if (!funcaddr)
continue;
BYTE sig1[] = {0x81, XX, 0x00, 0x00, 0x10, 0x00};
BYTE sig2[] = {0x68, 0x00, 0x02, 0x00, 0x00, 0x68, 0x00, 0x02, 0x00, 0x00};
BYTE sig3[] = {XX, 0x80, 0x00, 0x00, 0x00, 0x0f, 0x95, 0xc1};
BYTE sig4[] = {0xC1, XX, 0x18};
int found = 0;
for (auto sigsz : std::vector<std::pair<BYTE *, int>>{{sig1, sizeof(sig1)}, {sig2, sizeof(sig2)}, {sig3, sizeof(sig3)}, {sig4, sizeof(sig4)}})
{
auto fd = MemDbg::findBytes(sigsz.first, sigsz.second, funcaddr, addr);
if (fd)
found += 1;
}
if(found==4){
if (found == 4)
{
{
HookParam hp;
hp.address = funcaddr;
hp.type = CODEC_ANSI_BE;
hp.offset=get_stack(2);
ok|=NewHook(hp, "Artemis4A");
hp.type = CODEC_ANSI_BE;
hp.offset = get_stack(2);
ok |= NewHook(hp, "Artemis4A");
}
{
HookParam hp;
hp.address = funcaddr+5;
hp.address = funcaddr + 5;
hp.type = CODEC_UTF16;
hp.offset=get_stack(2);
ok|=NewHook(hp, "Artemis4W");
hp.offset = get_stack(2);
ok |= NewHook(hp, "Artemis4W");
}
return ok;
}
@ -240,7 +263,8 @@ namespace{
return false;
}
}
bool Artemis::attach_function() {
return InsertArtemis1Hook() || InsertArtemis2Hook() || InsertArtemis3Hook()||a4();
}
bool Artemis::attach_function()
{
return InsertArtemis1Hook() || InsertArtemis2Hook() || InsertArtemis3Hook() || a4();
}

View File

@ -1,11 +1,13 @@
class Artemis:public ENGINE{
public:
Artemis(){
check_by=CHECK_BY::FILE;
check_by_target=L"*.pfs";
class Artemis : public ENGINE
{
public:
Artemis()
{
check_by = CHECK_BY::FILE;
check_by_target = L"*.pfs";
};
bool attach_function();
bool attach_function();
};

View File

@ -1,4 +1,4 @@
#include"Atelier.h"
#include "Atelier.h"
/********************************************************************************************
AtelierKaguya hook:
Game folder contains message.dat. Used by AtelierKaguya games.
@ -13,240 +13,253 @@ AtelierKaguya hook:
********************************************************************************************/
bool InsertAtelierHook()
{
PcHooks::hookOtherPcFunctions(); // lstrlenA gives good hook too
//SafeFillRange(processName, &base, &size);
//size=size-base;
//DWORD sig = 0x40c683; // add esi,0x40
//i=processStartAddress+SearchPattern(processStartAddress,processStopAddress-processStartAddress,&sig,3);
PcHooks::hookOtherPcFunctions(); // lstrlenA gives good hook too
// SafeFillRange(processName, &base, &size);
// size=size-base;
// DWORD sig = 0x40c683; // add esi,0x40
// i=processStartAddress+SearchPattern(processStartAddress,processStopAddress-processStartAddress,&sig,3);
DWORD i;
for (i = processStartAddress; i < processStopAddress - 4; i++) {
for (i = processStartAddress; i < processStopAddress - 4; i++)
{
DWORD sig = *(DWORD *)i & 0xffffff;
if (0x40c683 == sig) // add esi,0x40
break;
}
if (i < processStopAddress - 4)
for (DWORD j=i-0x200; i>j; i--)
if (*(DWORD *)i == 0xff6acccc) { // find the function entry
for (DWORD j = i - 0x200; i > j; i--)
if (*(DWORD *)i == 0xff6acccc)
{ // find the function entry
HookParam hp;
hp.address = i+2;
hp.offset=get_stack(2);
hp.address = i + 2;
hp.offset = get_stack(2);
hp.split = get_reg(regs::esp);
hp.type = USING_SPLIT;
ConsoleOutput("INSERT Aterlier KAGUYA");
//RegisterEngineType(ENGINE_ATELIER);
// RegisterEngineType(ENGINE_ATELIER);
return NewHook(hp, "Atelier KAGUYA");
}
ConsoleOutput("Aterlier: failed");
return false;
//ConsoleOutput("Unknown Atelier KAGUYA engine.");
// ConsoleOutput("Unknown Atelier KAGUYA engine.");
}
bool InsertAtelierKaguya2Hook()
bool InsertAtelierKaguya2Hook()
{
/*
* Sample games:
* https://vndb.org/v22713
* https://vndb.org/v31685
* https://vndb.org/v37081
*/
/*
* Sample games:
* https://vndb.org/v22713
* https://vndb.org/v31685
* https://vndb.org/v37081
*/
const BYTE bytes[] = {
0x51, // push ecx << hook here
0x50, // push eax
0xE8, XX4, // call Start.exe+114307
0x83, 0xC4, 0x08, // add esp,08
0x85, 0xC0, // test eax,eax
0x78, 0xA1 // js Start.exe+48947
0x51, // push ecx << hook here
0x50, // push eax
0xE8, XX4, // call Start.exe+114307
0x83, 0xC4, 0x08, // add esp,08
0x85, 0xC0, // test eax,eax
0x78, 0xA1 // js Start.exe+48947
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Atelier KAGUYA2: pattern not found");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::eax);
hp.type = USING_STRING|EMBED_AFTER_OVERWRITE|EMBED_BEFORE_SIMPLE|EMBED_ABLE|EMBED_DYNA_SJIS;
hp.hook_font=F_TextOutA;
hp.offset = get_reg(regs::eax);
hp.type = USING_STRING | EMBED_AFTER_OVERWRITE | EMBED_BEFORE_SIMPLE | EMBED_ABLE | EMBED_DYNA_SJIS;
hp.hook_font = F_TextOutA;
hp.filter_fun = NewLineCharToSpaceFilterA;
ConsoleOutput("INSERT Atelier KAGUYA2");
return NewHook(hp, "Atelier KAGUYA2");
}
bool InsertAtelierKaguya3Hook()
bool InsertAtelierKaguya3Hook()
{
/*
* Sample games:
* https://vndb.org/v10082
*/
/*
* Sample games:
* https://vndb.org/v10082
*/
const BYTE bytes[] = {
0x55, // push ebp << hook here
0x8B, 0xEC, // mov ebp,esp
0x6A, 0xFF, // push -01
0x68, 0x80, 0xB9, 0x4D, 0x00, // push Start.exe+DB980
0x64, 0xA1, XX4, // mov eax,fs:[00000000]
0x50, // push eax
0x51, // push ecx
0x81, 0xEC, 0xAC, 0x00, 0x00, 0x00 // sub esp,000000AC
0x55, // push ebp << hook here
0x8B, 0xEC, // mov ebp,esp
0x6A, 0xFF, // push -01
0x68, 0x80, 0xB9, 0x4D, 0x00, // push Start.exe+DB980
0x64, 0xA1, XX4, // mov eax,fs:[00000000]
0x50, // push eax
0x51, // push ecx
0x81, 0xEC, 0xAC, 0x00, 0x00, 0x00 // sub esp,000000AC
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Atelier KAGUYA3: pattern not found");
return false;
}
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::eax);
hp.offset = get_reg(regs::eax);
hp.type = USING_STRING;
hp.filter_fun = NewLineCharToSpaceFilterA;
ConsoleOutput("INSERT Atelier KAGUYA3");
return NewHook(hp, "Atelier KAGUYA3");
}
bool InsertAtelierKaguya4Hook()
bool InsertAtelierKaguya4Hook()
{
/*
* Sample games:
* https://vndb.org/v14705
*/
/*
* Sample games:
* https://vndb.org/v14705
*/
const BYTE bytes[] = {
0xE8, 0x90, 0xA8, 0xFF, 0xFF, // call Start.exe+18380
0x89, 0x45, 0xF8, // mov [ebp-08],eax
0x8B, 0x4D, 0x10, // mov ecx,[ebp+10]
0x51, // push ecx
0x8B, 0x55, 0x0C, // mov edx,[ebp+0C]
0x52, // push edx
0x8B, 0x45, 0x08, // mov eax,[ebp+08]
0x50 // push eax << hook here
0xE8, 0x90, 0xA8, 0xFF, 0xFF, // call Start.exe+18380
0x89, 0x45, 0xF8, // mov [ebp-08],eax
0x8B, 0x4D, 0x10, // mov ecx,[ebp+10]
0x51, // push ecx
0x8B, 0x55, 0x0C, // mov edx,[ebp+0C]
0x52, // push edx
0x8B, 0x45, 0x08, // mov eax,[ebp+08]
0x50 // push eax << hook here
};
enum
{
addr_offset = sizeof(bytes) - 1
};
enum { addr_offset = sizeof(bytes) - 1 };
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Atelier KAGUYA4: pattern not found");
return false;
}
HookParam hp;
hp.address = addr + addr_offset;
hp.offset=get_reg(regs::eax);
hp.offset = get_reg(regs::eax);
hp.type = USING_STRING;
hp.filter_fun = NewLineCharToSpaceFilterA;
ConsoleOutput("INSERT Atelier KAGUYA4");
return NewHook(hp, "Atelier KAGUYA4");
}
bool InsertAtelierKaguya5Hook()
bool InsertAtelierKaguya5Hook()
{
/*
* Sample games:
* https://vndb.org/v11224
*/
/*
* Sample games:
* https://vndb.org/v11224
*/
const BYTE bytes[] = {
0xC2, 0x04, 0x00, // ret 0004
0x55, // push ebp << hook here
0x8B, 0xEC, // mov ebp,esp
0x6A, 0xFF, // push -01
0x68, XX4, // push Start.exe+DA680
0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, // mov eax,fs:[00000000]
0x50, // push eax
0x51, // push ecx
0xC2, 0x04, 0x00, // ret 0004
0x55, // push ebp << hook here
0x8B, 0xEC, // mov ebp,esp
0x6A, 0xFF, // push -01
0x68, XX4, // push Start.exe+DA680
0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, // mov eax,fs:[00000000]
0x50, // push eax
0x51, // push ecx
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Atelier KAGUYA5: pattern not found");
return false;
}
HookParam hp;
hp.address = addr + 3;
hp.offset=get_reg(regs::eax);
hp.offset = get_reg(regs::eax);
hp.type = USING_STRING;
hp.filter_fun = NewLineCharToSpaceFilterA;
ConsoleOutput("INSERT Atelier KAGUYA5");
return NewHook(hp, "Atelier KAGUYA5");
}
bool InsertAtelierKaguyaX()
bool InsertAtelierKaguyaX()
{
//エロティ課 誘惑研修はじまるよ~ しごいちゃうから覚悟なさい!
// エロティ課 誘惑研修はじまるよ~ しごいちゃうから覚悟なさい!
const BYTE bytes[] = {
0x3D,0xF0,0x41,0x00,0x00,
0x75
};
0x3D, 0xF0, 0x41, 0x00, 0x00,
0x75};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) return false;
addr = findfuncstart(addr,0x1000);
if (!addr) return false;
if (!addr)
return false;
addr = findfuncstart(addr, 0x1000);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.type = USING_STRING;
hp.offset = get_stack(1);
hp.type = USING_STRING;
return NewHook(hp, "Atelier KAGUYA3");
}
bool Atelier::attach_function() {
return InsertAtelierHook() || InsertAtelierKaguya2Hook() ||InsertAtelierKaguyaX()|| InsertAtelierKaguya3Hook() || InsertAtelierKaguya4Hook() || InsertAtelierKaguya5Hook();
}
bool Atelier::attach_function()
{
return InsertAtelierHook() || InsertAtelierKaguya2Hook() || InsertAtelierKaguyaX() || InsertAtelierKaguya3Hook() || InsertAtelierKaguya4Hook() || InsertAtelierKaguya5Hook();
}
bool Atelier2attach_function(){
//https://vndb.org/v304
//ダンジョンクルセイダーズTALES OF DEMON EATER
const BYTE bytes[] = {
0x83 ,0xFE ,0x34 ,
0xF6 ,XX ,
0x88 ,XX,0x24 ,0x29 ,
0x7D
};
bool Atelier2attach_function()
{
// https://vndb.org/v304
// ダンジョンクルセイダーズTALES OF DEMON EATER
const BYTE bytes[] = {
0x83, 0xFE, 0x34,
0xF6, XX,
0x88, XX, 0x24, 0x29,
0x7D};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) return false;
if (!addr)
return false;
HookParam hp;
hp.address = addr+sizeof(bytes)-1;
hp.address = addr + sizeof(bytes) - 1;
hp.offset = get_stack(10);
hp.type=USING_CHAR|NO_CONTEXT;
//NO_CONTEXT:
//牝奴隷 ~犯された放課後~
//https://vndb.org/v4351会把每行单独分开。
hp.type = USING_CHAR | NO_CONTEXT;
// NO_CONTEXT:
// 牝奴隷 ~犯された放課後~
// https://vndb.org/v4351会把每行单独分开。
return NewHook(hp, "Atelier KAGUYA3");
}
bool Atelier2attach_function2(){
//https://vndb.org/v7264
//禁断の病棟 特殊精神科医 遊佐惣介の診察記録
auto addr=MemDbg::findCallerAddressAfterInt3((ULONG)TextOutA,processStartAddress,processStopAddress);
if(addr==0)return 0;
bool Atelier2attach_function2()
{
// https://vndb.org/v7264
// 禁断の病棟 特殊精神科医 遊佐惣介の診察記録
auto addr = MemDbg::findCallerAddressAfterInt3((ULONG)TextOutA, processStartAddress, processStopAddress);
if (addr == 0)
return 0;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(3);
hp.type=USING_STRING|DATA_INDIRECT;
hp.offset = get_stack(3);
hp.type = USING_STRING | DATA_INDIRECT;
return NewHook(hp, "Atelier KAGUYA");
}
bool Atelier2::attach_function(){
return Atelier2attach_function()||Atelier2attach_function2();
bool Atelier2::attach_function()
{
return Atelier2attach_function() || Atelier2attach_function2();
}

View File

@ -1,24 +1,29 @@
class Atelier:public ENGINE{
public:
Atelier(){
check_by=CHECK_BY::FILE;
check_by_target=L"message.dat";
class Atelier : public ENGINE
{
public:
Atelier()
{
check_by = CHECK_BY::FILE;
check_by_target = L"message.dat";
};
bool attach_function();
bool attach_function();
};
class Atelier2:public ENGINE{
public:
Atelier2(){
check_by=CHECK_BY::CUSTOM;
check_by_target=[](){
return (Util::CheckFile(L"*.ARC")&&Util::CheckFile(L"*.ARI"))||
(Util::CheckFile(L"ARC\\*.ARC")&&Util::CheckFile(L"ARC\\*.ARI"));
class Atelier2 : public ENGINE
{
public:
Atelier2()
{
check_by = CHECK_BY::CUSTOM;
check_by_target = []()
{
return (Util::CheckFile(L"*.ARC") && Util::CheckFile(L"*.ARI")) ||
(Util::CheckFile(L"ARC\\*.ARC") && Util::CheckFile(L"ARC\\*.ARI"));
};
};
bool attach_function();
bool attach_function();
};

View File

@ -46,7 +46,6 @@ return i;
.text:00451B2D jmp short loc_451B13
*/
BYTE check[] = {
//clang-format off
0x8B, 0x44, 0x24, 0x0C,
0x59,
0x33, 0xF6,
@ -61,9 +60,7 @@ return i;
0x74, 0x04,
0x46,
0x40,
0xEB, 0xE4
//clang-format on
};
0xEB, 0xE4};
auto addrx = MemDbg::findBytes(check, sizeof(check), processStartAddress, processStopAddress);
if (!addrx)
return false;

View File

@ -80,15 +80,12 @@ namespace
{
// void __usercall sub_425580(char *a1@<edx>, int a2@<ecx>, int a3)
BYTE bytes[] = {
//clang-format off
0x3c, 0x24,
0x75, XX,
0x80, 0x7e, 0x01, 0x00,
0x74, XX,
0x83, XX, 0x02,
0x83, XX, 0x02,
//clang-format on
};
0x83, XX, 0x02};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return 0;

View File

@ -115,20 +115,17 @@ namespace
bool hook3()
{
BYTE _[] = {
// clang-format off
// if ( *(_WORD *)v38 == 8511 || (_WORD)v5 == 16161 || (_WORD)v5 == 8481 )
0xB9,0x3F,0x21,0x00,0x00,//mov ecx, 213Fh
0x0F,0xB7,0x02,//movzx eax, word ptr [edx]
0x66,0x3B,0xC1,// cmp ax, cx
0x0F,0x84,XX4,//jz loc_458294
0xb9,0x21,0x3f,0x00,0x00,// mov ecx, 3F21h
0x66,0x3B,0xC1,
0x0F,0x84,XX4,
0xb9,0x21,0x21,0x00,0x00,// mov ecx, 2121h
0x66,0x3B,0xC1,
0x0F,0x84,XX4,
// clang-format on
};
// if ( *(_WORD *)v38 == 8511 || (_WORD)v5 == 16161 || (_WORD)v5 == 8481 )
0xB9, 0x3F, 0x21, 0x00, 0x00, // mov ecx, 213Fh
0x0F, 0xB7, 0x02, // movzx eax, word ptr [edx]
0x66, 0x3B, 0xC1, // cmp ax, cx
0x0F, 0x84, XX4, // jz loc_458294
0xb9, 0x21, 0x3f, 0x00, 0x00, // mov ecx, 3F21h
0x66, 0x3B, 0xC1,
0x0F, 0x84, XX4,
0xb9, 0x21, 0x21, 0x00, 0x00, // mov ecx, 2121h
0x66, 0x3B, 0xC1,
0x0F, 0x84, XX4};
ULONG addr = MemDbg::findBytes(_, sizeof(_), processStartAddress, processStopAddress);
if (addr == 0)
return false;

View File

@ -727,10 +727,10 @@ namespace
{
bool h5()
{
//狙われた優等生 身代わりの代償
// 狙われた優等生 身代わりの代償
const BYTE bytes[] = {
// if ( v90 && ((v40 = *(_WORD *)(v94 + 28), v40 >= 0x41u && v40 <= 0x5Au) || v40 >= 0x61u && v40 <= 0x7Au) )
//clang-format off
0x8b, 0x45, XX,
0x0f, 0xb7, 0x50, XX,
@ -754,9 +754,7 @@ namespace
0x66, 0x3b, 0xc2,
0x1b, 0xc0,
0x40,
0x85, 0xc8,
//clang-format on
0x85, 0xc8
};

View File

@ -12,15 +12,13 @@ namespace
|| *(v6 - 3) != sub_40C130(255, 255, 255)
|| sub_418190(*(v6 - 4), v6 - 1) != 1
|| dword_B81054 && dword_975570 )*/
// clang-format off
0x83,0x7b,0xf8,0x17,
0x75,XX,
0x68,0xff,0x00,0x00,0x00,
0x68,0xff,0x00,0x00,0x00,
0x68,0xff,0x00,0x00,0x00,
0xe8,
// clang-format on
};
0x83, 0x7b, 0xf8, 0x17,
0x75, XX,
0x68, 0xff, 0x00, 0x00, 0x00,
0x68, 0xff, 0x00, 0x00, 0x00,
0x68, 0xff, 0x00, 0x00, 0x00,
0xe8};
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (!addr)
return false;

View File

@ -433,7 +433,6 @@ namespace
// WORDS WORTH【Windows10対応】
// elf3只能拿到人名跳过
uint8_t bytes[] = {
//clang-format off
0x72, 0x02,
0x8b, 0x36,
0x8a, 0x0e,
@ -448,9 +447,7 @@ namespace
0x76, 0x07,
0x8d, 0x41, 0x20,
0x3c, 0x0f,
0x77, XX,
//clang-format on
};
0x77, XX};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;
@ -468,7 +465,6 @@ namespace
// https://vndb.org/v3327
// 女系家族~淫謀~
BYTE sig[] = {
//clang-format off
0X55,
0x8b, 0xec, // mov ebp,esp
0x51, 0x53, 0x56,
@ -480,10 +476,7 @@ namespace
0x80, 0xfa, 0x81, // cmp dl,0x81
0x72, 0x05,
0x80, 0xfa, 0x9f, // cmp dl,0x9f
0x76, XX,
//clang-format on
};
// clang-format on
0x76, XX};
ULONG addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (!addr)
return false;
@ -605,31 +598,28 @@ namespace
{
// HAN4@49570:AI5WIN.exe
// clang-format off
BYTE sig[]={
0x33,0xc5,
0x89,0x45,0xfc,
0x8a,0x81,XX4,
BYTE sig[] = {
0x33, 0xc5,
0x89, 0x45, 0xfc,
0x8a, 0x81, XX4,
0x84,0xc0,
0x75,0x0e,
0x8b,0x81,XX4,
0x03,0x81,XX4,
0xeb,XX,
0x84, 0xc0,
0x75, 0x0e,
0x8b, 0x81, XX4,
0x03, 0x81, XX4,
0xeb, XX,
0x3c,0x01,
0x75,0x0e,
0x8b,0x81,XX4,
0x03,0x81,XX4,
0xeb,XX,
0x3c, 0x01,
0x75, 0x0e,
0x8b, 0x81, XX4,
0x03, 0x81, XX4,
0xeb, XX,
0x3c,0x02,
0x75,0x0e,
0x8b,0x81,XX4,
0x03,0x81,XX4,
0xeb,XX,
};
// clang-format on
0x3c, 0x02,
0x75, 0x0e,
0x8b, 0x81, XX4,
0x03, 0x81, XX4,
0xeb, XX};
ULONG addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (!addr)
return false;
@ -666,7 +656,6 @@ namespace
0x72, 0x10,
0x3c, 0xef,
0x77, 0x0c};
// clang-format on
ULONG addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (!addr)
return false;

View File

@ -536,7 +536,6 @@ namespace
bool TENMEI()
{
BYTE sig[] = {
//clang-format off
0xc7, 0x45, XX, 0x00, 0x00, 0x00, 0x00,
0xc7, 0x45, XX, 0x00, 0x00, 0x00, 0x00,
0xc7, 0x45, XX, 0x00, 0x00, 0x00, 0x00,
@ -549,9 +548,7 @@ namespace
0xc7, 0x45, XX, 0x00, 0x00, 0x00, 0x00,
0xc7, 0x45, XX, 0x0f, 0x00, 0x00, 0x00,
0xc6, 0x45, XX, 0x00,
0xc6, 0x45, XX, 0x03,
//clang-format on
};
0xc6, 0x45, XX, 0x03};
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (addr == 0)
return false;

View File

@ -8,7 +8,6 @@ bool Fizzattach_function1()
// さくらテイル
const BYTE bytes[] = {
//clang-format off
0x55, 0x8b, 0xec,
0x6a, 0xff,
0x68, XX4,
@ -25,10 +24,7 @@ bool Fizzattach_function1()
0xc7, 0x45, XX, 0, 0, 0, 0,
0xc7, 0x45, XX, 0, 0, 0, 0,
0x8d, 0x4d, XX,
0xe8, XX4,
//clang-format on
};
0xe8, XX4};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;
@ -47,16 +43,13 @@ namespace
// https://vndb.org/v5688
// size_t __cdecl strlen(const char *Str)
const BYTE bytes[] = {
//clang-format off
0xBA, 0xFF, 0xFE, 0xFE, 0x7E,
0x03, 0xD0,
0x83, 0xF0, 0xFF,
0x33, 0xC2,
0x83, 0xC1, 0x04,
0xA9, 0x00, 0x01, 0x01, 0x81,
0x74, XX,
//clang-format on
};
0x74, XX};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;

View File

@ -6,11 +6,7 @@ bool NNNConfig::attach_function()
// 復讐の女仕官ハイネ ~肢体に刻まれる淫欲のプログラム~
// https://vndb.org/v24955
const BYTE bytes[] = {
//clang-format off
0x68, 0xE8, 0x03, 0x00, 0x00, 0x6a, 0x00,
//clang-format on
};
0x68, 0xE8, 0x03, 0x00, 0x00, 0x6a, 0x00};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (addr == 0)
return false;

View File

@ -365,13 +365,12 @@ bool InsertNeXASHookW()
if (!addr)
continue;
BYTE check[] = {
//clang-format off
0x83, XX, XX4, 0x10, // cmp dword ptr [edi+0BCh], 10h; XX4:0xbc, 0x00, 0x00, 0x00
0x8d, XX, XX4, // lea edx, [edi+0A8h], XX4:0xa8, 0x00, 0x00, 0x00
0x89, XX, XX,
0x72, 0x06,
0x8b, XX, XX4, // mov edx, [edi+0A8h], XX4:0xa8, 0x00, 0x00, 0x00
//clang-format on
};
auto addrx = MemDbg::findBytes(check, sizeof(check), addr, addr1);
if (!addrx)

View File

@ -82,12 +82,9 @@ namespace
auto succ = NewHook(hp, "dmmdrc");
BYTE sig2[] = {
//clang-format off
0x68, 0x00, 0x02, 0x00, 0x00,
0xba, XX4,
0xe8, XX4,
//clang-format on
};
0xe8, XX4};
memcpy(sig2 + 6, (void *)(addr + 2), 4);
addr = MemDbg::findBytes(sig2, sizeof(sig2), addr, addr + 0x100);
if (addr)

View File

@ -489,7 +489,6 @@ namespace
if (addrX == 0)
break;
lower = addrX + 0x100;
// clang-format off
const uint8_t bytes[] = {
0x55, 0x8b, 0xec,
@ -499,11 +498,9 @@ namespace
0x74, XX,
0x8b, 0x4e, 0x14,
0x83, 0xf9, 0x10,
0x72,0x04,
0x8b,0x06,
0xeb,0x02,
};
// clang-format on
0x72, 0x04,
0x8b, 0x06,
0xeb, 0x02};
ULONG addr = reverseFindBytes(bytes, sizeof(bytes), addrX - 0x200, addrX);
if (!addr)

View File

@ -7,15 +7,12 @@ namespace
bool hook2()
{
BYTE bytes[] = {
//clang-format off
0x8b, 0xbe, XX2, 0x00, 0x00,
0x80, 0x3c, 0x07, 0x00,
0x8d, 0x1c, 0x07,
0x75, XX,
0x8b, 0xce,
0xe8, XX4,
//clang-format on
};
0xe8, XX4};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;

View File

@ -5,7 +5,6 @@
bool RPGMaker::attach_function()
{
BYTE bytes2[] = {
//clang-format off
0x81, 0xf9, 0xff, 0xff, 0xff, 0x7f,
XX2,
0xb9, 0xff, 0xff, 0xff, 0x7f,
@ -17,9 +16,7 @@ bool RPGMaker::attach_function()
0x2b, 0x45, 0x0c,
0x3b, 0xd0,
XX2,
0xb9, 0xff, 0xff, 0xff, 0x7f,
//clang-format on
};
0xb9, 0xff, 0xff, 0xff, 0x7f};
auto addr = MemDbg::findBytes(bytes2, sizeof(bytes2), processStartAddress, processStopAddress);
if (!addr)
return false;

View File

@ -210,13 +210,10 @@ bool Reallive::attach_function()
bool avg3216dattach_function()
{
BYTE pattern1[] = {
//clang-format off
0x3c, 0x81, XX2,
0x3c, 0x9f, XX2,
0x3c, 0xe0, XX2,
0x3c, 0xfc, XX2,
//clang-format on
};
0x3c, 0xfc, XX2};
BYTE pattern2[] = {
0x8b, 0x75, 0x08,
0x8a, 0x06,
@ -245,7 +242,6 @@ bool avg3216dattach_function2()
// https://vndb.org/v12860
// effect悪魔の仔
BYTE pattern2[] = {
//clang-format off
0x80, 0xf9, 0x81,
0x72, 0x05,
0x80, 0xf9, 0x9f,
@ -253,9 +249,7 @@ bool avg3216dattach_function2()
0x80, 0xf9, 0xe0,
0x72, 0x05,
0x80, 0xf9, 0xfc,
0x76, 0x0d,
//clang-format on
};
0x76, 0x0d};
auto addr = MemDbg::findBytes(pattern2, sizeof(pattern2), processStartAddress, processStopAddress);
if (addr == 0)
return false;

View File

@ -489,19 +489,16 @@ namespace
//[240531][1274293][シルキーズSAKURA] 淫魔淫姦 ~触手と合体して思い通りにやり返す~ DL版
bool silkys5()
{
// clang-format off
BYTE sig[]={
0xff,0xd0,//call eax
//<-- eax
0x8b,0x0f,
0x8b,0xf0,//mov esi,eax
0x68,0x80,0,0,0,
0x68,0x80,0,0,0,
0x6a,0,
0x8b,0x11,
0x6a,0,
};
// clang-format on
BYTE sig[] = {
0xff, 0xd0, // call eax
//<-- eax
0x8b, 0x0f,
0x8b, 0xf0, // mov esi,eax
0x68, 0x80, 0, 0, 0,
0x68, 0x80, 0, 0, 0,
0x6a, 0,
0x8b, 0x11,
0x6a, 0};
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (!addr)
return false;
@ -671,24 +668,21 @@ namespace
// HS932#-8@44D90:Angel.exe
bool fob2()
{
// clang-format off
const BYTE bytes[] = {
0x53,
0x56,
0x8b,0xf1,
0x8b,0xde,
0x8d,0x4b,0x01,
0x8d,0xa4,0x24,0x00,0x00,0x00,0x00,
0x8a,0x03,
0x43,
0x84,0xc0,
0x75,XX,
0x2b,0xd9,
0xb8,0xa8,0x00,0x00,0x00,
0x3b,0xd8,
0x68,0xac,0x00,0x00,0x00,
};
// clang-format on
const BYTE bytes[] = {
0x53,
0x56,
0x8b, 0xf1,
0x8b, 0xde,
0x8d, 0x4b, 0x01,
0x8d, 0xa4, 0x24, 0x00, 0x00, 0x00, 0x00,
0x8a, 0x03,
0x43,
0x84, 0xc0,
0x75, XX,
0x2b, 0xd9,
0xb8, 0xa8, 0x00, 0x00, 0x00,
0x3b, 0xd8,
0x68, 0xac, 0x00, 0x00, 0x00};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr)
return false;

View File

@ -111,7 +111,6 @@ namespace
auto [s, e] = Util::QueryModuleLimits(TextXtra);
// Text Asset.x32->this function
const BYTE bytes[] = {
//clang-format off
0x55, 0x8b, 0xec,
0x56,
0x8b, 0x75, 0x08,
@ -126,9 +125,7 @@ namespace
0xff, 0x70, 0x24,
0xe8, XX4,
0x66, 0x85, 0xc0,
0x74, XX,
//clang-format on
};
0x74, XX};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), s, e);
if (addr == 0)
return false;

View File

@ -141,14 +141,11 @@ bool TACTICSattach_function1()
bool TACTICSattach_function2()
{
BYTE sig[] = {
// clang-format off
0x2d,0x40,0x81,0x00,0x00,
0x89,0x83,XX,0x00,0x00,0x00,
0x3d,0x57,0x02,0x00,0x00,
0x0f,0x82,XX4,
0xbf,0x57,0x02,0x00,0x00,
// clang-format on
};
0x2d, 0x40, 0x81, 0x00, 0x00,
0x89, 0x83, XX, 0x00, 0x00, 0x00,
0x3d, 0x57, 0x02, 0x00, 0x00,
0x0f, 0x82, XX4,
0xbf, 0x57, 0x02, 0x00, 0x00};
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (!addr)
return false;
@ -181,18 +178,15 @@ namespace
}
*/
BYTE sig[] = {
// clang-format off
0x3d,0x40,0x81,0x00,0x00,
0x0f,0x84,XX4,
0x8b,0xf0,
0x81,0xee,0x40,0x81,0x00,0x00,
0x85,0xf6,
0x7c,0x08,
0x81,0xfe,0x55,0x02,0x00,0x00,
0x7e,XX,
0xbe,0x56,0x02,0x00,0x00
// clang-format on
};
0x3d, 0x40, 0x81, 0x00, 0x00,
0x0f, 0x84, XX4,
0x8b, 0xf0,
0x81, 0xee, 0x40, 0x81, 0x00, 0x00,
0x85, 0xf6,
0x7c, 0x08,
0x81, 0xfe, 0x55, 0x02, 0x00, 0x00,
0x7e, XX,
0xbe, 0x56, 0x02, 0x00, 0x00};
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (!addr)
return false;

View File

@ -1,18 +1,20 @@
#include"akatombo.h"
#include "akatombo.h"
bool akatombo::attach_function() {
//サキュヴァス ~堕ちた天使~
//https://vndb.org/v7387
bool akatombo::attach_function()
{
// サキュヴァス ~堕ちた天使~
// https://vndb.org/v7387
BYTE bytes[] = {
0x3C,0x80,0x72,XX,0x3C,0x9F,0x76,XX,0x3C,0xE0,0x72,XX,0x3C,0xEF,0x77,XX
};
0x3C, 0x80, 0x72, XX, 0x3C, 0x9F, 0x76, XX, 0x3C, 0xE0, 0x72, XX, 0x3C, 0xEF, 0x77, XX};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (addr == 0)return false;
addr = findfuncstart(addr,0x200);
if (addr == 0)return false;
if (addr == 0)
return false;
addr = findfuncstart(addr, 0x200);
if (addr == 0)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.type = USING_STRING|EMBED_ABLE|EMBED_AFTER_NEW|EMBED_BEFORE_SIMPLE|EMBED_DYNA_SJIS;
return NewHook(hp, "akatombo");
}
hp.offset = get_stack(1);
hp.type = USING_STRING | EMBED_ABLE | EMBED_AFTER_NEW | EMBED_BEFORE_SIMPLE | EMBED_DYNA_SJIS;
return NewHook(hp, "akatombo");
}

View File

@ -1,12 +1,14 @@
class akatombo:public ENGINE{
public:
akatombo(){
check_by=CHECK_BY::RESOURCE_STR;
check_by_target=L"akatombo";
is_engine_certain=false;
class akatombo : public ENGINE
{
public:
akatombo()
{
check_by = CHECK_BY::RESOURCE_STR;
check_by_target = L"akatombo";
is_engine_certain = false;
};
bool attach_function();
bool attach_function();
};

View File

@ -7,10 +7,8 @@ namespace
{
// HSN65001#-44@234699:te-win64vc14-release.exe
BYTE b1[] = {
//clang-format off
0x48, XX2, 0xb0, 0xfe, 0xff, 0xff,
0x4c, XX2, 0xb8, 0x01, 0x00, 0x00,
//clang-format on
0x4c, XX2, 0xb8, 0x01, 0x00, 0x00
};
auto addr = MemDbg::findBytes(b1, sizeof(b1), processStartAddress, processStopAddress);
@ -34,13 +32,9 @@ namespace
{
// HSN65001#-44@2346AC:te-win64vc14-release.exe
BYTE b1[] = {
//clang-format off
0x48, XX2, 0x10,
0x48, XX2, 0xb0, 0x01, 0x00, 0x00,
XX2, 0xc0, 0x08, 0x00, 0x00
//clang-format on
};
XX2, 0xc0, 0x08, 0x00, 0x00};
auto addr = MemDbg::findBytes(b1, sizeof(b1), processStartAddress, processStopAddress);
if (addr == 0)
return false;
@ -62,7 +56,6 @@ namespace
{
// HSN65001#-14@3D9814:te-win64vc14-release.exe
BYTE b1[] = {
//clang-format off
0x48, 0x8b, 0x1b,
0x48, 0x8b, 0x01,
0x48, 0x8b, 0xd3,
@ -71,9 +64,7 @@ namespace
0x48, 0x8b, 0x4d, 0xc0,
0x48, 0x2b, 0xc1,
0x48, 0xc1, 0xf8, 0x03,
0x48, 0x85, 0xc0,
//clang-format on
};
0x48, 0x85, 0xc0};
auto addr = MemDbg::findBytes(b1, sizeof(b1), processStartAddress, processStopAddress);
if (addr == 0)
return false;

View File

@ -5,15 +5,12 @@ namespace
{
// 有多个,但是只有最后一个是有效的
const uint8_t bytes[] = {
//clang-format off
0xB8, 0x42, 0x81, 0x00, 0x00,
0x66, XX2, 0x74, XX,
0xB8, 0x76, 0x81, 0x00, 0x00,
0x66, XX2, 0x74, XX,
0xB8, 0x78, 0x81, 0x00, 0x00,
0x66, XX2, 0x74, XX,
//clang-format on
};
0x66, XX2, 0x74, XX};
bool res = false;
auto addr = processStartAddress;

View File

@ -61,13 +61,10 @@ namespace
// 有太多乱的输出了,而且基本不需要它,所以先放到后面。
BYTE sig[] = {
//clang-format off
0x48, XX, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
0x48, 0x3B, 0xC3,
0x76, XX,
0x48, XX, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F,
//clang-format on
};
0x48, XX, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F};
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if (addr == 0)
return 0;

View File

@ -18,16 +18,13 @@ bool InsertENTERGRAM()
//[240125][1208048][エンターグラム] すだまリレイシヨン パッケージ版 (mdf+mds)
const BYTE BYTES[] = {
//clang-format off
0x48, 0x8B, 0x43, 0x38,
0x48, 0x8D, 0x7C, 0x24, 0x30,
0x48, 0x8B, 0x74, 0x24, 0x20,
0x48, 0x85, 0xC0,
0x48, 0x8B, 0xCD,
0x48, 0x89, 0x6C, 0x24, 0x40,
0x48, 0x0F, 0x45, 0xF8,
//clang-format on
};
0x48, 0x0F, 0x45, 0xF8};
auto addr = MemDbg::findBytes(BYTES, sizeof(BYTES), processStartAddress, processStopAddress);
if (addr == 0)
return false;

View File

@ -79,30 +79,17 @@ namespace
return NULL;
BYTE sig1[] = {
//clang-format off
0xCC,
0x48, 0x89, XX, 0x24, XX,
//clang-format on
};
0x48, 0x89, XX, 0x24, XX};
BYTE sig2[] = {
//clang-format off
0xC3,
0x48, 0x89, XX, 0x24, XX,
//clang-format on
};
0x48, 0x89, XX, 0x24, XX};
BYTE sig3[] = {
//clang-format off
0xCC,
0x89, XX, 0x24, XX,
//clang-format on
};
0x89, XX, 0x24, XX4};
BYTE sig4[] = {
//clang-format off
0xC3,
0x89, XX, 0x24, XX,
//clang-format on
};
0x89, XX, 0x24, XX};
int idx = 0;
uintptr_t maxaddr = 0;
for (auto sig : {sig1, sig2, sig3, sig4})
@ -567,12 +554,9 @@ namespace
for (auto addr : Util::SearchMemory(sig, sizeof(sig), PAGE_EXECUTE, processStartAddress, processStopAddress))
{
BYTE sig1[] = {
//clang-format off
0x55, 0x8b, 0xec,
0x81, 0xec, XX4,
0x8b, 0x0d, XX4,
//clang-format on
};
0x8b, 0x0d, XX4};
addr = reverseFindBytes(sig1, sizeof(sig1), addr - 0x200, addr);
if (!addr)
continue;