This commit is contained in:
恍兮惚兮 2024-08-21 20:25:56 +08:00
parent 48f521b909
commit e518d6431f
2 changed files with 187 additions and 164 deletions

View File

@ -1,6 +1,8 @@
#include "LightVN.h"
namespace{
bool _1() {
namespace
{
bool _1()
{
// void __fastcall sub_1404B7960(void **Src)
// HQ-1C*0@4B7960:LightApp.exe
const BYTE BYTES[] = {
@ -26,15 +28,16 @@ bool _1() {
0x0f, 0x87, XX4,
0xe8, XX4
};
auto suc = false;
auto addrs = Util::SearchMemory(BYTES, sizeof(BYTES), PAGE_EXECUTE, processStartAddress, processStopAddress);
for (auto addr : addrs) {
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;
if (addr == 0)
continue;
addr += 4;
ConsoleOutput("LightVN %p", addr);
HookParam hp;
@ -42,7 +45,8 @@ bool _1() {
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) {
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;
@ -52,29 +56,35 @@ bool _1() {
}
return suc;
}
bool _2(){
bool _2()
{
// https://vndb.org/r86006
// ファーストキス(体験版)
// https://vndb.org/r85992
// フサの大正女中ぐらし
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;
if (addr == 0)
return 0;
addr = MemDbg::findEnclosingAlignedFunction(addr);
if(addr==0)return 0;
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;
if (all_ascii((wchar_t *)data, *len))
return false;
// 高架下に広がる[瀟洒]<しょうしゃ>な店内には、あたしたちのような学生の他に、
auto str = std::wstring(reinterpret_cast<LPWSTR>(data), *len / 2);
auto filterpath = {
@ -82,8 +92,7 @@ bool _2(){
L".png", L".jpg", L".bmp",
L".mp3", L".ogg",
L".webm", L".mp4",
L".otf",L".ttf",L"Data/"
};
L".otf", L".ttf", L"Data/"};
for (auto _ : filterpath)
if (str.find(_) != str.npos)
return false;
@ -94,8 +103,10 @@ bool _2(){
return NewHook(hp, "LightVN2");
}
}
namespace{
bool lightvnparsestring(){
namespace
{
bool lightvnparsestring()
{
BYTE sig[] = {
0x4c, 0x8b, 0x47, 0x10,
0x48, 0x83, 0x7f, 0x18, 0x08,
@ -103,20 +114,19 @@ namespace{
0x48, 0x8b, 0x3f,
0x48, 0x8b, 0xd7,
0x48, 0x8b, 0xcb,
0xe8
};
0xe8};
auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress);
if(addr==0)return 0;
if (addr == 0)
return 0;
addr = MemDbg::findEnclosingAlignedFunction_strict(addr);
if(addr==0)return 0;
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)
{
*data = (uintptr_t)((TextUnionW *)stack->rdx)->getText();
*len = ((TextUnionW *)stack->rdx)->size * 2;
@ -125,7 +135,6 @@ namespace{
{
*split = 1;
}
};
hp.filter_fun = [](LPVOID data, size_t *size, HookParam *)
{
@ -138,26 +147,31 @@ namespace{
return NewHook(hp, "Light.VN.16");
}
bool xreflightvnparsestring(){
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."
};
L"attempting to log to backlog when backlog showing. likely you faded it out."};
auto succ = false;
for(auto str :checkstrings){
for (auto str : checkstrings)
{
auto straddr = MemDbg::findBytes(str, wcslen(str) * 2, processStartAddress, processStopAddress);
if(straddr==0)continue;
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)){
for (auto leaaddr : Util::SearchMemory(lea, sizeof(lea), PAGE_EXECUTE, processStartAddress, processStopAddress))
{
auto refaddr = (*(DWORD *)(leaaddr + 3)) + leaaddr + 7;
if(refaddr!=straddr)continue;
if (refaddr != straddr)
continue;
auto funcaddr = MemDbg::findEnclosingAlignedFunction_strict(leaaddr, 0x2000);
if(funcaddr==0)continue;
if (funcaddr == 0)
continue;
HookParam hp;
hp.address = funcaddr;
hp.type = CODEC_UTF16 | USING_STRING | NO_CONTEXT;
@ -171,10 +185,10 @@ namespace{
}
}
return succ;
}
}
bool LightVN::attach_function() {
bool LightVN::attach_function()
{
bool ok = _1();
ok = _2() || ok;
ok |= lightvnparsestring();

View File

@ -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); }
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,9 +49,13 @@ 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>;