mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-11-26 23:34:01 +08:00
format
This commit is contained in:
parent
bd62f89e9b
commit
edc5efec99
@ -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;
|
||||
}
|
@ -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();
|
||||
};
|
@ -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");
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
};
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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;
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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;
|
||||
}
|
@ -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();
|
||||
|
@ -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() | __();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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"));
|
||||
};
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
@ -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();
|
||||
};
|
@ -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");
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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;
|
||||
};
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
};
|
@ -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();
|
||||
}
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
@ -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();
|
||||
};
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user