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

View File

@ -1,5 +1,5 @@
#include"5pb.h"
#include"mages/mages.h"
#include "5pb.h"
#include "mages/mages.h"
/** jichi 12/2/2014 5pb
*
* Sample game: [140924] CROSS<EFBFBD>CHANNEL FINAL COMPLETE<EFBFBD> * See: http://sakuradite.com/topic/528
@ -123,7 +123,8 @@
* 001e9b2a c9 leave
* 001e9b2b c3 retn
*/
namespace { // unnamed
namespace
{ // unnamed
// Characters to ignore: [%0-9A-Z]
bool Insert5pbHook1()
@ -131,29 +132,32 @@ namespace { // unnamed
const BYTE bytes[] = {
0xcc, // 0016d90e cc int3
0xcc, // 0016d90f cc int3
0x8b,0x15, XX4, // 0016d910 8b15 782b6e06 mov edx,dword ptr ds:[0x66e2b78] ; .00b43bfe
0x8a,0x0a, // 0016d916 8a0a mov cl,byte ptr ds:[edx] ; jichi: hook here
0x33,0xc0, // 0016d918 33c0 xor eax,eax
0x84,0xc9 // 0016d91a 84c9 test cl,cl
0x8b, 0x15, XX4, // 0016d910 8b15 782b6e06 mov edx,dword ptr ds:[0x66e2b78] ; .00b43bfe
0x8a, 0x0a, // 0016d916 8a0a mov cl,byte ptr ds:[edx] ; jichi: hook here
0x33, 0xc0, // 0016d918 33c0 xor eax,eax
0x84, 0xc9 // 0016d91a 84c9 test cl,cl
};
enum
{
addr_offset = 0x0016d916 - 0x0016d90e
};
enum { addr_offset = 0x0016d916 - 0x0016d90e };
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
//GROWL_DWORD3(addr+addr_offset, processStartAddress,processStopAddress);
if (!addr) {
// GROWL_DWORD3(addr+addr_offset, processStartAddress,processStopAddress);
if (!addr)
{
ConsoleOutput("5pb1: pattern not found");
return false;
}
HookParam hp;
hp.address = addr + addr_offset;
hp.offset=get_reg(regs::edx);
hp.offset = get_reg(regs::edx);
hp.type = USING_STRING;
ConsoleOutput("INSERT 5pb1");
// GDI functions are not used by 5pb games anyway.
//ConsoleOutput("5pb: disable GDI hooks");
// ConsoleOutput("5pb: disable GDI hooks");
//
return NewHook(hp, "5pb1");
}
@ -165,13 +169,13 @@ namespace { // unnamed
}
// 001e9b15 8a10 mov dl,byte ptr ds:[eax] ; jichi: here, word by word
void SpecialHook5pb2(hook_stack* stack, HookParam*, uintptr_t* data, uintptr_t* split, size_t* len)
void SpecialHook5pb2(hook_stack *stack, HookParam *, uintptr_t *data, uintptr_t *split, size_t *len)
{
static DWORD lasttext;
DWORD text = stack->eax;
if (lasttext == text)
return;
BYTE c = *(BYTE*)text;
BYTE c = *(BYTE *)text;
if (!c)
return;
BYTE size = ::LeadByteTable[c]; // 1, 2, or 3
@ -185,13 +189,14 @@ namespace { // unnamed
bool Insert5pbHook2()
{
const BYTE bytes[] = {
0x8a,0x10, // 001e9b15 8a10 mov dl,byte ptr ds:[eax] ; jichi: here, word by word
0x84,0xd2, // 001e9b17 84d2 test dl,dl
0x74,0x11 // 001e9b19 74 11 je short .001e9b2c
0x8a, 0x10, // 001e9b15 8a10 mov dl,byte ptr ds:[eax] ; jichi: here, word by word
0x84, 0xd2, // 001e9b17 84d2 test dl,dl
0x74, 0x11 // 001e9b19 74 11 je short .001e9b2c
};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
//GROWL_DWORD3(addr, processStartAddress,processStopAddress);
if (!addr) {
// GROWL_DWORD3(addr, processStartAddress,processStopAddress);
if (!addr)
{
ConsoleOutput("5pb2: pattern not found");
return false;
}
@ -202,9 +207,8 @@ namespace { // unnamed
hp.text_fun = SpecialHook5pb2;
ConsoleOutput("INSERT 5pb2");
// GDI functions are not used by 5pb games anyway.
//ConsoleOutput("5pb: disable GDI hooks");
// ConsoleOutput("5pb: disable GDI hooks");
//
return NewHook(hp, "5pb2");
}
@ -315,17 +319,20 @@ namespace { // unnamed
* 0026B2A5 CC INT3
* 0026B2A6 CC INT3
*/
void SpecialHook5pb3(hook_stack* stack, HookParam *hp, uintptr_t* data, uintptr_t* split, size_t* len)
void SpecialHook5pb3(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
int index=0;
int index = 0;
// Text in arg1, name in arg2
if (LPCSTR text = (LPCSTR)stack->stack[index+1])
if (*text) {
if (LPCSTR text = (LPCSTR)stack->stack[index + 1])
if (*text)
{
if (index) // trim spaces in character name
while (*text == ' ') text++;
while (*text == ' ')
text++;
size_t sz = ::strlen(text);
if (index)
while (sz && text[sz - 1] == ' ') sz--;
while (sz && text[sz - 1] == ' ')
sz--;
*data = (DWORD)text;
*len = sz;
*split = FIXED_SPLIT_VALUE << index;
@ -333,20 +340,22 @@ namespace { // unnamed
}
bool Insert5pbHook3()
{
const BYTE bytes[] = { // function starts
const BYTE bytes[] = {
// function starts
0x55, // 0025A130 55 PUSH EBP
0x8b,0xec, // 0025A131 8BEC MOV EBP,ESP
0x8b, 0xec, // 0025A131 8BEC MOV EBP,ESP
0x56, // 0025A133 56 PUSH ESI
0xff,0x75, 0x0c, // 0025A134 FF75 0C PUSH DWORD PTR SS:[EBP+0xC]
0x8b,0xf1, // 0025A137 8BF1 MOV ESI,ECX
0xff,0x75, 0x08, // 0025A139 FF75 08 PUSH DWORD PTR SS:[EBP+0x8]
0x8d,0x46, 0x08, // 0025A13C 8D46 08 LEA EAX,DWORD PTR DS:[ESI+0x8]
0xff, 0x75, 0x0c, // 0025A134 FF75 0C PUSH DWORD PTR SS:[EBP+0xC]
0x8b, 0xf1, // 0025A137 8BF1 MOV ESI,ECX
0xff, 0x75, 0x08, // 0025A139 FF75 08 PUSH DWORD PTR SS:[EBP+0x8]
0x8d, 0x46, 0x08, // 0025A13C 8D46 08 LEA EAX,DWORD PTR DS:[ESI+0x8]
0x50, // 0025A13F 50 PUSH EAX
0xe8 // 0025A140 E8 DB100100 CALL .0026B220
};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
//GROWL_DWORD3(addr, processStartAddress,processStopAddress);
if (!addr) {
// GROWL_DWORD3(addr, processStartAddress,processStopAddress);
if (!addr)
{
ConsoleOutput("5pb2: pattern not found");
return false;
}
@ -359,7 +368,7 @@ namespace { // unnamed
ConsoleOutput("INSERT 5pb3");
// GDI functions are not used by 5pb games anyway.
//ConsoleOutput("5pb: disable GDI hooks");
// ConsoleOutput("5pb: disable GDI hooks");
//
return NewHook(hp, "5pb3");
}
@ -372,21 +381,22 @@ bool Insert5pbHook()
ok = Insert5pbHook3() || ok;
return ok;
}
bool Insert5pbHookex() {
//祝姬
bool Insert5pbHookex()
{
// 祝姬
const BYTE bytes[] = {
0x0F,0xB6,0xC2, 0x35,0xC5 ,0x9D ,0x1C ,0x81
};
0x0F, 0xB6, 0xC2, 0x35, 0xC5, 0x9D, 0x1C, 0x81};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (addr == 0)return false;
if (addr == 0)
return false;
const BYTE start[] = {
0x55,0x8b,0xec,0x83,0xe4
};
0x55, 0x8b, 0xec, 0x83, 0xe4};
addr = reverseFindBytes(start, sizeof(start), addr - 0x40, addr);
if (addr == 0)return false;
if (addr == 0)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_reg(regs::ecx);
hp.offset = get_reg(regs::ecx);
hp.type = CODEC_UTF16;
return NewHook(hp, "5pb");
@ -402,19 +412,20 @@ bool InsertStuffScriptHook()
// );
HookParam hp;
hp.address = (DWORD)::GetTextExtentPoint32A;
hp.offset=get_stack(2); // arg2 lpString
hp.offset = get_stack(2); // arg2 lpString
hp.split = get_reg(regs::esp);
hp.type = USING_STRING | USING_SPLIT;
ConsoleOutput("INSERT StuffScriptEngine");
return NewHook(hp, "StuffScriptEngine");
//RegisterEngine(ENGINE_STUFFSCRIPT);
// RegisterEngine(ENGINE_STUFFSCRIPT);
}
bool StuffScript2Filter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
if (text[0] == '-') {
if (text[0] == '-')
{
StringFilter(text, len, "-/-", 3);
StringFilterBetween(text, len, "-", 1, "-", 1);
}
@ -463,7 +474,7 @@ bool InsertStuffScript2Hook()
HookParam hp;
hp.address = addr + 0x11;
hp.offset=get_reg(regs::eax);
hp.offset = get_reg(regs::eax);
hp.index = 0;
hp.type = USING_STRING | NO_CONTEXT;
hp.filter_fun = StuffScript2Filter;
@ -475,15 +486,16 @@ bool StuffScript3Filter(LPVOID data, size_t *size, HookParam *)
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t *>(size);
if (text[0] == '\x81' && text[1] == '\x40') { //removes space at the beginning of the sentence
if (text[0] == '\x81' && text[1] == '\x40')
{ // removes space at the beginning of the sentence
*len -= 2;
::memmove(text, text + 2, *len);
}
StringFilterBetween(text, len, "/\x81\x79", 3, "\x81\x7A", 2); //remove hidden name
StringFilterBetween(text, len, "[", 1, "]", 1); //garbage
StringFilterBetween(text, len, "/\x81\x79", 3, "\x81\x7A", 2); // remove hidden name
StringFilterBetween(text, len, "[", 1, "]", 1); // garbage
//ruby
// ruby
CharFilter(text, len, '<');
StringFilterBetween(text, len, ",", 1, ">", 1);
@ -511,7 +523,8 @@ bool InsertStuffScript3Hook()
};
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 + 1;
@ -521,25 +534,26 @@ bool InsertStuffScript3Hook()
NewHook(hp, "StuffScript3");
return true;
}
bool StuffScript_attach_function() {
auto _=InsertStuffScriptHook();
_|=InsertStuffScript2Hook();
_|=InsertStuffScript3Hook();
bool StuffScript_attach_function()
{
auto _ = InsertStuffScriptHook();
_ |= InsertStuffScript2Hook();
_ |= InsertStuffScript3Hook();
return _;
}
bool _5pb::attach_function() {
bool _5pb::attach_function()
{
bool b1 = Insert5pbHook();
bool b2 = Insert5pbHookex();
bool b3=hookmages::MAGES();
bool sf=StuffScript_attach_function();
return b1 || b2 || b3||sf;
bool b3 = hookmages::MAGES();
bool sf = StuffScript_attach_function();
return b1 || b2 || b3 || sf;
}
bool KaleidoFilter(LPVOID data, size_t* size, HookParam*)
bool KaleidoFilter(LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t*>(size);
auto len = reinterpret_cast<size_t *>(size);
// Unofficial eng TL with garbage newline spaces
StringCharReplacer(text, len, " \\n ", 4, ' ');
@ -566,17 +580,21 @@ bool InsertKaleidoHook()
0x64, 0x89, 0x0D, XX4, // mov fs:[00000000],ecx
0x59 // pop ecx << 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) return false;
if (!addr)
return false;
HookParam hp;
hp.address = addr + addr_offset;
hp.offset=get_reg(regs::esi);
hp.offset = get_reg(regs::esi);
hp.index = 0;
hp.split =get_stack(3);
hp.split = get_stack(3);
hp.split_index = 0;
hp.type = USING_STRING | USING_SPLIT;
hp.filter_fun = KaleidoFilter;
@ -585,118 +603,129 @@ bool InsertKaleidoHook()
return NewHook(hp, "Kaleido");
}
namespace
{ //ANONYMOUS;CODE 官中
bool __1() {
{ // ANONYMOUS;CODE 官中
bool __1()
{
BYTE bytes[] = {
0x8d,0x45,0xf4,0x64,0xA3,0x00,0x00,0x00,0x00,0x8b,0xf1,0x8a,0x46,0x2c,0x8b,0x55,0x08,0x84,0xc0,0x74,0x04,0x32,0xc0
};
0x8d, 0x45, 0xf4, 0x64, 0xA3, 0x00, 0x00, 0x00, 0x00, 0x8b, 0xf1, 0x8a, 0x46, 0x2c, 0x8b, 0x55, 0x08, 0x84, 0xc0, 0x74, 0x04, 0x32, 0xc0};
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if (!addr) return false;
if (!addr)
return false;
addr = MemDbg::findEnclosingAlignedFunction(addr);
if (addr == 0)return false;
if (addr == 0)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.offset = get_stack(1);
hp.type = USING_STRING | CODEC_UTF8 | EMBED_ABLE | EMBED_BEFORE_SIMPLE | EMBED_AFTER_NEW;
hp.newlineseperator = L"\\n";
return NewHook(hp, "5bp");
}
bool __() {
bool __()
{
BYTE sig1[] = {
0x81,0xFE,0xF0,0x00,0x00,0x00
};
0x81, 0xFE, 0xF0, 0x00, 0x00, 0x00};
BYTE sig2[] = {
0x81,0xFE,0xF8,0x00,0x00,0x00
};
0x81, 0xFE, 0xF8, 0x00, 0x00, 0x00};
BYTE sig3[] = {
0x81,0xFE,0xFC,0x00,0x00,0x00
};
0x81, 0xFE, 0xFC, 0x00, 0x00, 0x00};
BYTE sig4[] = {
0x81,0xFE,0xFE,0x00,0x00,0x00
};
0x81, 0xFE, 0xFE, 0x00, 0x00, 0x00};
BYTE sig5[] = {
0x81,0xFE,0x80,0x00,0x00,0x00
};
0x81, 0xFE, 0x80, 0x00, 0x00, 0x00};
BYTE sig6[] = {
0x81,0xFE,0xE0,0x00,0x00,0x00
};
std::unordered_map<uintptr_t, int>addr_hit;
for (auto sigsz : std::vector<std::pair<BYTE*, int>>{ {sig1,sizeof(sig1)},{sig2,sizeof(sig2)},{sig3,sizeof(sig3)},{sig4,sizeof(sig4)},{sig5,sizeof(sig5)},{sig6,sizeof(sig6)} }) {
for (auto addr : Util::SearchMemory(sigsz.first, sigsz.second, PAGE_EXECUTE, processStartAddress, processStopAddress)) {
0x81, 0xFE, 0xE0, 0x00, 0x00, 0x00};
std::unordered_map<uintptr_t, int> addr_hit;
for (auto sigsz : std::vector<std::pair<BYTE *, int>>{{sig1, sizeof(sig1)}, {sig2, sizeof(sig2)}, {sig3, sizeof(sig3)}, {sig4, sizeof(sig4)}, {sig5, sizeof(sig5)}, {sig6, sizeof(sig6)}})
{
for (auto addr : Util::SearchMemory(sigsz.first, sigsz.second, PAGE_EXECUTE, processStartAddress, processStopAddress))
{
addr = MemDbg::findEnclosingAlignedFunction(addr);
if (addr == 0)continue;
if (addr_hit.find(addr) == addr_hit.end()) {
if (addr == 0)
continue;
if (addr_hit.find(addr) == addr_hit.end())
{
addr_hit[addr] = 1;
}
else addr_hit[addr] += 1;
else
addr_hit[addr] += 1;
}
}
DWORD addr = 0; int m = 0;
for (auto _ : addr_hit) {
if (_.second > m) {
DWORD addr = 0;
int m = 0;
for (auto _ : addr_hit)
{
if (_.second > m)
{
m = _.second;
addr = _.first;
}
}
if(!addr)return false;
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.offset = get_stack(1);
hp.type = USING_STRING | CODEC_UTF8;
hp.filter_fun = [](LPVOID data, size_t* size, HookParam*) {
hp.filter_fun = [](LPVOID data, size_t *size, HookParam *)
{
auto text = reinterpret_cast<LPSTR>(data);
auto len = reinterpret_cast<size_t*>(size);
auto len = reinterpret_cast<size_t *>(size);
StringCharReplacer(text, len, "\\n", 2, '\n');
return true;
};
return NewHook(hp, "5bp");
}
} // namespace name
namespace{
namespace
{
bool __2()
{
//レヱル・ロマネスク origin 多国語版
//https://vndb.org/r119877
//char __thiscall sub_426B70(float *this, int a2, int a3, int a4, int a5, char a6, char a7)
BYTE bytes[]={
0x0f,0xb7,0x04,0x72,
// レヱル・ロマネスク origin 多国語版
// https://vndb.org/r119877
// char __thiscall sub_426B70(float *this, int a2, int a3, int a4, int a5, char a6, char a7)
BYTE bytes[] = {
0x0f, 0xb7, 0x04, 0x72,
0x46,
0x89,0x85,XX4,
0x0f,0xb7,0xc0,
0x83,0xc0,0xf6,
0x83,0xf8,0x52,
0x0f,0x87
};
0x89, 0x85, XX4,
0x0f, 0xb7, 0xc0,
0x83, 0xc0, 0xf6,
0x83, 0xf8, 0x52,
0x0f, 0x87};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
if(!addr)return false;
addr=MemDbg::findEnclosingAlignedFunction_strict(addr);
if(!addr)return false;
if (!addr)
return false;
addr = MemDbg::findEnclosingAlignedFunction_strict(addr);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.split=get_stack(2);
hp.type = USING_SPLIT|USING_STRING|FULL_STRING | CODEC_UTF16|EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_AFTER_NEW;//中文显示不出来
hp.filter_fun = [](LPVOID data, size_t* size, HookParam*) {
//そうして、[おひとよ,2]御一夜――\n眼下に広がるこの町も、僕を間違いなく救ってくれた。
//「行政に関しての最大の変化は、市長です。\n現在の市長には[ひない,1]雛衣・ポーレットが就任しています」
//「なるほど。それゆえ、御一夜は衰退し、\n\x%lエアクラ;#00ffc040;エアクラ%l;#;工場の誘致話が持ち上がったわけか?」
//「ナビ。お前も\x%lエアクラ;#00ffc040;エアクラ%l;#;の仲間だったな。\n気を悪くしたか
hp.offset = get_stack(1);
hp.split = get_stack(2);
hp.type = USING_SPLIT | USING_STRING | FULL_STRING | CODEC_UTF16 | EMBED_ABLE | EMBED_BEFORE_SIMPLE | EMBED_AFTER_NEW; // 中文显示不出来
hp.filter_fun = [](LPVOID data, size_t *size, HookParam *)
{
// そうして、[おひとよ,2]御一夜――\n眼下に広がるこの町も、僕を間違いなく救ってくれた。
// 「行政に関しての最大の変化は、市長です。\n現在の市長には[ひない,1]雛衣・ポーレットが就任しています」
// 「なるほど。それゆえ、御一夜は衰退し、\n\x%lエアクラ;#00ffc040;エアクラ%l;#;工場の誘致話が持ち上がったわけか?」
// 「ナビ。お前も\x%lエアクラ;#00ffc040;エアクラ%l;#;の仲間だったな。\n気を悪くしたか
auto text = reinterpret_cast<LPWSTR>(data);
auto len = reinterpret_cast<size_t*>(size);
auto xx=std::wstring(text,*len/2);
auto len = reinterpret_cast<size_t *>(size);
auto xx = std::wstring(text, *len / 2);
xx = std::regex_replace(xx, std::wregex(L"\\[(.*?),\\d\\]"), L"$1");
xx = std::regex_replace(xx, std::wregex(L"\\\\x%l(.*?);(.*?);(.*?);#;"), L"$1");
return write_string_overwrite(data,size,xx);
return write_string_overwrite(data, size, xx);
};
hp.newlineseperator=L"\\n";
hp.newlineseperator = L"\\n";
return NewHook(hp, "5bp");
}
}
bool _5pb_2::attach_function() {
bool _5pb_2::attach_function()
{
bool ___1 = __1() || __();
___1|=__2();
___1 |= __2();
return InsertKaleidoHook() || ___1;
}

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();
};
class _5pb_2:public ENGINE{
public:
_5pb_2(){
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;
check_by = CHECK_BY::FILE;
check_by_target = L"windata/script_body.bin";
is_engine_certain = false;
};
bool attach_function();
};

View File

@ -1,24 +1,29 @@
#include"A98SYS.h"
#include "A98SYS.h"
bool A98SYS::attach_function() {
//https://vndb.org/v6447
//Rainy Blue 6月の雨
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;
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(){
class A98SYS : public ENGINE
{
public:
A98SYS()
{
check_by=CHECK_BY::FILE;
check_by_target=L"A98SYS.PAK";//STREAM.PAK
check_by = CHECK_BY::FILE;
check_by_target = L"A98SYS.PAK"; // STREAM.PAK
};
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
{
typedef struct _NSTRING
{
PVOID vfTable;
DWORD lenWithNull;
DWORD lenWithoutNull;
WCHAR str[1];
} NSTRING;
} NSTRING;
// qsort correctly identifies overflow.
int cmp(const void * a, const void * b)
{ return *(int*)a - *(int*)b; }
// 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);
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) {
// 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 };
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);
// 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);
// 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(){
class AB2Try : public ENGINE
{
public:
AB2Try()
{
check_by=CHECK_BY::FILE;
check_by_target=L"Yanesdk.dll";
check_by = CHECK_BY::FILE;
check_by_target = L"Yanesdk.dll";
};
bool attach_function();
};

View File

@ -1,23 +1,26 @@
#include"ACTGS.h"
#include "ACTGS.h"
bool ACTGS::attach_function() {
bool ACTGS::attach_function()
{
const BYTE bytes[] = {
0x0F,0xBE,0xD0,
0x83,0xFA,0x20,
0x74,XX,
0x83,0xfa,0x09,
0x75,XX
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.offset = get_stack(2);
hp.type = USING_STRING;
hp.filter_fun = all_ascii_Filter;

View File

@ -1,11 +1,13 @@
class ACTGS:public ENGINE{
public:
ACTGS(){
class ACTGS : public ENGINE
{
public:
ACTGS()
{
check_by=CHECK_BY::RESOURCE_STR;
check_by_target=L"ACTRESS Game System";
check_by = CHECK_BY::RESOURCE_STR;
check_by_target = L"ACTRESS Game System";
};
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

@ -1,77 +1,82 @@
#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*/
.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
};
0x8b, 0xec,
0x83, 0xec, 0x38, 0x53, 0x56, 0x8b, 0xf1};
ULONG addr = MemDbg::findBytes(bytes1, sizeof(bytes1), processStartAddress, processStopAddress);
if (!addr) {
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: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);
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)) {
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;
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){
if (found == 4)
{
HookParam hp;
hp.address = funcaddr;
hp.type = DATA_INDIRECT;
hp.offset=get_stack(1);
hp.index=0;
hp.offset = get_stack(1);
hp.index = 0;
return NewHook(hp, "AGS");
}
}
@ -79,7 +84,8 @@ namespace{
}
}
bool AGS::attach_function() {
bool AGS::attach_function()
{
return InsertAGSHook()||hook2();
return InsertAGSHook() || hook2();
}

View File

@ -1,12 +1,14 @@
class AGS:public ENGINE{
public:
AGS(){
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;
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();
};

View File

@ -1,10 +1,12 @@
#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
@ -14,45 +16,48 @@ bool InsertAIL2Hook() {
//.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
};
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");
succ |= NewHook(hp, "AIL1");
BYTE bytes[] = { //if ( v12 != 32 && v12 != 33088 )
0x3d,0x40,0x81,0x00,0x00,0x0f
};
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();
}

View File

@ -1,11 +1,13 @@
class AIL2:public ENGINE{
public:
AIL2(){
class AIL2 : public ENGINE
{
public:
AIL2()
{
check_by=CHECK_BY::FILE;
check_by_target=L"Gall*.dat";
check_by = CHECK_BY::FILE;
check_by_target = L"Gall*.dat";
};
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,38 +78,46 @@ 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");
@ -121,35 +129,43 @@ bool InsertAOS2Hook()
{
const BYTE bytes[] = {
0x51, // 00C4E7E0 /$ 51 PUSH ECX ; mireado: hook here, function begins
0x33,0xc0, // 00C4E7E1 |. 33C0 XOR EAX,EAX
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]
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");
@ -158,32 +174,42 @@ bool InsertAOS2Hook()
}
bool InsertAOSHook()
{ return InsertAOS1Hook() || InsertAOS2Hook();}
{
return InsertAOS1Hook() || InsertAOS2Hook();
}
namespace
{
namespace{
DWORD calladdr(DWORD addr){
if(addr==0)return 0;
BYTE callop[] = { 0xe8 };
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);
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;
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;
}
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;
case 0x48:
@ -204,56 +230,62 @@ regs mov_reg_ebpoffset(int reg) {
return regs::invalid;
}
}
bool AOS_EX() {
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,
};
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;
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));
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);
if (reg != regs::invalid)
{
// usercall
off = get_reg(reg);
}
else if(((*(WORD*)addr))==0xec83) {
//姫様LOVEライフ
//也是usercall但是第二个参数是栈上。
off=get_stack(1);
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
{
// 螺旋遡行のディストピア -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);
else
{
// cdecl;
off = get_stack(2);
}
}
HookParam hp;
@ -267,8 +299,9 @@ bool 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(){
class AOS : public ENGINE
{
public:
AOS()
{
check_by=CHECK_BY::FILE;
check_by_target=L"*.aos";
check_by = CHECK_BY::FILE;
check_by_target = L"*.aos";
};
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;
if (addr == 0)
return false;
addr = findfuncstart(addr,0x1000);
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");
}
namespace{
bool hook2(){
//剣乙女ノア
//Maria天使のキスと悪魔の花嫁
namespace
{
bool hook2()
{
// 剣乙女ノア
// Maria天使のキスと悪魔の花嫁
BYTE bytes[] = {
0x55,0x8b,0xec,
0x55, 0x8b, 0xec,
0x56,
0x8b,0xf0,
0x3b,0x9e,0x8c,0xf8,0x00,0x00,
0x57
};
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() {
bool AXL::attach_function()
{
return InsertAXLHook()||hook2();
return InsertAXLHook() || hook2();
}

View File

@ -1,12 +1,14 @@
class AXL:public ENGINE{
public:
AXL(){
class AXL : public ENGINE
{
public:
AXL()
{
check_by=CHECK_BY::FILE;
check_by_target=L"script.arc";
is_engine_certain=false;
check_by = CHECK_BY::FILE;
check_by_target = L"script.arc";
is_engine_certain = false;
};
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.address = addr + 4;
hp.offset = get_reg(regs::eax);
hp.type = DATA_INDIRECT;
hp.index = 0;
return NewHook(hp, "AbaloneHook");
}
bool Abalone::attach_function() {
bool Abalone::attach_function()
{
return AbaloneHook();
}

View File

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

View File

@ -1,4 +1,4 @@
#include"Abel.h"
#include "Abel.h"
/********************************************************************************************
AbelSoftware hook:
@ -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() {
bool Abel::attach_function()
{
return InsertAbelHook();
}

View File

@ -1,17 +1,18 @@
class Abel:public ENGINE{
public:
Abel(){
check_by=CHECK_BY::CUSTOM;
check_by_target=[](){
class Abel : public ENGINE
{
public:
Abel()
{
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))
// 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];
@ -48,7 +49,7 @@ class Abel:public ENGINE{
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();
};

View File

@ -1,4 +1,4 @@
#include"AdobeAir.h"
#include "AdobeAir.h"
/**
* jichi 4/15/2014: Insert Adobe AIR hook
@ -66,98 +66,110 @@
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)) {
// 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
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
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]
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
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);
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;
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);
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.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
// hp.filter_fun = [](void* str, DWORD* len, HookParam* hp, BYTE index) // removes some of the garbage threads
//{
// return *len < 4 &&
// *(char*)str != '[' &&
@ -167,7 +179,7 @@ bool InsertAIRNovelHook()
// *(char*)str != '\n' &&
// *(char*)str != '\t' &&
// memcmp((char*)str, "app:/", 5);
//};
// };
ConsoleOutput("INSERT AIRNovel");
@ -175,51 +187,58 @@ bool InsertAIRNovelHook()
}
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 AdobeAir::attach_function()
{
bool b1= InsertAdobeAirHook();
b1|=AdobeAIRhook2();
b1|=adobelair3();
b1=b1||InsertAIRNovelHook();//乱码太多了这个
bool b1 = InsertAdobeAirHook();
b1 |= AdobeAIRhook2();
b1 |= adobelair3();
b1 = b1 || InsertAIRNovelHook(); // 乱码太多了这个
return b1;
}

View File

@ -1,12 +1,15 @@
class AdobeAir:public ENGINE{
public:
AdobeAir(){
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");
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();

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
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
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() {
bool AdobeFlash10::attach_function()
{
return InsertAdobeFlash10Hook()|__();
return InsertAdobeFlash10Hook() | __();
}

View File

@ -1,11 +1,13 @@
class AdobeFlash10:public ENGINE{
public:
AdobeFlash10(){
class AdobeFlash10 : public ENGINE
{
public:
AdobeFlash10()
{
check_by=CHECK_BY::RESOURCE_STR;
check_by_target=L"Adobe Flash Player 10";
check_by = CHECK_BY::RESOURCE_STR;
check_by_target = L"Adobe Flash Player 10";
};
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,
0x8d, 0x4f, XX,
0xff, 0x15, XX4,
XX,
0x8d,0x8f,XX4,
0xff,0x15,XX4,
0x8d,XX,XX4,
0x8d, 0x8f, XX4,
0xff, 0x15, XX4,
0x8d, XX, XX4,
XX,
0x8d,0x8f,XX4,
0xff,0x15,XX4,
0x8b,XX,
0xff,0x15,XX4,
};
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() {
bool Ages3ResT::attach_function()
{
return Ages3ResTHook();
}

View File

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

View File

@ -1,9 +1,10 @@
#include"Aksys.h"
#include "Aksys.h"
namespace
{
bool _Aksys() {
//https://vndb.org/v25385
//Spirit Hunter: NG
bool _Aksys()
{
// https://vndb.org/v25385
// Spirit Hunter: NG
/*
int __usercall sub_4CDD70@<eax>(const char *a1@<edx>, int a2, _DWORD *a3, int *a4)
{
@ -33,30 +34,33 @@ bool _Aksys() {
}
*/
BYTE bytes[] = {
0x68,0xe9,0xfd,0,0,
0x68, 0xe9, 0xfd, 0, 0,
0x56,
0x68,0xa4,0x03,0,0,
0x33,XX,
0x33,XX,
0xe8
};
0x68, 0xa4, 0x03, 0, 0,
0x33, XX,
0x33, XX,
0xe8};
auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress);
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_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());
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() {
bool Aksys::attach_function()
{
return _Aksys();
}

View File

@ -1,12 +1,14 @@
class Aksys:public ENGINE{
public:
Aksys(){
class Aksys : public ENGINE
{
public:
Aksys()
{
check_by=CHECK_BY::FILE;
check_by_target=L"System.bra";
is_engine_certain=false;
check_by = CHECK_BY::FILE;
check_by_target = L"System.bra";
is_engine_certain = false;
};
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

@ -1,6 +1,4 @@
#include"Alice.h"
#include "Alice.h"
/********************************************************************************************
System40 hook:
@ -31,14 +29,17 @@ 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.
while (true)
{ // Find the first register push onto stack.
DWORD c = ::disasm((BYTE *)s);
if (c == 1)
break;
@ -47,13 +48,13 @@ static bool InsertAliceHook1(DWORD addr)
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;
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);
// RegisterEngineType(ENGINE_SYS40);
return NewHook(hp, "System40");
}
ConsoleOutput("AliceHook1: failed");
@ -61,18 +62,19 @@ static bool InsertAliceHook1(DWORD addr)
}
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")) {
bool ok = false;
if (auto addr = Util::FindFunction("SP_TextDraw"))
{
ok|= InsertAliceHook1(addr);
ok |= InsertAliceHook1(addr);
}
//if (GetFunctionAddr("SP_SetTextSprite", &addr, &low, &high, 0) && addr) {
// 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
if (auto addr = Util::FindFunction("SP_SetTextSprite"))
{ // Artikash 6/27/2018 not sure if this works
ok|= InsertAliceHook2(addr);
ok |= InsertAliceHook2(addr);
}
//ConsoleOutput("AliceHook: failed");
// ConsoleOutput("AliceHook: failed");
return ok;
}
bool Alice::attach_function() {
bool Alice::attach_function()
{
return InsertAliceHook();
}

View File

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

View File

@ -1,70 +1,71 @@
#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
};
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;
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){
else
{
if (hb <= 0x7e && lb <= 0x7e)
{
*len=2;
*len = 2;
BYTE low;
if ((hb & 1)== 0)
if ((hb & 1) == 0)
low = lb + 0x7E;
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()
{
@ -73,28 +74,32 @@ bool InsertAnex86Hook()
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]) {
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;
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.offset = get_reg(regs::ecx);
hp.type = USING_CHAR;
hp.text_fun = SpecialHookAnex86;
//hp.type = EXTERN_HOOK;
// hp.type = EXTERN_HOOK;
ConsoleOutput("INSERT Anex86");
found |=NewHook(hp, "Anex86");
found |= NewHook(hp, "Anex86");
}
if (found) return true;
if (found)
return true;
ConsoleOutput("Anex86: failed");
return false;
}
bool Anex86::attach_function() {
bool Anex86::attach_function()
{
return InsertAnex86Hook();
}

View File

@ -1,12 +1,14 @@
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"));
};
};

View File

@ -1,54 +1,60 @@
#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);
@ -82,25 +88,26 @@ namespace{
};
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
if (!addr) {
if (!addr)
{
ConsoleOutput("Anim3: pattern not found");
return false;
}
HookParam hp;
hp.address = addr + 1;
hp.offset=get_reg(regs::edx);
hp.offset = get_reg(regs::edx);
hp.type = USING_STRING;
hp.filter_fun = Anim3Filter;
ConsoleOutput("INSERT Anim3");
return NewHook(hp, "Anim3");
}
}
bool Anim::attach_function() {
bool Anim::attach_function()
{
auto b1= InsertAnimHook() || InsertAnim2Hook();
b1=InsertAnim3Hook()||b1;
auto b1 = InsertAnimHook() || InsertAnim2Hook();
b1 = InsertAnim3Hook() || b1;
return b1;
}

View File

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

View File

@ -1,23 +1,24 @@
#include"Anisetta.h"
#include "Anisetta.h"
bool Anisetta::attach_function() {
//https://vndb.org/v4068
//12+
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;
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);
hp.offset = get_stack(5);
return NewHook(hp, "Anisetta");
}

View File

@ -1,12 +1,14 @@
class Anisetta:public ENGINE{
public:
Anisetta(){
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;
check_by = CHECK_BY::FILE_ANY;
check_by_target = check_by_list{L"*.pd", L".pb"};
is_engine_certain = false;
};
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
*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;
}
}
}
@ -122,15 +134,16 @@ bool InsertApricoTHook()
for (DWORD i = processStartAddress + 0x1000; i < processStopAddress - 4; i++)
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);
// GROWL_DWORD3(hp.address, processStartAddress, processStopAddress);
//RegisterEngineType(ENGINE_APRICOT);
// RegisterEngineType(ENGINE_APRICOT);
// jichi 2/14/2015: disable cached GDI functions
ConsoleOutput("ApRicoT: disable GDI hooks");
@ -141,7 +154,8 @@ bool InsertApricoTHook()
return false;
}
bool ApricoT::attach_function() {
bool ApricoT::attach_function()
{
return InsertApricoTHook();
}

View File

@ -1,21 +1,25 @@
class ApricoT:public ENGINE{
public:
ApricoT(){
class ApricoT : public ENGINE
{
public:
ApricoT()
{
check_by=CHECK_BY::FILE;
check_by_target=L"arc.a*";
check_by = CHECK_BY::FILE;
check_by_target = L"arc.a*";
};
bool attach_function();
};
class ApricoTlast:public ApricoT{
public:
ApricoTlast(){
class ApricoTlast : public ApricoT
{
public:
ApricoTlast()
{
check_by=CHECK_BY::FILE;
check_by_target=L"arc.dat";
is_engine_certain=false;
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,32 +59,33 @@
bool InsertArtemis1Hook()
{
const BYTE bytes[] = {
0x83,0xc4, 0x0c, // add esp,0xc ; hook here
0x0f,0xb6,0xc0, // movzx eax,al
0x85,0xc0, // test eax,eax
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");
}
@ -115,36 +116,44 @@ bool InsertArtemis2Hook()
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;
}
@ -174,65 +183,79 @@ bool InsertArtemis3Hook()
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");
}
namespace{
bool a4(){
//高慢な奥さんは好きですか?~傲慢人妻教師の堕とし方~
std::vector<uint64_t> addrs;
for(DWORD func:{(DWORD)GetGlyphOutlineA,(DWORD)GetGlyphOutlineW})
namespace
{
bool a4()
{
auto addrs_ = findiatcallormov_all(func,processStartAddress,processStartAddress,processStopAddress,PAGE_EXECUTE);
// 高慢な奥さんは好きですか?~傲慢人妻教師の堕とし方~
std::vector<uint64_t> addrs;
for (DWORD func : {(DWORD)GetGlyphOutlineA, (DWORD)GetGlyphOutlineW})
{
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.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() {
bool Artemis::attach_function()
{
return InsertArtemis1Hook() || InsertArtemis2Hook() || InsertArtemis3Hook()||a4();
return InsertArtemis1Hook() || InsertArtemis2Hook() || InsertArtemis3Hook() || a4();
}

View File

@ -1,11 +1,13 @@
class Artemis:public ENGINE{
public:
Artemis(){
class Artemis : public ENGINE
{
public:
Artemis()
{
check_by=CHECK_BY::FILE;
check_by_target=L"*.pfs";
check_by = CHECK_BY::FILE;
check_by_target = L"*.pfs";
};
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.
@ -14,33 +14,35 @@ 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);
// 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()
@ -63,16 +65,17 @@ bool InsertAtelierKaguya2Hook()
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");
@ -99,14 +102,15 @@ bool InsertAtelierKaguya3Hook()
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");
@ -131,18 +135,22 @@ bool InsertAtelierKaguya4Hook()
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");
@ -169,14 +177,15 @@ bool InsertAtelierKaguya5Hook()
};
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");
@ -185,68 +194,72 @@ bool InsertAtelierKaguya5Hook()
}
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;
if (!addr)
return false;
addr = findfuncstart(addr,0x1000);
if (!addr) return false;
addr = findfuncstart(addr, 0x1000);
if (!addr)
return false;
HookParam hp;
hp.address = addr;
hp.offset=get_stack(1);
hp.offset = get_stack(1);
hp.type = USING_STRING;
return NewHook(hp, "Atelier KAGUYA3");
}
bool Atelier::attach_function() {
bool Atelier::attach_function()
{
return InsertAtelierHook() || InsertAtelierKaguya2Hook() ||InsertAtelierKaguyaX()|| InsertAtelierKaguya3Hook() || InsertAtelierKaguya4Hook() || InsertAtelierKaguya5Hook();
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,23 +1,28 @@
class Atelier:public ENGINE{
public:
Atelier(){
class Atelier : public ENGINE
{
public:
Atelier()
{
check_by=CHECK_BY::FILE;
check_by_target=L"message.dat";
check_by = CHECK_BY::FILE;
check_by_target = L"message.dat";
};
bool attach_function();
};
class Atelier2:public ENGINE{
public:
Atelier2(){
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"));
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();

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
};
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
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
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,
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
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;
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(){
class akatombo : public ENGINE
{
public:
akatombo()
{
check_by=CHECK_BY::RESOURCE_STR;
check_by_target=L"akatombo";
is_engine_certain=false;
check_by = CHECK_BY::RESOURCE_STR;
check_by_target = L"akatombo";
is_engine_certain = false;
};
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;