216 lines
6.2 KiB
C++
Raw Normal View History

2024-02-07 20:59:24 +08:00
#include"V8.h"
#include"v8/v8.h"
2024-03-20 20:11:20 +08:00
#if 0
2024-02-07 20:59:24 +08:00
// Artikash 6/23/2019: V8 (JavaScript runtime) has rcx = string** at v8::String::Write
// sample game https://www.freem.ne.jp/dl/win/18963
bool InsertV8Hook(HMODULE module)
{
uint64_t addr1 = (uint64_t)GetProcAddress(module, "?Write@String@v8@@QEBAHPEAGHHH@Z"),
// Artikash 6/7/2021: Add new hook for new version of V8 used by RPG Maker MZ
addr2 = (uint64_t)GetProcAddress(module, "??$WriteToFlat@G@String@internal@v8@@SAXV012@PEAGHH@Z");
if (addr1 || addr2)
{
std::tie(spDefault.minAddress, spDefault.maxAddress) = Util::QueryModuleLimits(module);
spDefault.maxRecords = Util::SearchMemory(spDefault.pattern, spDefault.length, PAGE_EXECUTE, spDefault.minAddress, spDefault.maxAddress).size() * 20;
ConsoleOutput("JavaScript hook is known to be low quality: try searching for hooks if you don't like it");
}
auto succ=false;
if (addr1)
{
HookParam hp;
hp.type = USING_STRING | CODEC_UTF16;
hp.address = addr1;
hp.text_fun = [](hook_stack* stack, HookParam *hp, uintptr_t* data, uintptr_t* split, size_t* count)
{
*data=(*(uintptr_t*)(stack->rcx))+23;
int len = *(int*)(*data - 4);
2024-02-13 18:57:28 +08:00
if(wcslen((wchar_t*)*data)*2<len)return;
2024-02-07 20:59:24 +08:00
*count=len*2;
};
succ|=NewHook(hp, "JavaScript");
}
if (addr2)
{
HookParam hp;
hp.type = USING_STRING | CODEC_UTF16;
hp.address = addr2;
hp.text_fun = [](hook_stack* stack, HookParam *hp, uintptr_t* data, uintptr_t* split, size_t* count)
{
*data=(stack->rcx)+11;
int len = *(int*)(*data - 4);
2024-02-13 18:57:28 +08:00
if(wcslen((wchar_t*)*data)*2<len)return;
2024-02-07 20:59:24 +08:00
*count=len*2;
};
succ|=NewHook(hp, "JavaScript");
}
return succ;
}
namespace{
uintptr_t forwardsearch(BYTE* b,int size,uintptr_t addr,int range){
for(int i=0;i<range;i++){
bool ok=true;
for(int j=0;j<size;j++){
if((*(BYTE*)(b+j))==XX)continue;
if((*(BYTE*)(b+j))!=((*(BYTE*)(addr+i+j)))){
ok=false;break;
}
}
if(ok){
return addr+i;
}
}
return 0;
}
regs andregimm(BYTE* b){
if(*b==0x81)
switch (*(b+1))
{
case 0xe1:return regs::rcx;//rcx
case 0xe2:return regs::rdx;//rdx
case 0xe3:return regs::rbp;//rbx
case 0xe5:return regs::rbp;//rbp
case 0xe6:return regs::rsi;//rsi
case 0xe7:return regs::rdi;//rdi
default:return regs::invalid;
}
else
return regs::invalid;
}
std::vector<HookParam> hookw(HMODULE module){
const BYTE BYTES[] = {
0x81,XX,0x00,0xf8,0x00,0x00
};
std::vector<HookParam>save;
auto addrs = Util::SearchMemory(BYTES, sizeof(BYTES), PAGE_EXECUTE, processStartAddress, processStopAddress);
for(auto addr:addrs){
auto addrsave=addr;
BYTE sig1[]={0x81,XX,0x00,0xD8,0x00,0x00};
BYTE sig2[]={0x81,XX,0x00,0xFC,0x00,0x00};
BYTE sig3[]={0x81,XX,0x00,0xDC,0x00,0x00};
BYTE sig4[]={XX,0x00,0x24,0xA0,0xFC};
addr=forwardsearch(sig1,sizeof(sig1),addr,0x20);
if(addr==0)continue;
addr=forwardsearch(sig2,sizeof(sig2),addr,0x100);
if(addr==0)continue;
addr=forwardsearch(sig3,sizeof(sig3),addr,0x20);
if(addr==0)continue;
addr=forwardsearch(sig4,sizeof(sig4),addr,0x20);
if(addr==0)continue;
auto off=andregimm((BYTE*)addrsave);
if(off==regs::invalid)continue;
HookParam hp;
hp.address = (uint64_t)addrsave ;
hp.type = CODEC_UTF16|NO_CONTEXT ;
hp.offset =get_reg(off);
save.push_back(hp);
}
return save;
}
2024-03-20 20:11:20 +08:00
#if 0
2024-02-07 20:59:24 +08:00
std::vector<HookParam> v8hook1(HMODULE module) {
const BYTE BYTES[] = {
0x81,0xE1,0x00,0xF8,0x00,0x00,
0x41,0xBE,0x01,0x00,0x00,0x00,
0x81,0xF9,0x00,0xD8,0x00,0x00
};
auto addrs = Util::SearchMemory(BYTES, sizeof(BYTES), PAGE_EXECUTE, processStartAddress, processStopAddress);
if (addrs.size() != 1)return {};
auto addr = (uint64_t)addrs[0];
const BYTE start[] = {
0xCC
};
const BYTE start2[] = {
0x41,0x57,0x41,0x56,0x41,0x55,0x41,0x54
};
addr=reverseFindBytes(start, sizeof(start), addr - 0x1000, addr);
if (addr == 0)return {};
addr += 1;
addrs = findxref_reverse(addr, addr - 0x10000, addr + 0x10000);
if (addrs.size() != 1)return {};
addr = addrs[0];
addr = reverseFindBytes(start2, sizeof(start2), addr - 0x1000, addr);
if (addr == 0)return {};
addrs = findxref_reverse(addr, addr - 0x10000, addr + 0x10000);
std::vector<HookParam> save;
for (auto addr : addrs) {
addr = reverseFindBytes(start2, sizeof(start2), addr - 0x1000, addr);
if (addr == 0)continue;
HookParam hp;
hp.address = (uint64_t)addr;
hp.type = USING_STRING | CODEC_UTF16 | DATA_INDIRECT;
hp.offset=get_reg(regs::rcx);
hp.padding = 0xC;
hp.index = 0;
save.push_back(hp);
}
return save;
}
2024-03-20 20:11:20 +08:00
#endif
2024-02-07 20:59:24 +08:00
bool innerHTML(HMODULE module) {
//花葬
//result = sub_142DF3CA0(a2, v5, 1u, (__int64)"innerHTML", a3);
//r10当全为ascii是普通string否则为wchar_t
//a3是一个callback,并不是字符串。
char innerHTML[]="innerHTML";
auto addr = MemDbg::findBytes(innerHTML, sizeof(innerHTML), processStartAddress, processStopAddress);
ConsoleOutput("%x",addr);
if(addr==0)return false;
bool ok=false;
for(auto _addr=processStartAddress+4;_addr<processStopAddress;_addr+=1){
if((_addr+*(int*)(_addr-4) )==addr){
ConsoleOutput("%x",_addr-processStartAddress);
for(int i=0;i<0x20;i++){
if(*(BYTE*)(_addr+i)==0xe8){
uintptr_t subaddr=_addr+i+5+*(int*)(_addr+i+1);
HookParam hp;
hp.address = (uint64_t)subaddr;
hp.type = USING_STRING | CODEC_UTF16 ;
hp.offset=get_reg(regs::r10);
hp.text_fun=[](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
auto text =stack->r10;
if(strlen((char*) text)>1){
hp->type=USING_STRING|CODEC_UTF8|NO_CONTEXT;
*split=0x1;
*len=strrchr((char*)text,'>')+1-(char*)text;
}
else{
hp->type=USING_STRING|CODEC_UTF16|NO_CONTEXT;
*split=0x10;
*len=wcsrchr((wchar_t*)text,L'>')+1-(wchar_t*)text;
*len*=2;
}
};
ok|=NewHook(hp,"innerHTML");
}
}
}
}
return ok;
}
bool addhooks(HMODULE module){
if (GetProcAddress(module, "?Write@String@v8@@QEBAHPEAVIsolate@2@PEAGHHH@Z") == 0)return false;
bool success=false;
for(auto h:hookw(module)){
success|=NewHook(h,"electronW");
}
return innerHTML(module)|| success;
}
}
2024-02-14 23:48:36 +08:00
2024-03-20 20:11:20 +08:00
#endif
2024-02-14 23:48:36 +08:00
bool V8::attach_function_() {
2024-03-20 20:11:20 +08:00
return tryhookv8();
2024-02-07 20:59:24 +08:00
}