1
0
mirror of https://github.com/0O0o0oOoO00/Alas.git synced 2026-05-15 14:29:25 +08:00
Files
Alas/blcrack/cracker/ui/hook.cpp
2025-09-05 17:58:49 +08:00

164 lines
5.5 KiB
C++

#include <spdlog/spdlog.h>
#include <android/input.h>
#include <dlfcn.h>
#include <EGL/egl.h>
#include "sol/sol.hpp"
#include "hook.hpp"
#include "dobby.h"
#include "ui.hpp"
#include "imgui/imgui.h"
#include "imgui/imgui_impl_android.h"
#include "imgui/imgui_impl_opengl3.h"
using eglSwapBuffers_fnT = EGLBoolean(EGLDisplay dpy, EGLSurface surface);
eglSwapBuffers_fnT* old_eglSwapBuffers = nullptr;
EGLBoolean my_eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) {
ui_eglSwapBuffers(dpy, surface);
return old_eglSwapBuffers(dpy, surface);
}
#ifdef USE_32
using Input_fnT = int32_t(void* thiz, void* ex_ab, void* ex_ac);
#endif
#ifdef USE_64
using Input_fnT = int64_t(void* thiz, void* ex_ab, void* ex_ac);
#endif
Input_fnT* old_Input = nullptr;
#ifdef USE_32
int32_t my_Input(void* thiz, void* ex_ab, void* ex_ac)
#endif
#ifdef USE_64
int64_t my_Input(void* thiz, void* ex_ab, void* ex_ac)
#endif
{
auto ret = old_Input(thiz, ex_ab, ex_ac);
ImGui_ImplAndroid_HandleInputEvent((AInputEvent *) thiz);
return ret;
}
#ifdef USE_32
using Consume_fnT = int32_t(void* thiz, void* arg1, bool arg2, long arg3, uint32_t* arg4, AInputEvent** input_event);
#endif
#ifdef USE_64
using Consume_fnT = int64_t(void* thiz, int64_t arg1, char arg2, int64_t arg3, uint32_t* arg4, AInputEvent** input_event);
#endif
Consume_fnT* old_Consume = nullptr;
#ifdef USE_32
int32_t my_Consume(void* thiz, void* arg1, bool arg2, long arg3, uint32_t* arg4, AInputEvent** input_event)
#endif
#ifdef USE_64
int64_t my_Consume(void* thiz, int64_t arg1, char arg2, int64_t arg3, uint32_t* arg4, AInputEvent** input_event)
#endif
{
SPDLOG_INFO("my_Consume Called");
auto result = old_Consume(thiz, arg1, arg2, arg3, arg4, input_event);
if(result != 0 || *input_event == nullptr)
return result;
ImGui_ImplAndroid_HandleInputEvent(*input_event);
return result;
}
bool has_hooked = false;
#ifdef USE_32
#define INPUT_SO "/system/lib/libinput.so"
#endif
#ifdef USE_64
#define INPUT_SO "/system/lib64/libinput.so"
#endif
#ifdef USE_32
#define EGL_SO "/system/lib/libEGL.so"
#endif
#ifdef USE_64
#define EGL_SO "/system/lib64/libEGL.so"
#endif
#define android_InputConsumer_initializeMotionEvent "_ZN7android13InputConsumer21initializeMotionEventEPNS_11MotionEventEPKNS_12InputMessageE"
#define android_InputConsumer_consume "_ZN7android13InputConsumer7consumeEPNS_26InputEventFactoryInterfaceEblPjPPNS_10InputEventE"
void do_ui_hook() {
if (has_hooked) {
return;
}
auto eglhandle = dlopen(EGL_SO, RTLD_LAZY);
auto sym_eglSwapBuffers = dlsym(eglhandle, "eglSwapBuffers");
DobbyHook(reinterpret_cast<void*>(sym_eglSwapBuffers), reinterpret_cast<void*>(my_eglSwapBuffers), reinterpret_cast<void **>(&old_eglSwapBuffers));
void* sym_input = DobbySymbolResolver(INPUT_SO, android_InputConsumer_initializeMotionEvent);
if(sym_input != nullptr) {
DobbyHook(sym_input, reinterpret_cast<void*>(my_Input), reinterpret_cast<void **>(&old_Input));
} else {
sym_input = DobbySymbolResolver(INPUT_SO, android_InputConsumer_consume);
if(sym_input != nullptr) {
DobbyHook(sym_input, reinterpret_cast<void*>(my_Consume), reinterpret_cast<void **>(&old_Consume));
}
}
has_hooked = true;
SPDLOG_INFO("Hook done!");
}
void hook_game_setting_panel(lua_State* l) {
sleep(10);
sol::state_view lua(lua_newthread(l));
SPDLOG_INFO("Get SettingsNotificationPanel.OnItemSwitch");
Lua::Function old = lua["SettingsNotificationPanel"]["OnItemSwitch"];
SPDLOG_INFO("Replace SettingsNotificationPanel.OnItemSwitch");
lua["SettingsNotificationPanel"]["OnItemSwitch"] = [old](sol::this_state L, Lua::VariadicArgs args) {
Lua::Table config_into = args[1];
int config_id = config_into["id"];
if (config_id == 4) {
bool is_enable_ui = args[2];
is_enable_ui = !is_enable_ui;
if (is_enable_ui) {
do_ui_hook();
CrackerUI::get_instance().show_ui();
} else {
CrackerUI::get_instance().close_ui();
}
}
old(L, args);
};
}
bool g_is_game_loaded = false;
bool g_is_panel_loaded = false;
lua_State* g_target_L = nullptr;
int (*old_luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz, const char *name);
int my_luaL_loadbuffer(lua_State *L, const char *buff, size_t sz,const char *name) {
auto ret = old_luaL_loadbuffer(L, buff, sz, name);
if (!g_is_panel_loaded) {
if (strstr(name, "SettingsNotificationPanel") != nullptr) {
g_target_L = L;
g_is_panel_loaded = true;
}
}
return ret;
}
int (*old_lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
int my_lua_pcall (lua_State *L, int nargs, int nresults, int errfunc) {
auto ret = old_lua_pcall(L, nargs, nresults, errfunc);
if (g_is_panel_loaded && !g_is_game_loaded && g_target_L == L) {
std::thread(hook_game_setting_panel, L).detach();
g_is_game_loaded = true;
}
return ret;
}
void hook_game_lua_for_ingame_ui() {
auto libtolua = dlopen("libtolua.so", RTLD_LAZY);
auto sym_luaL_loadbuffer = dlsym(libtolua, "luaL_loadbuffer");
DobbyHook(reinterpret_cast<void*>(sym_luaL_loadbuffer), reinterpret_cast<void*>(my_luaL_loadbuffer), reinterpret_cast<void **>(&old_luaL_loadbuffer));
auto sym_lua_pcall = dlsym(libtolua, "lua_pcall");
DobbyHook(reinterpret_cast<void*>(sym_lua_pcall), reinterpret_cast<void*>(my_lua_pcall), reinterpret_cast<void **>(&old_lua_pcall));
}