mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-12-24 04:04:14 +08:00
sizet
This commit is contained in:
parent
48f521b909
commit
e518d6431f
@ -1,183 +1,197 @@
|
||||
#include"LightVN.h"
|
||||
namespace{
|
||||
bool _1() {
|
||||
//void __fastcall sub_1404B7960(void **Src)
|
||||
//HQ-1C*0@4B7960:LightApp.exe
|
||||
const BYTE BYTES[] = {
|
||||
0x90,
|
||||
XX4,
|
||||
XX4,
|
||||
0x48,0x8b,0xce,
|
||||
0xe8,XX4,
|
||||
0x90,
|
||||
0x48,0x8b,XX2,
|
||||
0x48,0x83,0xfa,0x08,
|
||||
0x72,0x36,
|
||||
0x48,0x8D,0x14,0x55,0x02,0x00,0x00,0x00,
|
||||
0x48,0x8b,XX2,
|
||||
0x48,0x8b,0xc1,
|
||||
0x48,0x81,0xFA,0x00,0x10,0x00,0x00,
|
||||
0x72,0x19,
|
||||
0x48,0x83,0xC2,0x27,
|
||||
0x48,0x8b,XX2,
|
||||
0x48,0x2b,0xc1,
|
||||
0x48,0x83,0xC0,0xF8,
|
||||
0x48,0x83,0xF8,0x1F ,
|
||||
0x0f,0x87,XX4,
|
||||
0xe8,XX4
|
||||
#include "LightVN.h"
|
||||
namespace
|
||||
{
|
||||
bool _1()
|
||||
{
|
||||
// void __fastcall sub_1404B7960(void **Src)
|
||||
// HQ-1C*0@4B7960:LightApp.exe
|
||||
const BYTE BYTES[] = {
|
||||
0x90,
|
||||
XX4,
|
||||
XX4,
|
||||
0x48, 0x8b, 0xce,
|
||||
0xe8, XX4,
|
||||
0x90,
|
||||
0x48, 0x8b, XX2,
|
||||
0x48, 0x83, 0xfa, 0x08,
|
||||
0x72, 0x36,
|
||||
0x48, 0x8D, 0x14, 0x55, 0x02, 0x00, 0x00, 0x00,
|
||||
0x48, 0x8b, XX2,
|
||||
0x48, 0x8b, 0xc1,
|
||||
0x48, 0x81, 0xFA, 0x00, 0x10, 0x00, 0x00,
|
||||
0x72, 0x19,
|
||||
0x48, 0x83, 0xC2, 0x27,
|
||||
0x48, 0x8b, XX2,
|
||||
0x48, 0x2b, 0xc1,
|
||||
0x48, 0x83, 0xC0, 0xF8,
|
||||
0x48, 0x83, 0xF8, 0x1F,
|
||||
0x0f, 0x87, XX4,
|
||||
0xe8, XX4
|
||||
|
||||
};
|
||||
auto suc = false;
|
||||
auto addrs = Util::SearchMemory(BYTES, sizeof(BYTES), PAGE_EXECUTE, processStartAddress, processStopAddress);
|
||||
for (auto addr : addrs)
|
||||
{
|
||||
ConsoleOutput("LightVN %p", addr);
|
||||
const BYTE aligned[] = {0xCC, 0xCC, 0xCC, 0xCC};
|
||||
addr = reverseFindBytes(aligned, sizeof(aligned), addr - 0x100, addr);
|
||||
if (addr == 0)
|
||||
continue;
|
||||
addr += 4;
|
||||
ConsoleOutput("LightVN %p", addr);
|
||||
HookParam hp;
|
||||
hp.address = addr;
|
||||
hp.type = CODEC_UTF16 | USING_STRING | DATA_INDIRECT;
|
||||
hp.index = 0;
|
||||
hp.offset = get_reg(regs::rcx);
|
||||
hp.filter_fun = [](void *data, size_t *len, HookParam *hp)
|
||||
{
|
||||
std::wstring s((wchar_t *)data, *len / 2);
|
||||
if (s.substr(s.size() - 2, 2) == L"\\w")
|
||||
*len -= 4;
|
||||
return true;
|
||||
};
|
||||
suc |= NewHook(hp, "LightVN");
|
||||
}
|
||||
return suc;
|
||||
}
|
||||
bool _2()
|
||||
{
|
||||
// https://vndb.org/r86006
|
||||
// ファーストキス(体験版)
|
||||
// https://vndb.org/r85992
|
||||
// フサの大正女中ぐらし
|
||||
|
||||
};
|
||||
auto suc=false;
|
||||
auto addrs = Util::SearchMemory(BYTES, sizeof(BYTES), PAGE_EXECUTE, processStartAddress, processStopAddress);
|
||||
for (auto addr : addrs) {
|
||||
ConsoleOutput("LightVN %p", addr);
|
||||
const BYTE aligned[] = { 0xCC,0xCC,0xCC,0xCC };
|
||||
addr = reverseFindBytes(aligned, sizeof(aligned), addr - 0x100, addr);
|
||||
if (addr == 0)continue;
|
||||
addr += 4;
|
||||
ConsoleOutput("LightVN %p", addr);
|
||||
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
|
||||
};
|
||||
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
|
||||
if (addr == 0)
|
||||
return 0;
|
||||
addr = MemDbg::findEnclosingAlignedFunction(addr);
|
||||
if (addr == 0)
|
||||
return 0;
|
||||
HookParam hp;
|
||||
hp.address = addr;
|
||||
hp.type = CODEC_UTF16 | USING_STRING|DATA_INDIRECT;
|
||||
hp.index = 0;
|
||||
hp.offset=get_reg(regs::rcx);
|
||||
hp.filter_fun = [](void* data, size_t* len, HookParam* hp) {
|
||||
std::wstring s((wchar_t*)data, *len / 2);
|
||||
if (s.substr(s.size() - 2, 2) == L"\\w")
|
||||
*len -= 4;
|
||||
hp.type = CODEC_UTF16 | USING_STRING;
|
||||
hp.offset = get_stack(6);
|
||||
hp.filter_fun = [](void *data, size_t *len, HookParam *hp)
|
||||
{
|
||||
if (all_ascii((wchar_t *)data, *len))
|
||||
return false;
|
||||
// 高架下に広がる[瀟洒]<しょうしゃ>な店内には、あたしたちのような学生の他に、
|
||||
auto str = std::wstring(reinterpret_cast<LPWSTR>(data), *len / 2);
|
||||
auto filterpath = {
|
||||
L".rpy", L".rpa", L".py", L".pyc", L".txt",
|
||||
L".png", L".jpg", L".bmp",
|
||||
L".mp3", L".ogg",
|
||||
L".webm", L".mp4",
|
||||
L".otf", L".ttf", L"Data/"};
|
||||
for (auto _ : filterpath)
|
||||
if (str.find(_) != str.npos)
|
||||
return false;
|
||||
str = std::regex_replace(str, std::wregex(L"\\[(.*?)\\]<(.*?)>"), L"$1");
|
||||
write_string_overwrite(data, len, str);
|
||||
return true;
|
||||
};
|
||||
suc|=NewHook(hp, "LightVN");
|
||||
return NewHook(hp, "LightVN2");
|
||||
}
|
||||
return suc;
|
||||
}
|
||||
bool _2(){
|
||||
//https://vndb.org/r86006
|
||||
//ファーストキス(体験版)
|
||||
//https://vndb.org/r85992
|
||||
//フサの大正女中ぐらし
|
||||
|
||||
BYTE sig[]={
|
||||
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,
|
||||
};
|
||||
auto addr=MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
|
||||
if(addr==0)return 0;
|
||||
addr=MemDbg::findEnclosingAlignedFunction(addr);
|
||||
if(addr==0)return 0;
|
||||
HookParam hp;
|
||||
hp.address = addr;
|
||||
hp.type = CODEC_UTF16|USING_STRING;
|
||||
hp.offset =get_stack(6);
|
||||
hp.filter_fun = [](void* data, size_t* len, HookParam* hp)
|
||||
{
|
||||
if(all_ascii((wchar_t*)data,*len))return false;
|
||||
//高架下に広がる[瀟洒]<しょうしゃ>な店内には、あたしたちのような学生の他に、
|
||||
auto str=std::wstring(reinterpret_cast<LPWSTR>(data),*len/2);
|
||||
auto filterpath={
|
||||
L".rpy",L".rpa",L".py",L".pyc",L".txt",
|
||||
L".png",L".jpg",L".bmp",
|
||||
L".mp3",L".ogg",
|
||||
L".webm",L".mp4",
|
||||
L".otf",L".ttf",L"Data/"
|
||||
};
|
||||
for(auto _ :filterpath)
|
||||
if(str.find(_)!=str.npos)
|
||||
return false;
|
||||
str = std::regex_replace(str, std::wregex(L"\\[(.*?)\\]<(.*?)>"), L"$1");
|
||||
write_string_overwrite(data,len,str);
|
||||
return true;
|
||||
};
|
||||
return NewHook(hp, "LightVN2");
|
||||
}
|
||||
}
|
||||
namespace{
|
||||
bool lightvnparsestring(){
|
||||
BYTE sig[]={
|
||||
0x4c,0x8b,0x47,0x10,
|
||||
0x48,0x83,0x7f,0x18,0x08,
|
||||
0x72,0x03,
|
||||
0x48,0x8b,0x3f,
|
||||
0x48,0x8b,0xd7,
|
||||
0x48,0x8b,0xcb,
|
||||
0xe8
|
||||
};
|
||||
auto addr=MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
|
||||
if(addr==0)return 0;
|
||||
addr=MemDbg::findEnclosingAlignedFunction_strict(addr);
|
||||
if(addr==0)return 0;
|
||||
namespace
|
||||
{
|
||||
bool lightvnparsestring()
|
||||
{
|
||||
BYTE sig[] = {
|
||||
0x4c, 0x8b, 0x47, 0x10,
|
||||
0x48, 0x83, 0x7f, 0x18, 0x08,
|
||||
0x72, 0x03,
|
||||
0x48, 0x8b, 0x3f,
|
||||
0x48, 0x8b, 0xd7,
|
||||
0x48, 0x8b, 0xcb,
|
||||
0xe8};
|
||||
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
|
||||
if (addr == 0)
|
||||
return 0;
|
||||
addr = MemDbg::findEnclosingAlignedFunction_strict(addr);
|
||||
if (addr == 0)
|
||||
return 0;
|
||||
HookParam hp;
|
||||
hp.address = addr;
|
||||
hp.type = CODEC_UTF16|USING_STRING|NO_CONTEXT;
|
||||
//包含太多短句,所以无法内嵌
|
||||
hp.text_fun=[](hook_stack* stack, HookParam*, uintptr_t* data, uintptr_t* split, size_t* len)
|
||||
hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT;
|
||||
// 包含太多短句,所以无法内嵌
|
||||
hp.text_fun = [](hook_stack *stack, HookParam *, uintptr_t *data, uintptr_t *split, size_t *len)
|
||||
{
|
||||
|
||||
*data = (uintptr_t)((TextUnionW *)stack->rdx)->getText();
|
||||
*len = ((TextUnionW *)stack->rdx)->size * 2;
|
||||
|
||||
*data=(uintptr_t)((TextUnionW*)stack->rdx)->getText();
|
||||
*len=((TextUnionW*)stack->rdx)->size*2;
|
||||
|
||||
std::wstring str=(wchar_t*)*data;
|
||||
if(startWith(str,L"\\n")&&endWith(str,L"\\n"))
|
||||
{
|
||||
*split=1;
|
||||
}
|
||||
|
||||
std::wstring str = (wchar_t *)*data;
|
||||
if (startWith(str, L"\\n") && endWith(str, L"\\n"))
|
||||
{
|
||||
*split = 1;
|
||||
}
|
||||
};
|
||||
hp.filter_fun=[](LPVOID data, size_t *size, HookParam *)
|
||||
hp.filter_fun = [](LPVOID data, size_t *size, HookParam *)
|
||||
{
|
||||
auto str=std::wstring((wchar_t*)data,*size/2);
|
||||
auto str = std::wstring((wchar_t *)data, *size / 2);
|
||||
std::wregex pattern(L"-{2,}");
|
||||
str = std::regex_replace(str, pattern, L"");
|
||||
return write_string_overwrite(data,size,str);
|
||||
return write_string_overwrite(data, size, str);
|
||||
};
|
||||
hp.newlineseperator=L"\\n";
|
||||
hp.newlineseperator = L"\\n";
|
||||
return NewHook(hp, "Light.VN.16");
|
||||
}
|
||||
}
|
||||
|
||||
bool xreflightvnparsestring(){
|
||||
//ver16 是上面的xref
|
||||
//ver12 找不到上面的函数
|
||||
auto checkstrings={
|
||||
L"backlog voice already exists at line: {}",
|
||||
L"attempting to log to backlog when backlog showing. likely you faded it out."
|
||||
};
|
||||
auto succ=false;
|
||||
for(auto str :checkstrings){
|
||||
auto straddr=MemDbg::findBytes(str,wcslen(str)*2,processStartAddress,processStopAddress);
|
||||
if(straddr==0)continue;
|
||||
bool xreflightvnparsestring()
|
||||
{
|
||||
// ver16 是上面的xref
|
||||
// ver12 找不到上面的函数
|
||||
auto checkstrings = {
|
||||
L"backlog voice already exists at line: {}",
|
||||
L"attempting to log to backlog when backlog showing. likely you faded it out."};
|
||||
auto succ = false;
|
||||
for (auto str : checkstrings)
|
||||
{
|
||||
auto straddr = MemDbg::findBytes(str, wcslen(str) * 2, processStartAddress, processStopAddress);
|
||||
if (straddr == 0)
|
||||
continue;
|
||||
// 140CADC30
|
||||
// 48 8D 0D C5 94 AB 00
|
||||
// 1401F4764
|
||||
BYTE lea[]={0x48,0x8d,XX};
|
||||
for(auto leaaddr:Util::SearchMemory(lea,sizeof(lea),PAGE_EXECUTE,processStartAddress,processStopAddress)){
|
||||
auto refaddr=(*(DWORD*)(leaaddr+3))+leaaddr+7;
|
||||
if(refaddr!=straddr)continue;
|
||||
auto funcaddr=MemDbg::findEnclosingAlignedFunction_strict(leaaddr,0x2000);
|
||||
if(funcaddr==0)continue;
|
||||
BYTE lea[] = {0x48, 0x8d, XX};
|
||||
for (auto leaaddr : Util::SearchMemory(lea, sizeof(lea), PAGE_EXECUTE, processStartAddress, processStopAddress))
|
||||
{
|
||||
auto refaddr = (*(DWORD *)(leaaddr + 3)) + leaaddr + 7;
|
||||
if (refaddr != straddr)
|
||||
continue;
|
||||
auto funcaddr = MemDbg::findEnclosingAlignedFunction_strict(leaaddr, 0x2000);
|
||||
if (funcaddr == 0)
|
||||
continue;
|
||||
HookParam hp;
|
||||
hp.address = funcaddr;
|
||||
hp.type = CODEC_UTF16|USING_STRING|NO_CONTEXT;
|
||||
hp.text_fun=[](hook_stack* stack, HookParam*, uintptr_t* data, uintptr_t* split, size_t* len)
|
||||
hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT;
|
||||
hp.text_fun = [](hook_stack *stack, HookParam *, uintptr_t *data, uintptr_t *split, size_t *len)
|
||||
{
|
||||
//wstring=TextUnionW for msvc c++17
|
||||
*data=(uintptr_t)((TextUnionW*)stack->rdx)->getText();
|
||||
*len=((TextUnionW*)stack->rdx)->size*2;
|
||||
// wstring=TextUnionW for msvc c++17
|
||||
*data = (uintptr_t)((TextUnionW *)stack->rdx)->getText();
|
||||
*len = ((TextUnionW *)stack->rdx)->size * 2;
|
||||
};
|
||||
succ|= NewHook(hp, "Light.VN.12");
|
||||
succ |= NewHook(hp, "Light.VN.12");
|
||||
}
|
||||
}
|
||||
return succ;
|
||||
|
||||
}
|
||||
}
|
||||
bool LightVN::attach_function() {
|
||||
bool ok=_1();
|
||||
ok=_2()||ok;
|
||||
ok|=lightvnparsestring();
|
||||
ok|=xreflightvnparsestring();
|
||||
bool LightVN::attach_function()
|
||||
{
|
||||
bool ok = _1();
|
||||
ok = _2() || ok;
|
||||
ok |= lightvnparsestring();
|
||||
ok |= xreflightvnparsestring();
|
||||
return ok;
|
||||
}
|
@ -1,19 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
inline size_t str_len(const char *s){return strlen(s);}
|
||||
inline size_t str_len(const wchar_t *s){return wcslen(s);}
|
||||
inline size_t str_len(const char *s) { return strlen(s); }
|
||||
inline size_t str_len(const wchar_t *s) { return wcslen(s); }
|
||||
|
||||
template<class CharT>
|
||||
template <class CharT>
|
||||
struct TextUnion
|
||||
{
|
||||
enum { ShortTextCapacity = 0x10/sizeof(CharT) };
|
||||
enum
|
||||
{
|
||||
ShortTextCapacity = 0x10 / sizeof(CharT)
|
||||
};
|
||||
|
||||
union {
|
||||
union
|
||||
{
|
||||
const CharT *text; // 0x0
|
||||
CharT chars[ShortTextCapacity];
|
||||
};
|
||||
int size, // 0x10
|
||||
size_t size, // 0x10
|
||||
capacity;
|
||||
|
||||
bool isValid() const
|
||||
@ -25,9 +28,11 @@ struct TextUnion
|
||||
}
|
||||
|
||||
const CharT *getText() const
|
||||
{ return capacity < ShortTextCapacity ? chars : text; }
|
||||
{
|
||||
return capacity < ShortTextCapacity ? chars : text;
|
||||
}
|
||||
|
||||
void setText(const CharT *_text, int _size)
|
||||
void setText(const CharT *_text, size_t _size)
|
||||
{
|
||||
if (_size < ShortTextCapacity)
|
||||
::memcpy(chars, _text, (_size + 1) * sizeof(CharT));
|
||||
@ -36,7 +41,7 @@ struct TextUnion
|
||||
capacity = size = _size;
|
||||
}
|
||||
|
||||
void setLongText(const CharT *_text, int _size)
|
||||
void setLongText(const CharT *_text, size_t _size)
|
||||
{
|
||||
text = _text;
|
||||
size = _size;
|
||||
@ -44,11 +49,15 @@ struct TextUnion
|
||||
}
|
||||
|
||||
void setText(const std::basic_string<CharT> &text)
|
||||
{ setText((const CharT *)text.c_str(), text.size()); }
|
||||
{
|
||||
setText((const CharT *)text.c_str(), text.size());
|
||||
}
|
||||
void setLongText(const std::basic_string<CharT> &text)
|
||||
{ setLongText((const CharT *)text.c_str(), text.size()); }
|
||||
{
|
||||
setLongText((const CharT *)text.c_str(), text.size());
|
||||
}
|
||||
};
|
||||
|
||||
using TextUnionA=TextUnion<char>;
|
||||
using TextUnionW=TextUnion<wchar_t>;
|
||||
using TextUnionA = TextUnion<char>;
|
||||
using TextUnionW = TextUnion<wchar_t>;
|
||||
// EOF
|
||||
|
Loading…
x
Reference in New Issue
Block a user