Привет! Я пытаюсь перехватывать события, провёл исследование, но по какой-то причине в моём коде возникает критическая ошибка:
Моё исследование заключалось в следующем: я искал onEvent в моей библиотеке nWindow:
"?eventOnEvent@UUIScript@@QAEXHABVFString@@@Z"
void __thiscall UUIScript::eventOnEvent(UUIScript *this,int param_1,FString *param_2)
Итак, я нашёл функцию eventOnEvent с этой сигнатурой и затем перешёл к своей DLL:
Я не знаю, в чём может быть ошибка: параметры я копирую правильно, соглашение вызова тоже соблюдаю, но подозреваю, что проблема может быть в моём “splice”. У кого-нибудь есть идеи, почему это происходит?
Ах да, я внедрил эту DLL в fire.dll
Моё исследование заключалось в следующем: я искал onEvent в моей библиотеке nWindow:
"?eventOnEvent@UUIScript@@QAEXHABVFString@@@Z"
void __thiscall UUIScript::eventOnEvent(UUIScript *this,int param_1,FString *param_2)
Итак, я нашёл функцию eventOnEvent с этой сигнатурой и затем перешёл к своей DLL:
C++:
#include "pch.h"
#include <windows.h>
#include <string>
#include <iostream>
#include <locale>
#include <codecvt>
void createConsole() {
AllocConsole(); // Cria a janela do console
FILE* fp;
// Redireciona stdout (std::cout)
freopen_s(&fp, "CONOUT$", "w", stdout);
// Redireciona stderr (std::cerr)
freopen_s(&fp, "CONOUT$", "w", stderr);
// Redireciona stdin (opcional, para entradas de teclado no console)
freopen_s(&fp, "CONIN$", "r", stdin);
// Mensagem inicial no console
std::cout << "[INFO] console on!" << std::endl;
}
void logMessage(const char* format, ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
std::cout << std::endl;
}
void* splice(unsigned char* originalFunction, void* hookFunction) {
DWORD oldProtect;
VirtualProtect(originalFunction, 5, PAGE_EXECUTE_READWRITE, &oldProtect);
BYTE originalBytes[5];
memcpy(originalBytes, originalFunction, 5);
BYTE jmpInstruction[5] = { 0xE9, 0x00, 0x00, 0x00, 0x00 };
DWORD relativeAddress = (DWORD)hookFunction - (DWORD)originalFunction - 5;
memcpy(&jmpInstruction[1], &relativeAddress, 4);
memcpy(originalFunction, jmpInstruction, 5);
VirtualProtect(originalFunction, 5, oldProtect, &oldProtect);
return originalFunction + 5;
}
template<class T>
struct TArray
{
friend struct FString;
public:
inline TArray()
{
Data = nullptr;
Count = Max = 0;
};
inline size_t Num() const
{
return Count;
};
inline T& operator[](size_t i)
{
return Data[i];
};
inline const T& operator[](size_t i) const
{
return Data[i];
};
inline bool IsValidIndex(size_t i) const
{
return i < Num();
}
inline T& GetByIndex(size_t i)
{
return Data[i];
}
inline const T& GetByIndex(size_t i) const
{
return Data[i];
}
private:
T* Data;
int32_t Count;
int32_t Max;
};
struct FString : private TArray<wchar_t>
{
inline FString() {}
FString(const wchar_t* other)
{
Max = Count = *other ? std::wcslen(other) + 1 : 0;
if (Count)
{
Data = const_cast<wchar_t*>(other);
}
};
inline bool IsValid() const
{
return Data != nullptr;
}
inline const wchar_t* c_str() const
{
return Data;
}
std::string ToString() const
{
auto length = std::wcslen(Data);
std::string str(length, '\0');
std::use_facet<std::ctype<wchar_t>>(std::locale()).narrow(Data, Data + length, '?', &str[0]);
return str;
}
};
typedef void(__fastcall* _OnEvent)(unsigned int uuiscript, int eventID, FString* param);
_OnEvent true_OnEvent;
void new_OnEvent(unsigned int uuiscript, int eventID, FString* param) {
std::string paramStr = (param && param->IsValid()) ? param->ToString() : "Invalid";
if (eventID == 99977) {
MessageBoxA(NULL, "Found.", "Error", MB_OK);
}
logMessage("[INFO] Event_ID: %d | Param: %s", eventID, paramStr.c_str());
true_OnEvent(uuiscript, eventID, param);
}
void hookCore() {
HMODULE nWindow = GetModuleHandleW(L"nwindow.dll");
if (!nWindow) {
return;
}
void* addr = GetProcAddress(nWindow, "?eventOnEvent@UUIScript@@QAEXHABVFString@@@Z");
if (addr == nullptr) {
MessageBoxA(NULL, "Failed to find target function.", "Error", MB_OK);
return;
}
true_OnEvent = (_OnEvent)splice((unsigned char*)addr, new_OnEvent);
}
extern "C" __declspec(dllexport)
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
if (fdwReason == DLL_PROCESS_ATTACH) {
createConsole();
DisableThreadLibraryCalls(hinstDLL);
CreateThread(0, 0, LPTHREAD_START_ROUTINE(hookCore), 0, 0, 0);
}
return TRUE;
}
Я не знаю, в чём может быть ошибка: параметры я копирую правильно, соглашение вызова тоже соблюдаю, но подозреваю, что проблема может быть в моём “splice”. У кого-нибудь есть идеи, почему это происходит?
Ах да, я внедрил эту DLL в fire.dll