2024-03-20 20:11:20 +08:00
|
|
|
|
|
|
|
|
|
#include"common.h"
|
|
|
|
|
#include"defs.h"
|
2024-03-15 21:51:59 +08:00
|
|
|
|
#include"types.h"
|
|
|
|
|
#include"main.h"
|
|
|
|
|
#include"v8.h"
|
2024-03-19 23:14:08 +08:00
|
|
|
|
#include"embed_util.h"
|
2024-03-20 23:20:17 +08:00
|
|
|
|
#include"stackoffset.hpp"
|
2024-03-15 21:51:59 +08:00
|
|
|
|
namespace{
|
2024-03-25 14:59:33 +08:00
|
|
|
|
constexpr auto magicsend =L"\x01LUNAFROMJS\x01";
|
|
|
|
|
constexpr auto magicrecv =L"\x01LUNAFROMHOST\x01";
|
2024-03-15 21:51:59 +08:00
|
|
|
|
bool hookClipboard(){
|
|
|
|
|
HookParam hp;
|
|
|
|
|
hp.address=(uintptr_t)SetClipboardData;
|
|
|
|
|
hp.type= USING_STRING|CODEC_UTF16|EMBED_ABLE|EMBED_BEFORE_SIMPLE;
|
|
|
|
|
hp.text_fun=[](hook_stack* stack, HookParam *hp, uintptr_t* data, uintptr_t* split, size_t* len){
|
2024-03-20 23:20:17 +08:00
|
|
|
|
HGLOBAL hClipboardData=(HGLOBAL)stack->ARG2;
|
2024-03-25 14:59:33 +08:00
|
|
|
|
auto text=(wchar_t*)GlobalLock(hClipboardData);
|
|
|
|
|
if(startWith(text,magicsend)){
|
|
|
|
|
text+=wcslen(magicsend);
|
|
|
|
|
auto spl=wcschr(text,L'\x02');
|
|
|
|
|
*split=std::stoi(std::wstring(text,spl-text));
|
|
|
|
|
text=spl+1;
|
|
|
|
|
*data=(uintptr_t)text;
|
|
|
|
|
*len=wcslen(text)*2;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-15 21:51:59 +08:00
|
|
|
|
GlobalUnlock(hClipboardData);
|
|
|
|
|
};
|
|
|
|
|
hp.hook_after=[](hook_stack*s,void* data, size_t len){
|
2024-03-25 14:59:33 +08:00
|
|
|
|
std::wstring transwithfont=magicrecv;
|
2024-03-19 23:14:08 +08:00
|
|
|
|
transwithfont+=embedsharedmem->fontFamily;
|
2024-03-25 14:59:33 +08:00
|
|
|
|
transwithfont+=L'\x02';
|
2024-03-19 23:14:08 +08:00
|
|
|
|
transwithfont+=std::wstring((wchar_t*)data,len/2);
|
2024-03-19 23:45:33 +08:00
|
|
|
|
HGLOBAL hClipboardData = GlobalAlloc(GMEM_MOVEABLE, transwithfont.size()*2 +2);
|
|
|
|
|
auto pchData = (wchar_t*)GlobalLock(hClipboardData);
|
2024-03-19 23:14:08 +08:00
|
|
|
|
wcscpy(pchData, (wchar_t*)transwithfont.c_str());
|
2024-03-15 21:51:59 +08:00
|
|
|
|
GlobalUnlock(hClipboardData);
|
2024-03-20 23:20:17 +08:00
|
|
|
|
s->ARG2=(uintptr_t)hClipboardData;
|
2024-03-15 21:51:59 +08:00
|
|
|
|
};
|
|
|
|
|
return NewHook(hp,"hookClipboard");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
namespace v8script{
|
|
|
|
|
HMODULE hmodule;
|
2024-03-17 00:16:21 +08:00
|
|
|
|
|
|
|
|
|
typedef void(*RequestInterrupt_callback)(void*, void*);
|
2024-03-15 21:51:59 +08:00
|
|
|
|
#ifndef _WIN64
|
|
|
|
|
|
2024-03-17 00:16:21 +08:00
|
|
|
|
#define fnRequestInterrupt "?RequestInterrupt@Isolate@v8@@QAEXP6AXPAV12@PAX@Z1@Z"
|
2024-03-15 21:51:59 +08:00
|
|
|
|
#define fnNewFromUtf8v2 "?NewFromUtf8@String@v8@@SA?AV?$MaybeLocal@VString@v8@@@2@PAVIsolate@2@PBDW4NewStringType@2@H@Z"
|
|
|
|
|
#define fnNewFromUtf8v1 "?NewFromUtf8@String@v8@@SA?AV?$Local@VString@v8@@@2@PAVIsolate@2@PBDW4NewStringType@12@H@Z"
|
|
|
|
|
#define fnGetCurrentContext "?GetCurrentContext@Isolate@v8@@QAE?AV?$Local@VContext@v8@@@2@XZ"
|
|
|
|
|
#define fnCompilev1 "?Compile@Script@v8@@SA?AV?$Local@VScript@v8@@@2@V?$Handle@VString@v8@@@2@PAVScriptOrigin@2@@Z"
|
|
|
|
|
#define fnCompilev12 "?Compile@Script@v8@@SA?AV?$Local@VScript@v8@@@2@V?$Local@VString@v8@@@2@PAVScriptOrigin@2@@Z"
|
|
|
|
|
#define fnRunv1 "?Run@Script@v8@@QAE?AV?$Local@VValue@v8@@@2@XZ"
|
|
|
|
|
#define fnCompilev2 "?Compile@Script@v8@@SA?AV?$MaybeLocal@VScript@v8@@@2@V?$Local@VContext@v8@@@2@V?$Local@VString@v8@@@2@PAVScriptOrigin@2@@Z"
|
|
|
|
|
#define fnRunv2 "?Run@Script@v8@@QAE?AV?$MaybeLocal@VValue@v8@@@2@V?$Local@VContext@v8@@@2@@Z"
|
|
|
|
|
|
|
|
|
|
#else
|
2024-03-17 00:16:21 +08:00
|
|
|
|
#define fnRequestInterrupt "?RequestInterrupt@Isolate@v8@@QEAAXP6AXPEAV12@PEAX@Z1@Z"
|
2024-03-15 21:51:59 +08:00
|
|
|
|
#define fnNewFromUtf8v2 "?NewFromUtf8@String@v8@@SA?AV?$MaybeLocal@VString@v8@@@2@PEAVIsolate@2@PEBDW4NewStringType@2@H@Z"
|
|
|
|
|
#define fnNewFromUtf8v1 "?NewFromUtf8@String@v8@@SA?AV?$Local@VString@v8@@@2@PEAVIsolate@2@PEBDW4NewStringType@12@H@Z"
|
|
|
|
|
#define fnGetCurrentContext "?GetCurrentContext@Isolate@v8@@QEAA?AV?$Local@VContext@v8@@@2@XZ"
|
|
|
|
|
#define fnCompilev1 "?Compile@Script@v8@@SA?AV?$Local@VScript@v8@@@2@V?$Handle@VString@v8@@@2@PEAVScriptOrigin@2@@Z"
|
|
|
|
|
#define fnCompilev12 fnCompilev1
|
|
|
|
|
#define fnRunv1 "?Run@Script@v8@@QEAA?AV?$Local@VValue@v8@@@2@XZ"
|
|
|
|
|
#define fnCompilev2 "?Compile@Script@v8@@SA?AV?$MaybeLocal@VScript@v8@@@2@V?$Local@VContext@v8@@@2@V?$Local@VString@v8@@@2@PEAVScriptOrigin@2@@Z"
|
|
|
|
|
#define fnRunv2 "?Run@Script@v8@@QEAA?AV?$MaybeLocal@VValue@v8@@@2@V?$Local@VContext@v8@@@2@@Z"
|
2024-03-17 00:16:21 +08:00
|
|
|
|
|
2024-03-15 21:51:59 +08:00
|
|
|
|
#endif
|
2024-03-20 23:20:17 +08:00
|
|
|
|
typedef void*(THISCALL *GetCurrentContextt)(void*, void*);
|
|
|
|
|
typedef void*(THISCALL *Runt1)(void*,void*);
|
|
|
|
|
typedef void*(THISCALL *Runt2)(void*,void*,void*);
|
|
|
|
|
typedef void*(THISCALL *RequestInterruptt)(void*, RequestInterrupt_callback, void*);
|
|
|
|
|
|
2024-03-15 21:51:59 +08:00
|
|
|
|
typedef void*(*NewFromUtf8t)(void*, void*, const char*, int, int) ;
|
|
|
|
|
typedef void*(*Compilet)(void*, void*, void*, void*);
|
2024-03-17 00:16:21 +08:00
|
|
|
|
RequestInterruptt RequestInterrupt;
|
|
|
|
|
NewFromUtf8t NewFromUtf8=0,NewFromUtf8v2,NewFromUtf8v1;
|
|
|
|
|
GetCurrentContextt GetCurrentContext ;
|
|
|
|
|
Compilet Compile;
|
|
|
|
|
void* Run;
|
2024-03-15 21:51:59 +08:00
|
|
|
|
bool v8runscript_isolate(void* isolate){
|
|
|
|
|
|
|
|
|
|
if(isolate==0)return false;
|
2024-03-17 00:16:21 +08:00
|
|
|
|
RequestInterrupt= (decltype(RequestInterrupt))GetProcAddress(hmodule, fnRequestInterrupt);
|
|
|
|
|
|
|
|
|
|
NewFromUtf8v2 = (decltype(NewFromUtf8))GetProcAddress(hmodule, fnNewFromUtf8v2);
|
|
|
|
|
NewFromUtf8v1 = (decltype(NewFromUtf8))GetProcAddress(hmodule, fnNewFromUtf8v1);
|
2024-03-15 21:51:59 +08:00
|
|
|
|
|
|
|
|
|
GetCurrentContext = (decltype(GetCurrentContext))GetProcAddress(hmodule, fnGetCurrentContext);
|
|
|
|
|
|
|
|
|
|
if(NewFromUtf8v1)
|
|
|
|
|
{
|
|
|
|
|
NewFromUtf8=NewFromUtf8v1;
|
|
|
|
|
Compile = (decltype(Compile))GetProcAddress(hmodule, fnCompilev1);
|
2024-03-17 00:16:21 +08:00
|
|
|
|
if(!Compile) Compile=(decltype(Compile))GetProcAddress(hmodule, fnCompilev12);
|
2024-03-15 21:51:59 +08:00
|
|
|
|
Run = (decltype(Run))GetProcAddress(hmodule, fnRunv1);
|
|
|
|
|
}
|
|
|
|
|
else if(NewFromUtf8v2)
|
|
|
|
|
{
|
|
|
|
|
NewFromUtf8=NewFromUtf8v2;
|
|
|
|
|
Compile = (decltype(Compile))GetProcAddress(hmodule, fnCompilev2);
|
|
|
|
|
Run = (decltype(Run))GetProcAddress(hmodule, fnRunv2);
|
|
|
|
|
}
|
2024-03-17 00:16:21 +08:00
|
|
|
|
ConsoleOutput("%p %p",NewFromUtf8v1,NewFromUtf8v2);
|
|
|
|
|
ConsoleOutput("%p %p %p %p",GetCurrentContext, NewFromUtf8, Compile, Run);
|
|
|
|
|
if(!(GetCurrentContext && NewFromUtf8 && Compile && Run && RequestInterrupt))return false;
|
|
|
|
|
|
|
|
|
|
if(RequestInterrupt==0)return false;
|
|
|
|
|
RequestInterrupt(isolate,+[](void*isolate,void*){
|
|
|
|
|
void* context;
|
|
|
|
|
void* v8string;
|
|
|
|
|
void* script;
|
|
|
|
|
void* useless;
|
|
|
|
|
ConsoleOutput("isolate %p",isolate);
|
|
|
|
|
GetCurrentContext(isolate,&context);
|
|
|
|
|
ConsoleOutput("context %p",context);
|
|
|
|
|
if(context==0)return;
|
|
|
|
|
NewFromUtf8(&v8string,isolate,LoadResData(L"lunajspatch",L"JSSOURCE").c_str(),1,-1);
|
|
|
|
|
ConsoleOutput("v8string %p",v8string);
|
|
|
|
|
if(v8string==0)return;
|
|
|
|
|
if(NewFromUtf8v1)
|
|
|
|
|
{
|
|
|
|
|
Compile(&script,v8string,0,0);
|
|
|
|
|
ConsoleOutput("script %p",script);
|
|
|
|
|
if(script==0)return;
|
|
|
|
|
((Runt1)Run)(script,&useless);
|
2024-03-20 22:51:24 +08:00
|
|
|
|
ConsoleOutput("useless %p",useless);
|
2024-03-17 00:16:21 +08:00
|
|
|
|
}
|
|
|
|
|
else if(NewFromUtf8v2)
|
|
|
|
|
{
|
|
|
|
|
Compile(&script,context,v8string,0);
|
|
|
|
|
ConsoleOutput("script %p",script);
|
|
|
|
|
if(script==0)return ;
|
|
|
|
|
((Runt2)Run)(script,&useless,context);
|
|
|
|
|
ConsoleOutput("useless %p",useless);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
},0);
|
2024-03-15 21:51:59 +08:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void v8runscript_isolate_bypass(hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len){
|
2024-03-20 20:11:20 +08:00
|
|
|
|
|
2024-03-15 21:51:59 +08:00
|
|
|
|
hp->type=HOOK_EMPTY;hp->text_fun=nullptr;
|
2024-03-20 20:11:20 +08:00
|
|
|
|
static bool runonce=false;
|
|
|
|
|
if(runonce)return;
|
|
|
|
|
runonce=true;
|
2024-03-20 23:20:17 +08:00
|
|
|
|
|
|
|
|
|
auto isolate=(void*)stack->ARG2;//测试正确,且和v8::Isolate::GetCurrent结果相同
|
2024-03-15 21:51:59 +08:00
|
|
|
|
v8runscript_isolate(isolate);
|
|
|
|
|
}
|
|
|
|
|
void* v8getcurrisolate(HMODULE hmod){
|
|
|
|
|
#ifndef _WIN64
|
|
|
|
|
#define fnGetCurrent "?GetCurrent@Isolate@v8@@SAPAV12@XZ"
|
|
|
|
|
#define fnTryGetCurrent "?TryGetCurrent@Isolate@v8@@SAPAV12@XZ"
|
|
|
|
|
#else
|
|
|
|
|
#define fnGetCurrent "?GetCurrent@Isolate@v8@@SAPEAV12@XZ"
|
|
|
|
|
#define fnTryGetCurrent "?TryGetCurrent@Isolate@v8@@SAPEAV12@XZ"
|
|
|
|
|
#endif
|
|
|
|
|
void* GetCurrent;
|
|
|
|
|
GetCurrent = GetProcAddress(hmod, fnGetCurrent);
|
|
|
|
|
if ( !GetCurrent )
|
|
|
|
|
GetCurrent = GetProcAddress(hmod, fnTryGetCurrent);
|
|
|
|
|
if(!GetCurrent)return 0;
|
|
|
|
|
auto isolate=((void*(*)())GetCurrent)();
|
|
|
|
|
return isolate;
|
|
|
|
|
}
|
|
|
|
|
bool v8runscript(HMODULE _hmodule){
|
|
|
|
|
auto isolate=v8getcurrisolate(_hmodule);
|
|
|
|
|
if(isolate)
|
|
|
|
|
return v8runscript_isolate(isolate);
|
|
|
|
|
#ifndef _WIN64
|
2024-03-20 20:11:20 +08:00
|
|
|
|
#define fnisolategetters {"?New@Number@v8@@SA?AV?$Local@VNumber@v8@@@2@PEAVIsolate@2@N@Z","?New@Number@v8@@SA?AV?$Local@VNumber@v8@@@2@PAVIsolate@2@N@Z","?NewFromUtf8@String@v8@@SA?AV?$Local@VString@v8@@@2@PAVIsolate@2@PBDW4NewStringType@12@H@Z"}
|
2024-03-15 21:51:59 +08:00
|
|
|
|
#else
|
2024-03-20 20:11:20 +08:00
|
|
|
|
#define fnisolategetters {"?New@Integer@v8@@SA?AV?$Local@VInteger@v8@@@2@PEAVIsolate@2@H@Z","?New@Number@v8@@SA?AV?$Local@VNumber@v8@@@2@PEAVIsolate@2@N@Z","?New@Number@v8@@SA?AV?$Local@VNumber@v8@@@2@PAVIsolate@2@N@Z","?NewFromUtf8@String@v8@@SA?AV?$Local@VString@v8@@@2@PEAVIsolate@2@PEBDW4NewStringType@12@H@Z","?Utf8Length@String@v8@@QEBAHPEAVIsolate@2@@Z"}
|
2024-03-15 21:51:59 +08:00
|
|
|
|
#endif
|
2024-03-20 20:11:20 +08:00
|
|
|
|
bool succ=false;
|
|
|
|
|
for(auto fnisolategetter:fnisolategetters){
|
|
|
|
|
auto isolategetter=GetProcAddress(_hmodule,fnisolategetter);
|
|
|
|
|
if(!isolategetter)continue;
|
|
|
|
|
hmodule=_hmodule;
|
|
|
|
|
HookParam hp;
|
|
|
|
|
hp.address=(uintptr_t)isolategetter;
|
|
|
|
|
hp.text_fun=v8runscript_isolate_bypass;
|
|
|
|
|
succ|= NewHook(hp,"isolategetter");
|
|
|
|
|
}
|
|
|
|
|
return succ;
|
2024-03-15 21:51:59 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
namespace{
|
2024-03-20 20:11:20 +08:00
|
|
|
|
#ifndef _WIN64
|
|
|
|
|
#define v8StringLength "?Length@String@v8@@QBEHXZ"
|
|
|
|
|
#define v8StringWriteUtf8 "?WriteUtf8@String@v8@@QBEHPADHPAHH@Z"
|
|
|
|
|
#define v8StringUtf8Length "?Utf8Length@String@v8@@QBEHXZ"
|
|
|
|
|
#define v8StringWrite "?Write@String@v8@@QBEHPAGHHH@Z"
|
|
|
|
|
#define v8StringWriteIsolate "?Write@String@v8@@QBEHPAVIsolate@2@PAGHHH@Z"
|
|
|
|
|
#else
|
|
|
|
|
#define v8StringLength "?Length@String@v8@@QEBAHXZ"
|
|
|
|
|
#define v8StringWriteUtf8 "?WriteUtf8@String@v8@@QEBAHPEADHPEAHH@Z"
|
|
|
|
|
#define v8StringUtf8Length "?Utf8Length@String@v8@@QEBAHXZ"
|
|
|
|
|
#define v8StringWrite "?Write@String@v8@@QEBAHPEAGHHH@Z"
|
|
|
|
|
#define v8StringWriteIsolate "?Write@String@v8@@QEBAHPEAVIsolate@2@PEAGHHH@Z"
|
|
|
|
|
#endif
|
|
|
|
|
uintptr_t WriteUtf8;
|
|
|
|
|
uintptr_t Utf8Length;
|
|
|
|
|
bool hookstring(HMODULE hm){
|
2024-03-15 21:51:59 +08:00
|
|
|
|
WriteUtf8=(uintptr_t)GetProcAddress(hm,v8StringWriteUtf8);
|
|
|
|
|
Utf8Length=(uintptr_t)GetProcAddress(hm,v8StringUtf8Length);
|
2024-03-20 20:11:20 +08:00
|
|
|
|
if(WriteUtf8==0||Utf8Length==0)return false;
|
|
|
|
|
|
|
|
|
|
|
2024-03-15 21:51:59 +08:00
|
|
|
|
HookParam hp;
|
|
|
|
|
hp.type=USING_STRING|CODEC_UTF8;
|
|
|
|
|
hp.text_fun=
|
|
|
|
|
[](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len)
|
|
|
|
|
{
|
2024-03-20 20:11:20 +08:00
|
|
|
|
|
2024-03-20 23:20:17 +08:00
|
|
|
|
auto length=((size_t(THISCALL *)(void*))Utf8Length)((void*)stack->THISCALLTHIS);
|
2024-03-15 21:51:59 +08:00
|
|
|
|
if(!length)return;
|
|
|
|
|
auto u8str=new char[length+1];
|
|
|
|
|
int writen;
|
2024-03-20 23:20:17 +08:00
|
|
|
|
((size_t(THISCALL *)(void*,char*,int,int*,int))WriteUtf8)((void*)stack->THISCALLTHIS,u8str,length,&writen,0);
|
|
|
|
|
*data=(uintptr_t)u8str;
|
2024-03-15 21:51:59 +08:00
|
|
|
|
*len=length;
|
|
|
|
|
|
|
|
|
|
};
|
2024-03-16 21:47:09 +08:00
|
|
|
|
hp.filter_fun=[](void* data, size_t* len, HookParam* hp){
|
|
|
|
|
if(strstr((char*)data,R"(\\?\)")!=0)return false;//过滤路径
|
|
|
|
|
return true;
|
|
|
|
|
};
|
2024-03-20 20:11:20 +08:00
|
|
|
|
bool succ=false;
|
|
|
|
|
|
|
|
|
|
auto pv8StringLength=GetProcAddress(hm,v8StringLength);
|
|
|
|
|
if(pv8StringLength){
|
|
|
|
|
|
|
|
|
|
hp.address=(uintptr_t)pv8StringLength;
|
|
|
|
|
succ|=NewHook(hp,"v8::String::Length");
|
|
|
|
|
}
|
|
|
|
|
auto pv8StringWrite=GetProcAddress(hm,v8StringWrite);
|
|
|
|
|
if(pv8StringWrite){
|
|
|
|
|
|
|
|
|
|
hp.address=(uintptr_t)pv8StringWrite;
|
|
|
|
|
succ|=NewHook(hp,"v8::String::Write");
|
|
|
|
|
}
|
|
|
|
|
auto pv8StringWriteIsolate=GetProcAddress(hm,v8StringWriteIsolate);
|
|
|
|
|
if(pv8StringWriteIsolate){
|
|
|
|
|
hp.address=(uintptr_t)pv8StringWriteIsolate;
|
|
|
|
|
succ|=NewHook(hp,"v8::String::Write::isolate");
|
|
|
|
|
}
|
|
|
|
|
return succ;
|
2024-03-15 21:51:59 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2024-03-20 20:11:20 +08:00
|
|
|
|
bool tryhookv8_internal(HMODULE hm){
|
|
|
|
|
auto succ=hookstring(hm);
|
2024-03-15 21:51:59 +08:00
|
|
|
|
if(v8script::v8runscript(hm))
|
|
|
|
|
succ|= hookClipboard();
|
|
|
|
|
return succ;
|
2024-03-20 20:11:20 +08:00
|
|
|
|
}
|
|
|
|
|
bool tryhookv8() {
|
|
|
|
|
for (const wchar_t* moduleName : { (const wchar_t*)NULL, L"node.dll", L"nw.dll" }) {
|
|
|
|
|
auto hm=GetModuleHandleW(moduleName);
|
|
|
|
|
if(hm==0)continue;
|
|
|
|
|
bool ok=tryhookv8_internal(hm);
|
|
|
|
|
if(ok) return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|