This commit is contained in:
2025-04-28 23:02:20 +08:00
parent bfb9be65b5
commit 1fddc97e20
12 changed files with 756 additions and 81 deletions

View File

@@ -3,9 +3,12 @@
#include "MinHook.h"
#include "inlinehook.h"
#include "RegisterSquirrel.hpp"
#include "IO_Ex.hpp"
//游戏初始化完毕Flag
static bool InitGameFlag = false;
//宽屏百级UI
static bool Yosin百级UIFlag = false;
@@ -30,7 +33,11 @@ int Sq_mycompilebuffer(HSQUIRRELVM v, const wchar_t* s, int size, const wchar_t*
buf.ptr = 0;
return SQ_Compile(v, (LSQLEXREADFUNC)0x1359AD0, &buf, filename, printerror);
}
void Suxn() {
size_t Ds = BaseData.size();
for (size_t i = 0; i < Ds; i++)
@@ -304,7 +311,7 @@ void __declspec(naked)Damage_Hook() {
if (InitGameFlag)
{
int Address = Damage_HookAsm.EBX;//只要等于 red 或者 等于0 就说明是我自己的伤害
int Address = Damage_HookAsm.EBX;//只要等于 read 或者 等于0 就说明是我自己的伤害
int Damage = *(DWORD*)(Damage_HookAsm.EBP - 0x17c);
Damage_HookAsm.VmAddress = Sq_gettop(*(HSQUIRRELVM*)0x1AF3544);
@@ -333,6 +340,127 @@ void __declspec(naked)Damage_Hook() {
}
typedef struct REG1
{
DWORD EAX;
DWORD EBX;
DWORD ECX;
DWORD EDX;
DWORD ESI;
DWORD EDI;
DWORD ESP;
DWORD EBP;
DWORD VmAddress;
BYTE Cl;
SQBool flag;
int vm_data1;
} REG1;
REG1 DiscardItem_HookAsm = { 0 };
void __declspec(naked)DiscardItem_Hook() {
static int address = 0xE71EAB;
static int func = 0xE6E070;
_asm
{
pushad
pushfd
mov DiscardItem_HookAsm.ESI, esi
mov DiscardItem_HookAsm.EBX, ebx
}
if (InitGameFlag)
{
DiscardItem_HookAsm.VmAddress = Sq_gettop(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushstring(*(HSQUIRRELVM*)0x1AF3544, L"Sq_DiscardItem", -1);
if (SQ_SUCCEEDED(Sq_get(*(HSQUIRRELVM*)0x1AF3544, -2)))
{
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, DiscardItem_HookAsm.ESI);
Sq_call(*(HSQUIRRELVM*)0x1AF3544, 2, 1, 1);
Sq_getbool(*(HSQUIRRELVM*)0x1AF3544, -1, &DiscardItem_HookAsm.flag);
}
Sq_settop(*(HSQUIRRELVM*)0x1AF3544, DiscardItem_HookAsm.VmAddress);
if (!DiscardItem_HookAsm.flag) {
_asm {
popfd
popad
mov eax,0
jmp address
}
}
}
_asm {
popfd
popad
push 1
push DiscardItem_HookAsm.ESI
push 0xFB
mov ecx, DiscardItem_HookAsm.EBX
call func
jmp address
}
}
REG1 DiscardItem_HookBAsm = { 0 };
void __declspec(naked)DiscardItemB_Hook() {
static int address = 0xE71E95;
static int func = 0x10086C0;
_asm
{
pushad
pushfd
mov DiscardItem_HookBAsm.EAX, eax
mov DiscardItem_HookBAsm.ESI, esi
mov DiscardItem_HookBAsm.ECX, ecx
}
if (InitGameFlag)
{
DiscardItem_HookBAsm.VmAddress = Sq_gettop(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushstring(*(HSQUIRRELVM*)0x1AF3544, L"Sq_DiscardItem", -1);
if (SQ_SUCCEEDED(Sq_get(*(HSQUIRRELVM*)0x1AF3544, -2)))
{
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, DiscardItem_HookBAsm.ESI);
Sq_call(*(HSQUIRRELVM*)0x1AF3544, 2, 1, 1);
Sq_getbool(*(HSQUIRRELVM*)0x1AF3544, -1, &DiscardItem_HookBAsm.flag);
}
Sq_settop(*(HSQUIRRELVM*)0x1AF3544, DiscardItem_HookBAsm.VmAddress);
if (!DiscardItem_HookBAsm.flag) {
_asm {
popfd
popad
mov eax, 0
jmp address
}
}
}
_asm {
popfd
popad
push 0
push 0
push 0
push 0x1C
push DiscardItem_HookBAsm.EAX
push 0
push 0
call func
jmp address
}
}
void __declspec(naked)SelectCharacter_Hook() {
static int address = 0x10F79D1;
_asm
@@ -504,6 +632,56 @@ void __declspec(naked)ReadStringBin_HookB() {
}
}
REG1 MonsetrRace_HookAsm = { 0 };
void __declspec(naked)MonsetrRace_Hook() {
static int address = 0x43A8BA;
static int address1 = 0x43A86A;
_asm
{
mov MonsetrRace_HookAsm.EBX, ebx
mov MonsetrRace_HookAsm.EDX, edx
xor ebx, ebx
push edi
mov edi, [ebp + 0x8]
test eax, eax
pushad
pushfd
mov MonsetrRace_HookAsm.ESI, esi
mov MonsetrRace_HookAsm.vm_data1, 34
}
MonsetrRace_HookAsm.VmAddress = Sq_gettop(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushstring(*(HSQUIRRELVM*)0x1AF3544, L"L_Rindro_MonsterEXControl_Race", -1);
if (SQ_SUCCEEDED(Sq_get(*(HSQUIRRELVM*)0x1AF3544, -2)))
{
Sq_pushroottable(*(HSQUIRRELVM*)0x1AF3544);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.ESI);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.EBX);
Sq_pushinteger(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.EDX);
Sq_call(*(HSQUIRRELVM*)0x1AF3544, 4, 1, 1);
Sq_getinteger(*(HSQUIRRELVM*)0x1AF3544, -1, &MonsetrRace_HookAsm.vm_data1);
}
else {
Sq_settop(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.VmAddress);
_asm {
popfd
popad
jmp address1
}
}
Sq_settop(*(HSQUIRRELVM*)0x1AF3544, MonsetrRace_HookAsm.VmAddress);
_asm {
popfd
popad
mov edi, MonsetrRace_HookAsm.vm_data1
jmp address
}
}
@@ -618,21 +796,24 @@ void __declspec(naked)ReadStringBin_HookB() {
//窗口打开事件Hook
typedef void(__fastcall _OpenWindow)(DWORD thisc, DWORD Seat, DWORD a1, char* a2, DWORD a3);
typedef void(__fastcall _OpenWindow)(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2, DWORD a3);
static _OpenWindow* OldOpenWindow;
void __fastcall NewOpenWindow(DWORD thisc, DWORD Seat, DWORD a1, char* a2, DWORD a3) {
if (*(DWORD*)0x1A5FB20 == thisc) {
HSQUIRRELVM v = *(HSQUIRRELVM*)0x1AF3544;
SQInteger Top = Sq_gettop(v);
Sq_pushroottable(v);
Sq_pushstring(v, L"L_OpenOldWindowCallBack", -1);
if (SQ_SUCCEEDED(Sq_get(v, -2))) {
void __fastcall NewOpenWindow(DWORD thisc, DWORD Seat, DWORD a1, DWORD a2, DWORD a3) {
if (InitGameFlag) {
if (*(DWORD*)0x1A5FB20 == thisc) {
HSQUIRRELVM v = *(HSQUIRRELVM*)0x1AF3544;
SQInteger Top = Sq_gettop(v);
Sq_pushroottable(v);
Sq_pushinteger(v, a1);
Sq_call(v, 2, SQFalse, SQTrue);
Sq_pushstring(v, L"L_OpenOldWindowCallBack", -1);
if (SQ_SUCCEEDED(Sq_get(v, -2))) {
Sq_pushroottable(v);
Sq_pushinteger(v, a1);
Sq_call(v, 2, SQFalse, SQTrue);
}
Sq_settop(v, Top);
}
Sq_settop(v, Top);
}
OldOpenWindow(thisc, 0, a1, a2, a3);
}
@@ -775,7 +956,7 @@ void Pack_Control(int idx, int code, void* p3, void* p4)
HSQUIRRELVM v = *(HSQUIRRELVM*)0x1AF3544;
SQInteger Top = Sq_gettop(v);
Sq_pushroottable(v);
#ifdef SELL
#if defined(SELL) || defined(EXPRESS)
Sq_pushstring(v, L"Sq_Pack_Control", -1);
#else
Sq_pushstring(v, L"Sq_Pack_ControlLocal", -1);
@@ -849,19 +1030,75 @@ DWORD _fastcall New4C61F0(DWORD thisc, DWORD Seat)
}
static void InitBin() {
void* buf = malloc(81443744);
int readsize;
typedef bool(_59E3D0)(wchar_t* path, void* buffer, int a3, int* a4);
_59E3D0* SUB_59E3D0 = (_59E3D0*)0x59E3D0;
bool a = SUB_59E3D0(L"stringtable.bin", buf, 81443744, &readsize);
if (a) {
IO_Ex pvf((char*)buf, readsize);
int Count = pvf.GetInt();
int CurrentIndex = 0;
for (int i = 0; i < Count; i++) {
pvf.seek(CurrentIndex * 4 + 4);
int StartPos = pvf.GetInt();
int EndPos = pvf.GetInt();
int Len = EndPos - StartPos;
pvf.seek(StartPos + 4);
std::string Str = pvf.GetString(Len);
StringBin.push_back(Str);
CurrentIndex++;
}
}
free(buf);
}
void PFunc(HSQUIRRELVM v, const SQChar* s, ...) {
va_list vl;
va_start(vl, s);
// 使用_vsnwprintf正确计算格式化后的宽字符字符串长度
int len = _vsnwprintf(nullptr, 0, s, vl);
va_end(vl);
va_start(vl, s);
// 动态分配足够的内存空间注意长度计算需要考虑宽字符的字节数通常一个宽字符占2字节或更多取决于平台和编码
wchar_t* buffer = new wchar_t[len + 1];
// 将格式化后的宽字符字符串拼接到动态分配的内存中
_vsnwprintf(buffer, len + 1, s, vl);
va_end(vl);
std::wofstream outFile("test.txt", std::ios::out | std::ios::app | std::ios::binary); // 以二进制模式打开文件用于追加写入
if (outFile) {
outFile << buffer << std::endl; // 将宽字符字符串写入文件,并添加换行符
outFile.close(); // 关闭文件流
std::wcout << L"宽字符字符串已成功追加写入文件。" << std::endl;
}
else {
std::wcerr << L"无法打开文件进行追加写入。" << std::endl;
}
std::wcout << buffer << std::endl; // 使用std::wcout输出宽字符字符串
delete[] buffer;
}
//HookNut函数注册
typedef void(__cdecl _Register_Nut)();
static _Register_Nut* Register_Nut_Old;
void __cdecl H_Register_Nut()
{
InitBin();
Register_Nut_Old();
static bool Init = false;
if (!Init) {
Init = true;
//sq_setprintfunc(*(HSQUIRRELVM*)0x1AF3544, PFunc);
R_Register_Nut();
std::string BaseFile = "YosinBaseC";
std::string Base = R"(
FFI_FIRST_ABI <- 0;
@@ -927,7 +1164,9 @@ getroottable().LenheartBaseFuncTab <- {};
getroottable().LenheartFuncTab <- {};
getroottable().Rindro_Scr_Width <- L_sq_RA(0x4D848E);
getroottable().Rindro_Scr_High <- L_sq_RA(0x4D8495);
)";
//是否为本地
FILE* file = fopen("sqr/DofileList.nut", "rb");
if (file)
@@ -952,8 +1191,9 @@ getroottable().Rindro_Scr_High <- L_sq_RA(0x4D8495);
delete[]filename;
delete[]str;
#ifndef SELL//本地模式要加在整体脚本
#ifndef EXPRESS//本地模式要加在整体脚本
Sq_pushroottable(v);
Sq_pushstring(v, L"dofile", -1);
if (SQ_SUCCEEDED(Sq_get(v, -2))) {
@@ -963,6 +1203,8 @@ getroottable().Rindro_Scr_High <- L_sq_RA(0x4D8495);
}
Sq_pop(v, 2);
#endif // !SELL
#endif // !SELL
}
}
@@ -987,7 +1229,7 @@ void _fastcall H_Register_DrawCode(DWORD thisc, int Seat, int a3, int a4, int a5
delete[]clone;
if (GameStr.find("商城") != std::string::npos) {
if (GameStr.find("将帐号金库中的物品存入金库中") != std::string::npos) {
std::cout << GameStr << std::endl;
}
@@ -1662,8 +1904,49 @@ int _fastcall New4017F0(int thisc, void* a2, char* str, int a3) {
return Old4017F0(thisc, a2, str,a3);
}
//怪物头像绘制HOOK
typedef int(__fastcall _43A1B0)(DWORD thisc, DWORD Seat, int Xpos , int Ypos);
static _43A1B0* Old43A1B0;
int __fastcall New43A1B0(DWORD thisc, DWORD Seat, int Xpos, int Ypos) {
SQBool Flag = true;
HSQUIRRELVM v = *(HSQUIRRELVM*)0x1AF3544;
SQInteger Top = Sq_gettop(v);
Sq_pushroottable(v);
Sq_pushstring(v, L"L_Rindro_MonsterEXControl_Face", -1);
if (SQ_SUCCEEDED(Sq_get(v, -2))) {
Sq_pushroottable(v);
Sq_pushinteger(v, *(DWORD*)(thisc + 8));
Sq_pushinteger(v, Xpos);
Sq_pushinteger(v, Ypos);
Sq_call(v, 4, SQTrue, SQTrue);
Sq_getbool(v, -1, &Flag);
}
Sq_settop(v, Top);
if(Flag)return Old43A1B0(thisc, Seat, Xpos, Ypos);
return 0;
}
void RegisterHook() {
#ifdef EXPRESS
InitGameFlag = true;
MH_Initialize();
//Hook收包
MH_CreateHook((void*)0x721EA0, &H_Register_Pack, reinterpret_cast<void**>(&Lpfn_Init));
MH_EnableHook((void*)0x721EA0);
//HookNut函数注册
MH_CreateHook((void*)0x67B910, &H_Register_Nut, reinterpret_cast<void**>(&Register_Nut_Old));
MH_EnableHook((void*)0x67B910);
return;
#endif // EXPRESS
//InlineHook///
//玩家菜单选项HOOK 有回调
@@ -1678,12 +1961,20 @@ void RegisterHook() {
//伤害HOOK
inlinehook DamageHook(0xE5A2DE, (int)&Damage_Hook);
DamageHook.Motify_address();
//丢弃道具的HOOK
inlinehook DiscardItemHook(0xE71E9C, (int)&DiscardItem_Hook);
DiscardItemHook.Motify_address();
inlinehook DiscardItemHookB(0xE71E83, (int)&DiscardItemB_Hook);
DiscardItemHookB.Motify_address();
//怪物种族绘制HOOK
inlinehook MonsetrRaceHook(0x43A862, (int)&MonsetrRace_Hook);
MonsetrRaceHook.Motify_address();
//读取StringBin文件
inlinehook ReadStringBinHookA(0x119F2F8, (int)&ReadStringBin_HookA);
ReadStringBinHookA.Motify_address();
inlinehook ReadStringBinHookB(0x119F2C0, (int)&ReadStringBin_HookB);
ReadStringBinHookB.Motify_address();
////读取StringBin文件
//inlinehook ReadStringBinHookA(0x119F2F8, (int)&ReadStringBin_HookA);
//ReadStringBinHookA.Motify_address();
//inlinehook ReadStringBinHookB(0x119F2C0, (int)&ReadStringBin_HookB);
//ReadStringBinHookB.Motify_address();
@@ -1761,8 +2052,8 @@ void RegisterHook() {
//Hook发包相关
//HOOK发包类型
//MH_CreateHook((void*)0x1127D60, &NewSendPacksType, reinterpret_cast<void**>(&_OldSendPackType));
//MH_EnableHook((void*)0x1127D60);
MH_CreateHook((void*)0x1127D60, &NewSendPacksType, reinterpret_cast<void**>(&_OldSendPackType));
MH_EnableHook((void*)0x1127D60);
//MH_CreateHook((void*)0x1128550, &NewSendPacksByte, reinterpret_cast<void**>(&_OldSendPackByte));
//MH_EnableHook((void*)0x1128550);
//MH_CreateHook((void*)0x1128580, &NewSendPacksWord, reinterpret_cast<void**>(&_OldSendPackWord));
@@ -1789,6 +2080,7 @@ void RegisterHook() {
//如果加载了百级UI
FILE* file = fopen("ImagePacks2/!HUD_Yosin百级UI.NPK", "rb");
if (file) {
Yosin百级UIFlag = true;
//BUFF图标 显示
inlinehook BuffIconHook(0x04C8C14, (int)&BuffIcon_Hook);
BuffIconHook.Motify_address();
@@ -1857,6 +2149,9 @@ void RegisterHook() {
//MH_CreateHook((void*)0x11D43A0, &New11D43A0, reinterpret_cast<void**>(&Old11D43A0));
//MH_EnableHook((void*)0x11D43A0);
//怪物头像绘制 Hook
MH_CreateHook((void*)0x43A1B0, &New43A1B0, reinterpret_cast<void**>(&Old43A1B0));
MH_EnableHook((void*)0x43A1B0);
//他人信息Hook 数值
MH_CreateHook((void*)0xFA42D0, &NewFA42D0, reinterpret_cast<void**>(&OldFA42D0));