From 1785ae6eaf174ca809392a7590a6361119d7a170 Mon Sep 17 00:00:00 2001 From: Nemirtingas Date: Sun, 1 Sep 2019 20:48:27 +0200 Subject: [PATCH] Moved every platform specific code to their own folder --- ImGui/impls/imgui_impl_x11.cpp | 302 --------- ImGui/impls/imgui_impl_x11.h | 21 - ImGui/impls/{ => windows}/imgui_impl_dx10.cpp | 0 ImGui/impls/{ => windows}/imgui_impl_dx10.h | 0 ImGui/impls/{ => windows}/imgui_impl_dx11.cpp | 0 ImGui/impls/{ => windows}/imgui_impl_dx11.h | 0 ImGui/impls/{ => windows}/imgui_impl_dx12.cpp | 0 ImGui/impls/{ => windows}/imgui_impl_dx12.h | 0 ImGui/impls/{ => windows}/imgui_impl_dx9.cpp | 0 ImGui/impls/{ => windows}/imgui_impl_dx9.h | 0 .../impls/{ => windows}/imgui_impl_win32.cpp | 0 ImGui/impls/{ => windows}/imgui_impl_win32.h | 0 overlay_experimental/Base_Hook.cpp | 2 +- overlay_experimental/Linux_Detour.cpp | 637 ------------------ overlay_experimental/Linux_Detour.h | 32 - overlay_experimental/OpenGLX_Hook.cpp | 150 ----- overlay_experimental/OpenGLX_Hook.h | 45 -- overlay_experimental/Renderer_Detector.cpp | 2 +- overlay_experimental/Renderer_Detector.h | 2 +- overlay_experimental/X11_Hook.cpp | 214 ------ overlay_experimental/X11_Hook.h | 50 -- overlay_experimental/steam_overlay.cpp | 10 +- .../{ => windows}/DX10_Hook.cpp | 0 .../{ => windows}/DX10_Hook.h | 0 .../{ => windows}/DX11_Hook.cpp | 0 .../{ => windows}/DX11_Hook.h | 0 .../{ => windows}/DX12_Hook.cpp | 0 .../{ => windows}/DX12_Hook.h | 0 .../{ => windows}/DX9_Hook.cpp | 0 overlay_experimental/{ => windows}/DX9_Hook.h | 0 .../{ => windows}/DirectX_VTables.h | 0 .../{ => windows}/ImGui_ShaderBlobs.cpp | 0 .../{ => windows}/ImGui_ShaderBlobs.h | 0 .../{ => windows}/OpenGL_Hook.cpp | 0 .../{ => windows}/OpenGL_Hook.h | 0 .../{ => windows}/Windows_Hook.cpp | 0 .../{ => windows}/Windows_Hook.h | 2 +- 37 files changed, 9 insertions(+), 1460 deletions(-) delete mode 100644 ImGui/impls/imgui_impl_x11.cpp delete mode 100644 ImGui/impls/imgui_impl_x11.h rename ImGui/impls/{ => windows}/imgui_impl_dx10.cpp (100%) rename ImGui/impls/{ => windows}/imgui_impl_dx10.h (100%) rename ImGui/impls/{ => windows}/imgui_impl_dx11.cpp (100%) rename ImGui/impls/{ => windows}/imgui_impl_dx11.h (100%) rename ImGui/impls/{ => windows}/imgui_impl_dx12.cpp (100%) rename ImGui/impls/{ => windows}/imgui_impl_dx12.h (100%) rename ImGui/impls/{ => windows}/imgui_impl_dx9.cpp (100%) rename ImGui/impls/{ => windows}/imgui_impl_dx9.h (100%) rename ImGui/impls/{ => windows}/imgui_impl_win32.cpp (100%) rename ImGui/impls/{ => windows}/imgui_impl_win32.h (100%) delete mode 100644 overlay_experimental/Linux_Detour.cpp delete mode 100644 overlay_experimental/Linux_Detour.h delete mode 100644 overlay_experimental/OpenGLX_Hook.cpp delete mode 100644 overlay_experimental/OpenGLX_Hook.h delete mode 100644 overlay_experimental/X11_Hook.cpp delete mode 100644 overlay_experimental/X11_Hook.h rename overlay_experimental/{ => windows}/DX10_Hook.cpp (100%) rename overlay_experimental/{ => windows}/DX10_Hook.h (100%) rename overlay_experimental/{ => windows}/DX11_Hook.cpp (100%) rename overlay_experimental/{ => windows}/DX11_Hook.h (100%) rename overlay_experimental/{ => windows}/DX12_Hook.cpp (100%) rename overlay_experimental/{ => windows}/DX12_Hook.h (100%) rename overlay_experimental/{ => windows}/DX9_Hook.cpp (100%) rename overlay_experimental/{ => windows}/DX9_Hook.h (100%) rename overlay_experimental/{ => windows}/DirectX_VTables.h (100%) rename overlay_experimental/{ => windows}/ImGui_ShaderBlobs.cpp (100%) rename overlay_experimental/{ => windows}/ImGui_ShaderBlobs.h (100%) rename overlay_experimental/{ => windows}/OpenGL_Hook.cpp (100%) rename overlay_experimental/{ => windows}/OpenGL_Hook.h (100%) rename overlay_experimental/{ => windows}/Windows_Hook.cpp (100%) rename overlay_experimental/{ => windows}/Windows_Hook.h (97%) diff --git a/ImGui/impls/imgui_impl_x11.cpp b/ImGui/impls/imgui_impl_x11.cpp deleted file mode 100644 index 1065ae4..0000000 --- a/ImGui/impls/imgui_impl_x11.cpp +++ /dev/null @@ -1,302 +0,0 @@ -// dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications) -// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) - -// Implemented features: -// [?] Platform: Clipboard support -// [?] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. -// [?] Platform: Keyboard arrays indexed using -// [?] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. - -#include "imgui.h" -#include "imgui_impl_x11.h" - -#include -#include -#include -#include - -// CHANGELOG -// (minor and older changes stripped away, please see git history for details) -// 2019-08-31: Initial X11 implementation - -// X11 Data -static Display* g_Display = nullptr; -static ImGuiMouseCursor g_LastMouseCursor = ImGuiMouseCursor_COUNT; -static bool g_HasGamepad = false; -static bool g_WantUpdateHasGamepad = true; - -// Functions -bool ImGui_ImplX11_Init(void *display) -{ - //if (!::QueryPerformanceFrequency((LARGE_INTEGER *)&g_TicksPerSecond)) - // return false; - //if (!::QueryPerformanceCounter((LARGE_INTEGER *)&g_Time)) - // return false; - - // Setup back-end capabilities flags - g_Display = reinterpret_cast(display); - ImGuiIO& io = ImGui::GetIO(); - io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) - io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) - io.BackendPlatformName = "imgui_impl_x11"; - io.ImeWindowHandle = nullptr; - - // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. - io.KeyMap[ImGuiKey_Tab] = -1; - io.KeyMap[ImGuiKey_LeftArrow] = -1; - io.KeyMap[ImGuiKey_RightArrow] = -1; - io.KeyMap[ImGuiKey_UpArrow] = -1; - io.KeyMap[ImGuiKey_DownArrow] = -1; - io.KeyMap[ImGuiKey_PageUp] = -1; - io.KeyMap[ImGuiKey_PageDown] = -1; - io.KeyMap[ImGuiKey_Home] = -1; - io.KeyMap[ImGuiKey_End] = -1; - io.KeyMap[ImGuiKey_Insert] = -1; - io.KeyMap[ImGuiKey_Delete] = -1; - io.KeyMap[ImGuiKey_Backspace] = -1; - io.KeyMap[ImGuiKey_Space] = -1; - io.KeyMap[ImGuiKey_Enter] = -1; - io.KeyMap[ImGuiKey_Escape] = -1; - io.KeyMap[ImGuiKey_A] = -1; - io.KeyMap[ImGuiKey_C] = -1; - io.KeyMap[ImGuiKey_V] = -1; - io.KeyMap[ImGuiKey_X] = -1; - io.KeyMap[ImGuiKey_Y] = -1; - io.KeyMap[ImGuiKey_Z] = -1; - return true; -} - -void ImGui_ImplX11_Shutdown() -{ - g_Display = nullptr; -} - -static bool ImGui_ImplWin32_UpdateMouseCursor() -{ - /* - ImGuiIO& io = ImGui::GetIO(); - if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) - return false; - - ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor(); - if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor) - { - // Hide OS mouse cursor if imgui is drawing it or if it wants no cursor - ::SetCursor(NULL); - } - else - { - // Show OS mouse cursor - LPTSTR win32_cursor = IDC_ARROW; - switch (imgui_cursor) - { - case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break; - case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break; - case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break; - case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break; - case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break; - case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break; - case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break; - case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break; - } - ::SetCursor(::LoadCursor(NULL, win32_cursor)); - } - */ - return true; -} - -static void ImGui_ImplWin32_UpdateMousePos() -{ - ImGuiIO& io = ImGui::GetIO(); - - // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) - //if (io.WantSetMousePos) - //{ - // POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; - // ::ClientToScreen(g_hWnd, &pos); - // ::SetCursorPos(pos.x, pos.y); - //} - - // Set mouse position - io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - - -} - -/* TODO: support linux gamepad ? -#ifdef _MSC_VER -#pragma comment(lib, "xinput") -#endif - -// Gamepad navigation mapping -static void ImGui_ImplWin32_UpdateGamepads() -{ - ImGuiIO& io = ImGui::GetIO(); - memset(io.NavInputs, 0, sizeof(io.NavInputs)); - if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0) - return; - - // Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow. - // Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE. - if (g_WantUpdateHasGamepad) - { - XINPUT_CAPABILITIES caps; - g_HasGamepad = (XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS); - g_WantUpdateHasGamepad = false; - } - - XINPUT_STATE xinput_state; - io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad; - if (g_HasGamepad && XInputGetState(0, &xinput_state) == ERROR_SUCCESS) - { - const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad; - io.BackendFlags |= ImGuiBackendFlags_HasGamepad; - - #define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; } - #define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; } - MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A - MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B - MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X - MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y - MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left - MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right - MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up - MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down - MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB - MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB - MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB - MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB - MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768); - MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); - MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767); - MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767); - #undef MAP_BUTTON - #undef MAP_ANALOG - } -} -*/ - -void ImGui_ImplX11_NewFrame() -{ - ImGuiIO& io = ImGui::GetIO(); - IM_ASSERT(io.Fonts->IsBuilt() && "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."); - - // Setup display size (every frame to accommodate for window resizing) - Window rootWnd = DefaultRootWindow(g_Display); - - // Todo: use X11 to get this value - GLint m_viewport[4]; - glGetIntegerv( GL_VIEWPORT, m_viewport ); - io.DisplaySize.x = m_viewport[2]; - io.DisplaySize.y = m_viewport[3]; - - - /* - io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top)); - - // Setup time step - INT64 current_time; - ::QueryPerformanceCounter((LARGE_INTEGER *)¤t_time); - io.DeltaTime = (float)(current_time - g_Time) / g_TicksPerSecond; - g_Time = current_time; - - // Read keyboard modifiers inputs - io.KeyCtrl = (::GetKeyState(VK_CONTROL) & 0x8000) != 0; - io.KeyShift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0; - io.KeyAlt = (::GetKeyState(VK_MENU) & 0x8000) != 0; - io.KeySuper = false; - // io.KeysDown[], io.MousePos, io.MouseDown[], io.MouseWheel: filled by the WndProc handler below. - - // Update OS mouse position - ImGui_ImplWin32_UpdateMousePos(); - - // Update OS mouse cursor with the cursor requested by imgui - ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor(); - if (g_LastMouseCursor != mouse_cursor) - { - g_LastMouseCursor = mouse_cursor; - ImGui_ImplWin32_UpdateMouseCursor(); - } - */ - - // Update game controllers (if enabled and available) - //ImGui_ImplWin32_UpdateGamepads(); -} - -// Process Win32 mouse/keyboard inputs. -// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. -// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. -// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. -// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. -// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds. -// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag. -IMGUI_IMPL_API int ImGui_ImplX11_EventHandler(XEvent &event) -{ - if (ImGui::GetCurrentContext() == NULL) - return 0; - - ImGuiIO& io = ImGui::GetIO(); - switch (event.type) - { - case ButtonPress: - switch(event.xbutton.button ) - { - case Button1: case Button2: case Button3: - io.MouseDown[event.xbutton.button-1] = true; - break; - - case Button4: // Mouse wheel up - event.xbutton.button = Button4; - //io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; - return 0; - - case Button5: // Mouse wheel down - event.xbutton.button = Button5; - //io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA; - return 0; - } - - break; - - case ButtonRelease: - switch(event.xbutton.button ) - { - case Button1: case Button2: case Button3: - io.MouseDown[event.xbutton.button-1] = false; - break; - } - break; - - case KeyPress: - case KeyRelease: - break; - - case MotionNotify: - io.MousePos.x = event.xmotion.x; - io.MousePos.y = event.xmotion.y; - break; - } - /* - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - if (wParam < 256) - io.KeysDown[wParam] = 1; - return 0; - case WM_KEYUP: - case WM_SYSKEYUP: - if (wParam < 256) - io.KeysDown[wParam] = 0; - return 0; - case WM_CHAR: - // You can also use ToAscii()+GetKeyboardState() to retrieve characters. - io.AddInputCharacter((unsigned int)wParam); - return 0; - case WM_DEVICECHANGE: - if ((UINT)wParam == DBT_DEVNODES_CHANGED) - g_WantUpdateHasGamepad = true; - return 0; - } - */ - return 0; -} - diff --git a/ImGui/impls/imgui_impl_x11.h b/ImGui/impls/imgui_impl_x11.h deleted file mode 100644 index 387609a..0000000 --- a/ImGui/impls/imgui_impl_x11.h +++ /dev/null @@ -1,21 +0,0 @@ -// dear imgui: Platform Binding for Windows (standard windows API for 32 and 64 bits applications) -// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..) - -// Implemented features: -// [X] Platform: Clipboard support (for Win32 this is actually part of core imgui) -// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'. -// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE). -// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'. - -#pragma once - -IMGUI_IMPL_API bool ImGui_ImplX11_Init(void* display); -IMGUI_IMPL_API void ImGui_ImplX11_Shutdown(); -IMGUI_IMPL_API void ImGui_ImplX11_NewFrame(); - -// Handler for Win32 messages, update mouse/keyboard data. -// You may or not need this for your implementation, but it can serve as reference for handling inputs. -// Intentionally commented out to avoid dragging dependencies on types. You can COPY this line into your .cpp code instead. -/* -IMGUI_IMPL_API int ImGui_ImplX11_EventHandler(XEvent *event); -*/ diff --git a/ImGui/impls/imgui_impl_dx10.cpp b/ImGui/impls/windows/imgui_impl_dx10.cpp similarity index 100% rename from ImGui/impls/imgui_impl_dx10.cpp rename to ImGui/impls/windows/imgui_impl_dx10.cpp diff --git a/ImGui/impls/imgui_impl_dx10.h b/ImGui/impls/windows/imgui_impl_dx10.h similarity index 100% rename from ImGui/impls/imgui_impl_dx10.h rename to ImGui/impls/windows/imgui_impl_dx10.h diff --git a/ImGui/impls/imgui_impl_dx11.cpp b/ImGui/impls/windows/imgui_impl_dx11.cpp similarity index 100% rename from ImGui/impls/imgui_impl_dx11.cpp rename to ImGui/impls/windows/imgui_impl_dx11.cpp diff --git a/ImGui/impls/imgui_impl_dx11.h b/ImGui/impls/windows/imgui_impl_dx11.h similarity index 100% rename from ImGui/impls/imgui_impl_dx11.h rename to ImGui/impls/windows/imgui_impl_dx11.h diff --git a/ImGui/impls/imgui_impl_dx12.cpp b/ImGui/impls/windows/imgui_impl_dx12.cpp similarity index 100% rename from ImGui/impls/imgui_impl_dx12.cpp rename to ImGui/impls/windows/imgui_impl_dx12.cpp diff --git a/ImGui/impls/imgui_impl_dx12.h b/ImGui/impls/windows/imgui_impl_dx12.h similarity index 100% rename from ImGui/impls/imgui_impl_dx12.h rename to ImGui/impls/windows/imgui_impl_dx12.h diff --git a/ImGui/impls/imgui_impl_dx9.cpp b/ImGui/impls/windows/imgui_impl_dx9.cpp similarity index 100% rename from ImGui/impls/imgui_impl_dx9.cpp rename to ImGui/impls/windows/imgui_impl_dx9.cpp diff --git a/ImGui/impls/imgui_impl_dx9.h b/ImGui/impls/windows/imgui_impl_dx9.h similarity index 100% rename from ImGui/impls/imgui_impl_dx9.h rename to ImGui/impls/windows/imgui_impl_dx9.h diff --git a/ImGui/impls/imgui_impl_win32.cpp b/ImGui/impls/windows/imgui_impl_win32.cpp similarity index 100% rename from ImGui/impls/imgui_impl_win32.cpp rename to ImGui/impls/windows/imgui_impl_win32.cpp diff --git a/ImGui/impls/imgui_impl_win32.h b/ImGui/impls/windows/imgui_impl_win32.h similarity index 100% rename from ImGui/impls/imgui_impl_win32.h rename to ImGui/impls/windows/imgui_impl_win32.h diff --git a/overlay_experimental/Base_Hook.cpp b/overlay_experimental/Base_Hook.cpp index 418f50b..c04b39d 100644 --- a/overlay_experimental/Base_Hook.cpp +++ b/overlay_experimental/Base_Hook.cpp @@ -39,7 +39,7 @@ void Base_Hook::UnhookAll() } #else -#include "Linux_Detour.h" +#include "linux/Linux_Detour.h" void Base_Hook::BeginHook() { diff --git a/overlay_experimental/Linux_Detour.cpp b/overlay_experimental/Linux_Detour.cpp deleted file mode 100644 index 984e815..0000000 --- a/overlay_experimental/Linux_Detour.cpp +++ /dev/null @@ -1,637 +0,0 @@ -#include "Linux_Detour.h" - -#include -#include - -#include - -#include -#include -#include -#include - -//------------------------------------------------------------------------------// -// Helper funcs -//------------------------------------------------------------------------------// -constexpr static auto relative_jump_size = 5; -constexpr static auto relative_addr_jump_size = sizeof(int32_t); -constexpr static auto absolute_jump_size = 6; - -struct -{ - bool has_r_m; - uint8_t base_size; -} s_opcodes[256] = -{ - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 0 - 7 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 8 - 15 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 16 - 23 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 24 - 31 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 32 - 39 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 40 - 47 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 48 - 55 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 56 - 63 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 64 - 71 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 72 - 79 - // PUSH ... - {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, // 80 - 87 - // POP ... - {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, // 88 - 95 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 96 - 103 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 104 - 111 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 112 - 129 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 120 - 127 - // MOV, ADD, ... R8 <- IMM8 TEST_8 TEST XCHG_8 XCHG - {true , 3}, {true , 6}, {true , 3}, {true , 3}, {true , 2}, {true , 2}, {true , 2}, {true , 2}, // 128 - 135 - // MOV_8 MOV MOV_R8_B MOV_R32_D MOV_32_ES LEA MOV_ES_32 POP - {true , 2}, {true , 2}, {true , 2}, {true , 2}, {true , 2}, {true , 2}, {true , 2}, {false, 2}, // 136 - 143 - // NOP - {false, 1}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 144 - 151 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 152 - 159 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 160 - 167 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 168 - 175 - // MOV_AL MOV_CL MOV_DL MOV_BL MOV_AH MOV_CH MOV_DH MOV_BH - {false, 2}, {false, 2}, {false, 2}, {false, 2}, {false, 2}, {false, 2}, {false, 2}, {false, 2}, // 176 - 183 - // MOV_EAX MOV_ECX MOV_EDX MOV_EBX MOV_ESP MOV_EBP MOV_ESI MOV_EDI, - {false, 5}, {false, 5}, {false, 5}, {false, 5}, {false, 5}, {false, 5}, {false, 5}, {false, 5}, // 184 - 191 - // RETN_IMM16 RETN - {false, 0}, {false, 0}, {false, 3}, {false, 1}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 192 - 199 - // LEAVE RETF_IMM16 RETF INT INT_IMM8 INTO - {false, 0}, {false, 1}, {false, 3}, {false, 1}, {false, 1}, {false, 1}, {false, 1}, {false, 0}, // 200 - 207 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 208 - 215 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 216 - 223 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 224 - 231 - // CALL JMP LJMP SHORT_JMP - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 232 - 239 - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, // 240 - 247 - // EXTENDED - {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 0}, {false, 6}, // 248 - 255 -}; - -static constexpr auto mod_mask = 0xC0; -static constexpr auto register_addressing_mode = 0xC0; -static constexpr auto four_bytes_signed_displacement = 0x80; -static constexpr auto one_byte_signed_displacement = 0x40; - -static constexpr auto rm_mask = 0x05; -static constexpr auto displacement_only_addressing = 0x05; -static constexpr auto sib_with_no_displacement = 0x04; -static constexpr auto register_indirect_addressing_mode = 0x00; - -enum opcodes_e // Commonly used opcode in the beginning of functions -{ - PUSH_EAX = 0x50, PUSH_ECX, PUSH_EDX, PUSH_EBX, PUSH_ESP, PUSH_EBP, PUSH_ESI, PUSH_EDI, - POP_EAX , POP_ECX , POP_EDX , POP_EBX , POP_ESP , POP_EBP , POP_ESI , POP_EDI , - - R8_IMM8 = 0x80, R32_IMM32, R8_IMM8_2, R32_IMM8, - TEST_8, TEST, - XCHG_8, XCHG, - MOV_8 , MOV, - MOV_8_B, MOV_32_D, MOV_32_ES, - LEA, - MOV_ES_32, POP, - NOP, - MOV_AL = 0xB0, MOV_CL, MOV_DL, MOV_BL, MOV_AH, MOV_CH, MOV_DH, MOV_BH, - MOV_EAX, MOV_ECX, MOV_EDX, MOV_EBX, MOV_ESP, MOV_EBP, MOV_ESI, MOV_EDI, - RETN_IMM16 = 0xC2, RETN, - LEAVE = 0xC9, RETF_IMM16, RETF, INT, INT_IMM8, INTO, - CALL = 0xE8, // 5 bytes don't process - JMP, // 5 bytes don't process - LJMP, // 7 bytes, don't process - SHORT_JMP, // 2 bytes don't process - EXTENDED = 0xFF, -}; - -const char* opcode_name(uint8_t opcode) -{ -#define NAME(opcode_name) case opcode_name: return #opcode_name - switch( opcode ) - { - NAME(PUSH_EAX); NAME(PUSH_ECX); NAME(PUSH_EDX); NAME(PUSH_EBX); - NAME(PUSH_ESP); NAME(PUSH_EBP); NAME(PUSH_ESI); NAME(PUSH_EDI); - NAME(POP_EAX); NAME(POP_ECX); NAME(POP_EDX); NAME(POP_EBX); - NAME(POP_ESP); NAME(POP_EBP); NAME(POP_ESI); NAME(POP_EDI); - NAME(R8_IMM8); NAME(R32_IMM32); NAME(R8_IMM8_2); NAME(R32_IMM8); - NAME(TEST_8); NAME(TEST); NAME(XCHG_8); NAME(XCHG); NAME(MOV_8); NAME(MOV); - NAME(MOV_8_B); NAME(MOV_32_D); NAME(MOV_32_ES); - NAME(LEA); - NAME(MOV_ES_32); NAME(POP); - NAME(NOP); - NAME(MOV_AL) ; NAME(MOV_CL) ; NAME(MOV_DL) ; NAME(MOV_BL) ; NAME(MOV_AH) ; NAME(MOV_CH) ; NAME(MOV_DH) ; NAME(MOV_BH) ; - NAME(MOV_EAX); NAME(MOV_ECX); NAME(MOV_EDX); NAME(MOV_EBX); NAME(MOV_ESP); NAME(MOV_EBP); NAME(MOV_ESI); NAME(MOV_EDI); - NAME(RETN_IMM16); NAME(RETN); NAME(LEAVE); NAME(RETF_IMM16); NAME(RETF); - NAME(INT); NAME(INT_IMM8); NAME(INTO); NAME(CALL); NAME(JMP); NAME(LJMP); NAME(SHORT_JMP); - NAME(EXTENDED); - } -#undef NAME - return "no registered"; -} - -#pragma pack(push, 1) - -struct trampoline_x86_t -{ - uint8_t trampolineBytes[16+relative_jump_size]; // trampoline + original function opcodes - uint8_t hookJump[relative_jump_size]; // jump to hook addr, needed because of relative jump overflow - uint8_t nOriginalBytes; // number of original function bytes bkp - uint8_t originalBytes[16]; // original function bytes -}; - -typedef trampoline_x86_t trampoline_t; - -struct trampoline_region_t -{ - uint32_t header; - uint8_t numTrampolines; // current trampolines allocated - trampoline_t *trampolines_start; // start pointer of current region trampolines - trampoline_t *next_free_trampoline; // next free trampoline in region -}; - -#pragma pack(pop) - -struct transaction_t -{ - bool detach; - void** ppOriginalFunc; - trampoline_t *trampoline; -}; - -static std::list trampoline_regions; - -static bool transaction_started = false; -static std::list cur_transaction; - -inline size_t page_size() -{ - static size_t _page_size = sysconf(_SC_PAGESIZE); - return _page_size; -} - -inline size_t region_size() -{ - return page_size(); -} - -static uint8_t max_trampolines_in_region = region_size() / sizeof(trampoline_t); - -inline void* library_address_by_handle(void *library) -{ - return (library == nullptr ? nullptr : *reinterpret_cast(library)); -} - -inline size_t page_align(size_t size, size_t page_size) -{ - return (size+(page_size-1)) & (((size_t)-1)^(page_size-1)); -} - -inline void* page_addr(void* addr, size_t page_size) -{ - return reinterpret_cast(reinterpret_cast(addr) & (((size_t)-1)^(page_size-1))); -} - -//////////////////////////////////////////////////// -/// Tiny disasm - -bool is_opcode_terminating_function(uint8_t* pCode) -{ - switch( *pCode ) - { - case LEAVE: - case RETN: case RETN_IMM16: - case RETF: case RETF_IMM16: - case INT: case INT_IMM8: case INTO: - return true; - } - return false; -} - -int find_space_for_trampoline(uint8_t* func, int bytes_needed) -{ - if( func == nullptr ) - return -1; - - int code_len = -1; - bool search = true; - uint8_t *startCode = reinterpret_cast(func); - uint8_t *pCode = startCode; - while( search ) // Find opcodes size and try to find at least 5 bytes for our JMP - { - if( is_opcode_terminating_function(pCode) ) - break; - - if( s_opcodes[*pCode].has_r_m ) - { // MOD-REG-R/M Byte - // 7 6 5 4 3 2 1 0 - bits - //[ MOD ][ REG ][ R/M ] - switch( pCode[1] & mod_mask ) // Check MOD to know how many bytes we have after this opcode - { - case register_addressing_mode : pCode += s_opcodes[*pCode].base_size ; break;// register addressing mode [opcode] [R/M] [XX] - case four_bytes_signed_displacement: pCode += s_opcodes[*pCode].base_size+5; break;// address mode byte + 4 bytes displacement - case one_byte_signed_displacement : pCode += s_opcodes[*pCode].base_size+2; break;// address mode byte + 1 byte displacement - case 0x00: - switch( pCode[1] & rm_mask ) - { - case sib_with_no_displacement : pCode += s_opcodes[*pCode].base_size+1; break;// SIB with no displacement - case displacement_only_addressing : pCode += s_opcodes[*pCode].base_size+4; break;// 4 bytes Displacement only addressing mode - case register_indirect_addressing_mode: pCode += s_opcodes[*pCode].base_size; // Register indirect addressing mode - } - } - } - else if( s_opcodes[*pCode].base_size ) - { - pCode += s_opcodes[*pCode].base_size; - } - else - { - switch( *pCode ) - { - case CALL: case JMP: case LJMP: case SHORT_JMP: - //std::cerr << "CALL and JMP are not supported for trampolines." << std::endl; - search = false; - break; - - case EXTENDED: - //std::cerr << "IMPORT_JUMP is not handled" << std::endl; - if (pCode[1] == 0x25) // This is an imported function - { // Get the true function call - //pCode = (uint8_t*)*(pCode+2); - //startCode = pCode; - // For now disable this case - search = false; - } - else - { - search = false; - } - break; - - default: - //std::cerr << "opcode " << std::hex << (uint32_t)*pCode << " no registered" << std::endl; - search = false; - } - } - - if( (pCode - startCode) >= bytes_needed && search ) - { - search = false; - code_len = pCode-startCode; - } - } - return code_len; -} - -/////////////////////////////////////////// -// Tiny asm - -inline uint8_t* gen_immediate_addr(uint8_t* opcode_addr, uint8_t* dest) -{ - *reinterpret_cast(opcode_addr) = (dest - (opcode_addr + relative_addr_jump_size)); - return opcode_addr + relative_addr_jump_size; -} - -inline uint8_t* gen_immediate_jump(uint8_t* opcode_addr, uint8_t* dest) -{ - *opcode_addr++ = JMP; - return gen_immediate_addr(opcode_addr, dest); -} - -inline uint8_t* gen_immediate_call(uint8_t* opcode_addr, uint8_t* dest) -{ - *opcode_addr++ = CALL; - return gen_immediate_addr(opcode_addr, dest); -} - -uint8_t* relative_addr_to_absolute(int32_t rel_addr, uint8_t *code_addr) -{ - return code_addr + rel_addr + relative_jump_size; -} - -void alloc_new_trampoline_region() -{ - trampoline_region_t region; - - region.numTrampolines = 0; - // allocate new trampoline right in the middle of memory so relative jump can access any function - region.trampolines_start = reinterpret_cast(mmap((void*)std::numeric_limits::max(), // allocate the page near the half of memory addressing - region_size(), // size - PROT_EXEC|PROT_WRITE|PROT_READ, // protection - MAP_PRIVATE|MAP_32BIT|MAP_ANONYMOUS, // don't map a file but memory - -1, // fd = -1 - 0) // offset - ); - // Fill the region with 0 - std::fill(reinterpret_cast(region.trampolines_start), reinterpret_cast(region.trampolines_start)+region_size(), 0); - region.next_free_trampoline = region.trampolines_start; - // Protect trampoline region memory - mprotect((void*)region.trampolines_start, region_size(), PROT_READ|PROT_EXEC); - - trampoline_regions.push_back(region); -} - -trampoline_t* get_free_trampoline() -{ - if (!transaction_started) - return nullptr; - - trampoline_t *res = nullptr; - auto it = std::find_if(trampoline_regions.begin(), trampoline_regions.end(), [&res](trampoline_region_t ®ion){ - if( region.numTrampolines == max_trampolines_in_region ) - return false; - return true; - }); - - if( it == trampoline_regions.end() ) - { - alloc_new_trampoline_region(); - it = --trampoline_regions.end(); - } - res = it->next_free_trampoline; - - trampoline_t *next_new_trampoline = res+1; - if( it->numTrampolines != max_trampolines_in_region ) - { - while( next_new_trampoline->nOriginalBytes != 0 ) - { - ++next_new_trampoline; - } - } - else - { - next_new_trampoline = nullptr; - } - it->next_free_trampoline = next_new_trampoline; - - ++it->numTrampolines; - - return res; -} - -void clear_trampoline(trampoline_region_t& region, trampoline_t *trampoline) -{ - --region.numTrampolines; - - std::fill(reinterpret_cast(trampoline), reinterpret_cast(trampoline+1), 0); - if( region.next_free_trampoline == nullptr || region.next_free_trampoline > trampoline ) - region.next_free_trampoline = trampoline; -} - -inline bool is_page_inside_region(void *page, trampoline_region_t& region) -{ - if( page >= region.trampolines_start && page <= (region.trampolines_start+region_size()) ) - return true; - return false; -} - -//------------------------------------------------------------------------------// - -/* -#include -#include - -static pid_t tid = 0; - -struct dism_pthread_t -{ - uint32_t d0; - uint32_t d4; - uint32_t d8; - uint32_t dc; - uint32_t d10; - uint32_t d14; - uint32_t d18; - uint32_t d1c; - uint32_t d20; - uint32_t d24; - uint32_t d28; - uint32_t d2c; - uint32_t d30; - uint32_t d34; - uint32_t d38; - uint32_t d3c; - uint32_t d40; - uint32_t d44; - uint32_t d48; - uint32_t d4c; - uint32_t d50; - uint32_t d54; - uint32_t d58; - uint32_t d5c; - uint32_t d60; - uint32_t d64; - pid_t task_id; -}; -*/ - -int Linux_Detour::update_thread(pthread_t thread_id) -{ - //dism_pthread_t *dt = (dism_pthread_t*)thread_id; - - // dt->task_id == syscall(SYS_gettid); - - - return 0; -} - -int Linux_Detour::transaction_begin() -{ - if( transaction_started ) - return -1; - - transaction_started = true; - - return 0; -} - -int Linux_Detour::transaction_abort() -{ - if(!transaction_started) - return -1; - - for( auto &i : cur_transaction ) - { - trampoline_t *trampoline = i.trampoline; - void *page_start = page_addr(reinterpret_cast(trampoline), page_size()); - auto it = std::find_if(trampoline_regions.begin(), trampoline_regions.end(), [page_start](trampoline_region_t ®ion){ - if( is_page_inside_region(page_start, region) ) - return true; - return false; - }); - if( it != trampoline_regions.end() ) - { - clear_trampoline(*it, trampoline); - } - } - cur_transaction.clear(); - transaction_started = false; - - return 0; -} - -int Linux_Detour::transaction_commit() -{ - if (!transaction_started ) - return -1; - - for( auto &i : cur_transaction) - { - trampoline_t *trampoline = i.trampoline; - void **ppOriginalFunc = i.ppOriginalFunc; - - int res; - - if( i.detach ) - { - void* trampoline_page = page_addr(reinterpret_cast(trampoline), page_size()); - - *ppOriginalFunc = (void*)(relative_addr_to_absolute(*reinterpret_cast(trampoline->trampolineBytes+trampoline->nOriginalBytes+1), - trampoline->trampolineBytes)); - - void* originalFunctionPage = page_addr(*ppOriginalFunc, page_size()); - - // Allow write on the original func - res = mprotect(originalFunctionPage, page_size()*2, PROT_READ|PROT_WRITE|PROT_EXEC); - - // Write the original opcodes - std::copy(trampoline->originalBytes, trampoline->originalBytes+trampoline->nOriginalBytes, - reinterpret_cast(*ppOriginalFunc)); - - // Remove write permission - res = mprotect(originalFunctionPage, page_size()*2, PROT_READ|PROT_EXEC); - - // Allow write on trampoline page - res = mprotect(trampoline_page, page_size()*2, PROT_READ|PROT_WRITE|PROT_EXEC); - - clear_trampoline(*reinterpret_cast(trampoline_page), trampoline); - - // Remove write permission - res = mprotect(trampoline_page, page_size()*2, PROT_READ|PROT_EXEC); - } - else - { - void* originalFunctionPage = page_addr(*ppOriginalFunc, page_size()); - - // Allow write on the original func - res = mprotect(originalFunctionPage, page_size()*2, PROT_READ|PROT_WRITE|PROT_EXEC); - - // Write the jump to trampoline - gen_immediate_jump(reinterpret_cast(*ppOriginalFunc), trampoline->hookJump); - - // Remove write permission - res = mprotect(originalFunctionPage, page_size()*2, PROT_READ|PROT_EXEC); - - *ppOriginalFunc = (void*)(trampoline->trampolineBytes); - } - } - cur_transaction.clear(); - transaction_started = false; - - return 0; -} - -int Linux_Detour::unhook_func(void** ppOriginalFunc, void* _hook) -{ - if( !transaction_started ) - return -EPERM; - - if( ppOriginalFunc == nullptr || _hook == nullptr || *ppOriginalFunc == nullptr ) - return -EINVAL; - - trampoline_t *trampoline = reinterpret_cast(*ppOriginalFunc); - void *page_start = page_addr(reinterpret_cast(trampoline), page_size()); - auto it = std::find_if(trampoline_regions.begin(), trampoline_regions.end(), [page_start](trampoline_region_t ®ion){ - if( is_page_inside_region(page_start, region) ) - return true; - return false; - }); - if( it != trampoline_regions.end() ) - { - cur_transaction.push_back({true, ppOriginalFunc, trampoline}); - } - - return -EINVAL; -} - -int Linux_Detour::hook_func(void** ppOriginalFunc, void* _hook) -{ - if( !transaction_started ) - return -EPERM; - - if( ppOriginalFunc == nullptr || _hook == nullptr || *ppOriginalFunc == nullptr ) - return -EINVAL; - - uint8_t* hook = reinterpret_cast(_hook); - uint8_t* pOriginalFunc = reinterpret_cast(*ppOriginalFunc); - int code_len = find_space_for_trampoline(pOriginalFunc, relative_jump_size); - - if( code_len < relative_jump_size ) - return -ENOSPC; - - // Allocate the trampoline, try to put it right in the middle of the mem, so a relative jump can access any function in the app (+/-2GB) - // - // Our hook is a 5 bytes JMP (1 bytes for opcode, 4 for RELATIVE jump) - // /!\ TODO: Add checks on JMP overflow - - trampoline_t *trampoline = get_free_trampoline(); - uint8_t *pTrampolineCode = trampoline->trampolineBytes; - - void* trampoline_page = page_addr(reinterpret_cast(trampoline), page_size()); - - // Enable write to the trampoline region - mprotect(trampoline_page, page_size()*2, PROT_READ|PROT_WRITE|PROT_EXEC); - // Create relative jmp to hook - gen_immediate_jump(trampoline->hookJump, hook); - // Copy original opcodes - trampoline->nOriginalBytes = code_len; - std::copy((uint8_t*)pOriginalFunc, ((uint8_t*)pOriginalFunc)+code_len, trampoline->originalBytes); - std::copy((uint8_t*)pOriginalFunc, ((uint8_t*)pOriginalFunc)+code_len, pTrampolineCode); - pTrampolineCode += code_len; - // Create the relative jmp to original (function + backed up opcodes) - pTrampolineCode = gen_immediate_jump(pTrampolineCode, pOriginalFunc+code_len); - pTrampolineCode += relative_addr_jump_size; - - // Disable trampoline region write - mprotect(trampoline_page, page_size()*2, PROT_READ|PROT_EXEC); - - cur_transaction.push_back({false, ppOriginalFunc, trampoline}); - - return 0; -} - -/* ------ DOCUMENTATION ------ -http://www.c-jump.com/CIS77/CPU/x86/lecture.html <- some help to understand [MOD][REG][R/M] (see paragraph #6) -http://shell-storm.org/online/Online-Assembler-and-Disassembler <- online assembler -http://ref.x86asm.net/coder32.html <- opcodes reference - -X86 - -push ebx : 0x53 -sub esp ?? : 0x83 0xEC 0x?? -call ????????: 0xE8 0x?? 0x?? 0x?? 0x?? - - -// relative jmp: ???????? = dst_addr - curr_addr - 5 -jmp ???????? : 0xe9 0x?? 0x?? 0x?? 0x?? -destination = 0x8dba8 -jmp location: 0x91995 - opcodes: e9 0e c2 ff ff -0e c2 ff ff = 0x8dba8 - 0x91995 - 5 - -// short jmp: ?? = dst_addr - curr_addr - 2 -jmp short ??: 0xeb 0x?? -destination = 0x91964 -jmp location: 0x9198f - opcodes: 0xeb 0xd3 -d3 = 0x91964 - 0x9198f - 2 - -X64 - -TODO: - Hint: make relative jump to near (+/-2Gb) code : 5 bytes - load absolute addr into R11 and call a jmp on register R11 : 13 bytes - Or - Reuse x86 relative jmp method - -Example: -mov r11, 0x0123456789abcdef -> 0x49 0xbb 0xef 0xcd 0xab 0x89 0x67 0x45 0x23 0x01 -jmp r11 -> 0x41 0xff 0xe3 - - -*/ diff --git a/overlay_experimental/Linux_Detour.h b/overlay_experimental/Linux_Detour.h deleted file mode 100644 index 731d426..0000000 --- a/overlay_experimental/Linux_Detour.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef LINUX_DETOUR_H -#define LINUX_DETOUR_H - -#include -#include -#include -#include - -class Linux_Detour -{ - public: - static int update_thread(pthread_t thread_id); - static int transaction_begin(); - static int transaction_abort(); - static int transaction_commit(); - static int hook_func(void** ppOriginalFunc, void* _hook); - static int unhook_func(void** ppOriginalFunc, void* _hook); - - private: - static int hook_func_abs(void** ppOriginalFunc, void* _hook); - static int hook_func_rel(void** ppOriginalFunc, void* _hook); - - Linux_Detour() = delete; - Linux_Detour(Linux_Detour const&) = delete; - Linux_Detour(Linux_Detour &&) = delete; - Linux_Detour& operator=(Linux_Detour const&) = delete; - Linux_Detour& operator=(Linux_Detour &&) = delete; -}; - -extern "C" void *elf_hook(char const *library_filename, void const *library_address, char const *function_name, void const *substitution_address); - -#endif // LINUX_DETOUR_H diff --git a/overlay_experimental/OpenGLX_Hook.cpp b/overlay_experimental/OpenGLX_Hook.cpp deleted file mode 100644 index a4fa3da..0000000 --- a/overlay_experimental/OpenGLX_Hook.cpp +++ /dev/null @@ -1,150 +0,0 @@ -#include "OpenGLX_Hook.h" -#include "X11_Hook.h" -#include "Renderer_Detector.h" -#include "../dll/dll.h" - -#ifndef NO_OVERLAY - -#include -#include - -#include "steam_overlay.h" - -OpenGLX_Hook* OpenGLX_Hook::_inst = nullptr; - -bool OpenGLX_Hook::start_hook() -{ - bool res = true; - if (!hooked) - { - if (!X11_Hook::Inst()->start_hook()) - return false; - - GLenum err = glewInit(); - - if (err == GLEW_OK) - { - PRINT_DEBUG("Hooked OpenGLX\n"); - - hooked = true; - Renderer_Detector::Inst().renderer_found(this); - - UnhookAll(); - BeginHook(); - HookFuncs( - std::make_pair(&(void*&)_glXSwapBuffers, (void*)&OpenGLX_Hook::MyglXSwapBuffers) - ); - EndHook(); - - get_steam_client()->steam_overlay->HookReady(); - } - else - { - PRINT_DEBUG("Failed to hook OpenGLX\n"); - /* Problem: glewInit failed, something is seriously wrong. */ - PRINT_DEBUG("Error: %s\n", glewGetErrorString(err)); - res = false; - } - } - return true; -} - -void OpenGLX_Hook::resetRenderState() -{ - if (initialized) - { - ImGui_ImplOpenGL3_Shutdown(); - //X11_Hook::Inst()->resetRenderState(); - ImGui::DestroyContext(); - - initialized = false; - } -} - -// Try to make this function and overlay's proc as short as possible or it might affect game's fps. -void OpenGLX_Hook::prepareForOverlay(Display* display) -{ - PRINT_DEBUG("Called SwapBuffer hook"); - - if( ! initialized ) - { - ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); - io.IniFilename = NULL; - - ImGui_ImplOpenGL3_Init(); - initialized = true; - } - - if( initialized ) - { - ImGuiIO& io = ImGui::GetIO(); - - GLint m_viewport[4]; - glGetIntegerv( GL_VIEWPORT, m_viewport ); - int width = m_viewport[2]; - int height = m_viewport[3]; - - ImGui_ImplOpenGL3_NewFrame(); - X11_Hook::Inst()->prepareForOverlay(display); - - ImGui::NewFrame(); - - get_steam_client()->steam_overlay->OverlayProc(width, height); - - ImGui::EndFrame(); - - ImGui::Render(); - - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - } -} - -void OpenGLX_Hook::MyglXSwapBuffers(Display* display, GLXDrawable drawable) -{ - OpenGLX_Hook::Inst()->prepareForOverlay(display); - OpenGLX_Hook::Inst()->_glXSwapBuffers(display, drawable); -} - -OpenGLX_Hook::OpenGLX_Hook(): - initialized(false), - hooked(false), - _glXSwapBuffers(nullptr) -{ - //_library = dlopen(DLL_NAME); -} - -OpenGLX_Hook::~OpenGLX_Hook() -{ - PRINT_DEBUG("OpenGLX Hook removed\n"); - - if (initialized) - { - ImGui_ImplOpenGL3_Shutdown(); - ImGui::DestroyContext(); - } - - //dlclose(_library); - - _inst = nullptr; -} - -OpenGLX_Hook* OpenGLX_Hook::Inst() -{ - if (_inst == nullptr) - _inst = new OpenGLX_Hook; - - return _inst; -} - -const char* OpenGLX_Hook::get_lib_name() const -{ - return DLL_NAME; -} - -void OpenGLX_Hook::loadFunctions(decltype(glXSwapBuffers)* pfnglXSwapBuffers) -{ - _glXSwapBuffers = pfnglXSwapBuffers; -} - -#endif//NO_OVERLAY diff --git a/overlay_experimental/OpenGLX_Hook.h b/overlay_experimental/OpenGLX_Hook.h deleted file mode 100644 index 271d50f..0000000 --- a/overlay_experimental/OpenGLX_Hook.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef __INCLUDED_OPENGLX_HOOK_H__ -#define __INCLUDED_OPENGLX_HOOK_H__ - -#include "Base_Hook.h" - -#ifdef __LINUX__ -#ifndef NO_OVERLAY -#include -#include - -class OpenGLX_Hook : public Base_Hook -{ -public: - static constexpr const char *DLL_NAME = "libGLX.so"; - -private: - static OpenGLX_Hook* _inst; - - // Variables - bool hooked; - bool initialized; - - // Functions - OpenGLX_Hook(); - - void resetRenderState(); - void prepareForOverlay(Display* display); - - // Hook to render functions - static void MyglXSwapBuffers(Display* display, GLXDrawable drawable); - - decltype(glXSwapBuffers)* _glXSwapBuffers; - -public: - virtual ~OpenGLX_Hook(); - - bool start_hook(); - static OpenGLX_Hook* Inst(); - virtual const char* get_lib_name() const; - void loadFunctions(decltype(glXSwapBuffers)* pfnglXSwapBuffers); -}; - -#endif//NO_OVERLAY -#endif//__LINUX__ -#endif//__INCLUDED_OPENGLX_HOOK_H__ diff --git a/overlay_experimental/Renderer_Detector.cpp b/overlay_experimental/Renderer_Detector.cpp index e15957c..8a429d0 100644 --- a/overlay_experimental/Renderer_Detector.cpp +++ b/overlay_experimental/Renderer_Detector.cpp @@ -625,7 +625,7 @@ Renderer_Detector::Renderer_Detector(): {} #else// defined(__LINUX__)//!STEAM_WIN32 -#include "X11_Hook.h" +#include "linux/X11_Hook.h" #include #include diff --git a/overlay_experimental/Renderer_Detector.h b/overlay_experimental/Renderer_Detector.h index a7ba624..e0e5939 100644 --- a/overlay_experimental/Renderer_Detector.h +++ b/overlay_experimental/Renderer_Detector.h @@ -64,7 +64,7 @@ public: }; #elif defined __LINUX__ -#include "OpenGLX_Hook.h" +#include "linux/OpenGLX_Hook.h" class Renderer_Detector { diff --git a/overlay_experimental/X11_Hook.cpp b/overlay_experimental/X11_Hook.cpp deleted file mode 100644 index 81ec275..0000000 --- a/overlay_experimental/X11_Hook.cpp +++ /dev/null @@ -1,214 +0,0 @@ -#include "X11_Hook.h" -#include "Renderer_Detector.h" -#include "../dll/dll.h" - -#ifndef NO_OVERLAY - -#include -#include - -#include -#include -#include - -extern int ImGui_ImplX11_EventHandler(XEvent &event); - -X11_Hook* X11_Hook::_inst = nullptr; - -bool X11_Hook::start_hook() -{ - bool res = true; - if (!hooked) - { - res = false; - std::ifstream flibrary("/proc/self/maps"); - std::string line; - while( std::getline(flibrary, line) ) - { - if( strcasestr(line.c_str(), DLL_NAME) != nullptr ) - { - _library = dlopen(line.substr(line.find('/')).c_str(), RTLD_NOW); - - if( _library != nullptr ) - { - // Hook only this - _XEventsQueued = (decltype(_XEventsQueued))dlsym(_library, "XEventsQueued"); - // Thoses are needed to ignore some events when overlay is on - _XPeekEvent = (decltype(_XPeekEvent))dlsym(_library, "XPeekEvent"); - _XNextEvent = (decltype(_XNextEvent))dlsym(_library, "XNextEvent"); - _XKeysymToKeycode = (decltype(_XKeysymToKeycode))dlsym(_library, "XKeysymToKeycode"); - _XLookupKeysym = (decltype(_XLookupKeysym))dlsym(_library, "XLookupKeysym"); - - if( _XEventsQueued != nullptr && _XPeekEvent != nullptr - && _XNextEvent != nullptr && _XKeysymToKeycode != nullptr - && _XLookupKeysym != nullptr ) - { - PRINT_DEBUG("Hooked X11\n"); - hooked = true; - - BeginHook(); - HookFuncs( - std::make_pair(&(void*&)_XEventsQueued, (void*)&X11_Hook::MyXEventsQueued) - ); - - EndHook(); - break; - } - dlclose(_library); - } - } - } - } - return res; -} - -void X11_Hook::resetRenderState() -{ - if (initialized) - { - initialized = false; - ImGui_ImplX11_Shutdown(); - } -} - -void X11_Hook::prepareForOverlay(Display *display) -{ - if (!initialized) - { - ImGui_ImplX11_Init(display); - - ImGuiIO &io = ImGui::GetIO(); - io.KeyMap[ImGuiKey_Tab] = _XKeysymToKeycode(display, XK_Tab); - io.KeyMap[ImGuiKey_LeftArrow] = _XKeysymToKeycode(display, XK_Left); - io.KeyMap[ImGuiKey_RightArrow] = _XKeysymToKeycode(display, XK_Right); - io.KeyMap[ImGuiKey_UpArrow] = _XKeysymToKeycode(display, XK_Up); - io.KeyMap[ImGuiKey_DownArrow] = _XKeysymToKeycode(display, XK_Down); - io.KeyMap[ImGuiKey_PageUp] = _XKeysymToKeycode(display, XK_Prior); - io.KeyMap[ImGuiKey_PageDown] = _XKeysymToKeycode(display, XK_Next); - io.KeyMap[ImGuiKey_Home] = _XKeysymToKeycode(display, XK_Home); - io.KeyMap[ImGuiKey_End] = _XKeysymToKeycode(display, XK_End); - io.KeyMap[ImGuiKey_Insert] = _XKeysymToKeycode(display, XK_Insert); - io.KeyMap[ImGuiKey_Delete] = _XKeysymToKeycode(display, XK_Delete); - io.KeyMap[ImGuiKey_Backspace] = _XKeysymToKeycode(display, XK_BackSpace); - io.KeyMap[ImGuiKey_Space] = _XKeysymToKeycode(display, XK_space); - io.KeyMap[ImGuiKey_Enter] = _XKeysymToKeycode(display, XK_Return); - io.KeyMap[ImGuiKey_Escape] = _XKeysymToKeycode(display, XK_Escape); - io.KeyMap[ImGuiKey_A] = _XKeysymToKeycode(display, XK_A); - io.KeyMap[ImGuiKey_C] = _XKeysymToKeycode(display, XK_C); - io.KeyMap[ImGuiKey_V] = _XKeysymToKeycode(display, XK_V); - io.KeyMap[ImGuiKey_X] = _XKeysymToKeycode(display, XK_X); - io.KeyMap[ImGuiKey_Y] = _XKeysymToKeycode(display, XK_Y); - io.KeyMap[ImGuiKey_Z] = _XKeysymToKeycode(display, XK_Z); - - initialized = true; - } - - ImGui_ImplX11_NewFrame(); -} - -///////////////////////////////////////////////////////////////////////////////////// -// X11 window hooks -bool IgnoreEvent(XEvent &event) -{ - switch(event.type) - { - // Keyboard - case KeyPress: case KeyRelease: - // MouseButton - case ButtonPress: case ButtonRelease: - // Mouse move - case MotionNotify: - return true; - } - return false; -} - -int X11_Hook::MyXEventsQueued(Display *display, int mode) -{ - static Time prev_time = {}; - X11_Hook* inst = X11_Hook::Inst(); - XEvent event = {}; - - int res = inst->_XEventsQueued(display, mode); - - if( res > 0 ) - { - /// The XPeekEvent function returns the first event from the event queue, - /// but it does not remove the event from the queue. If the queue is - /// empty, XPeekEvent flushes the output buffer and blocks until an event - /// is received. - inst->_XPeekEvent(display, &event); - Steam_Overlay* overlay = get_steam_client()->steam_overlay; - bool show = overlay->ShowOverlay(); - // Is the event is a key press - if (event.type == KeyPress) - { - // Tab is pressed and was not pressed before - if (event.xkey.keycode == inst->_XKeysymToKeycode(display, XK_Tab) && event.xkey.state & ShiftMask) - { - // if key TAB is help, don't make the overlay flicker :p - if( event.xkey.time != prev_time) - { - overlay->ShowOverlay(!overlay->ShowOverlay()); - - if (overlay->ShowOverlay()) - show = true; - } - } - } - else if(event.type == KeyRelease && event.xkey.keycode == inst->_XKeysymToKeycode(display, XK_Tab)) - { - prev_time = event.xkey.time; - } - - if (show) - { - ImGui_ImplX11_EventHandler(event); - - if (IgnoreEvent(event)) - { - inst->_XNextEvent(display, &event); - res = 0; - } - } - } - // XEventsQueued returns the num of events available. - // Usually, games tend to read all events queued before calling again XEventsQueued - // making us unavailable to intercept undesired events - return res; -} - -///////////////////////////////////////////////////////////////////////////////////// - -X11_Hook::X11_Hook() : - initialized(false), - hooked(false) -{ - //_library = dlopen(DLL_NAME, RTLD_NOW); -} - -X11_Hook::~X11_Hook() -{ - PRINT_DEBUG("X11 Hook removed\n"); - - resetRenderState(); - - //dlclose(_library); - - _inst = nullptr; -} - -X11_Hook* X11_Hook::Inst() -{ - if (_inst == nullptr) - _inst = new X11_Hook; - - return _inst; -} - -const char* X11_Hook::get_lib_name() const -{ - return DLL_NAME; -} - -#endif//NO_OVERLAY diff --git a/overlay_experimental/X11_Hook.h b/overlay_experimental/X11_Hook.h deleted file mode 100644 index 5c6228d..0000000 --- a/overlay_experimental/X11_Hook.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef __INCLUDED_X11_HOOK_H__ -#define __INCLUDED_X11_HOOK_H__ - -#include "Base_Hook.h" - -#ifdef __LINUX__ -#ifndef NO_OVERLAY - -#include // XEvent types -#include // XEvent structure - -class X11_Hook : public Base_Hook -{ -public: - static constexpr const char* DLL_NAME = "libX11.so"; - -private: - static X11_Hook* _inst; - - // Variables - bool hooked; - bool initialized; - - // Functions - X11_Hook(); - - // Hook to X11 window messages - static int MyXEventsQueued(Display * display, int mode); - - decltype(XEventsQueued)* _XEventsQueued; - - decltype(XPeekEvent)* _XPeekEvent; - decltype(XNextEvent)* _XNextEvent; - decltype(XKeysymToKeycode)* _XKeysymToKeycode; - decltype(XLookupKeysym)* _XLookupKeysym; - -public: - virtual ~X11_Hook(); - - void resetRenderState(); - void prepareForOverlay(Display *display); - - bool start_hook(); - static X11_Hook* Inst(); - virtual const char* get_lib_name() const; -}; - -#endif//NO_OVERLAY -#endif//__LINUX__ -#endif//__INCLUDED_X11_HOOK_H__ diff --git a/overlay_experimental/steam_overlay.cpp b/overlay_experimental/steam_overlay.cpp index 3b414ef..49cfe9b 100644 --- a/overlay_experimental/steam_overlay.cpp +++ b/overlay_experimental/steam_overlay.cpp @@ -11,10 +11,10 @@ #include "../dll/dll.h" #include "Renderer_Detector.h" -#include "Windows_Hook.h" -// Look here for info on how to hook on linux -// https://github.com/AimTuxOfficial/AimTux/ +#ifdef __WINDOWS__ +#include "windows/Windows_Hook.h" +#endif #include "notification.h" @@ -123,7 +123,7 @@ void Steam_Overlay::ShowOverlay(bool state) if (!Ready() || show_overlay == state) return; -#ifdef STEAM_WIN32 +#ifdef __WINDOWS__ static RECT old_clip; static BOOL show_cursor = FALSE; @@ -317,7 +317,7 @@ void Steam_Overlay::BuildFriendWindow(Friend const& frd, friend_window_state& st { if (state.window_state & window_state_need_attention && ImGui::IsWindowFocused()) { -#ifdef STEAM_WIN32 +#ifdef __WINDOWS__ PlaySound((LPCSTR)notif_invite_wav, NULL, SND_ASYNC | SND_MEMORY); #endif state.window_state &= ~window_state_need_attention; diff --git a/overlay_experimental/DX10_Hook.cpp b/overlay_experimental/windows/DX10_Hook.cpp similarity index 100% rename from overlay_experimental/DX10_Hook.cpp rename to overlay_experimental/windows/DX10_Hook.cpp diff --git a/overlay_experimental/DX10_Hook.h b/overlay_experimental/windows/DX10_Hook.h similarity index 100% rename from overlay_experimental/DX10_Hook.h rename to overlay_experimental/windows/DX10_Hook.h diff --git a/overlay_experimental/DX11_Hook.cpp b/overlay_experimental/windows/DX11_Hook.cpp similarity index 100% rename from overlay_experimental/DX11_Hook.cpp rename to overlay_experimental/windows/DX11_Hook.cpp diff --git a/overlay_experimental/DX11_Hook.h b/overlay_experimental/windows/DX11_Hook.h similarity index 100% rename from overlay_experimental/DX11_Hook.h rename to overlay_experimental/windows/DX11_Hook.h diff --git a/overlay_experimental/DX12_Hook.cpp b/overlay_experimental/windows/DX12_Hook.cpp similarity index 100% rename from overlay_experimental/DX12_Hook.cpp rename to overlay_experimental/windows/DX12_Hook.cpp diff --git a/overlay_experimental/DX12_Hook.h b/overlay_experimental/windows/DX12_Hook.h similarity index 100% rename from overlay_experimental/DX12_Hook.h rename to overlay_experimental/windows/DX12_Hook.h diff --git a/overlay_experimental/DX9_Hook.cpp b/overlay_experimental/windows/DX9_Hook.cpp similarity index 100% rename from overlay_experimental/DX9_Hook.cpp rename to overlay_experimental/windows/DX9_Hook.cpp diff --git a/overlay_experimental/DX9_Hook.h b/overlay_experimental/windows/DX9_Hook.h similarity index 100% rename from overlay_experimental/DX9_Hook.h rename to overlay_experimental/windows/DX9_Hook.h diff --git a/overlay_experimental/DirectX_VTables.h b/overlay_experimental/windows/DirectX_VTables.h similarity index 100% rename from overlay_experimental/DirectX_VTables.h rename to overlay_experimental/windows/DirectX_VTables.h diff --git a/overlay_experimental/ImGui_ShaderBlobs.cpp b/overlay_experimental/windows/ImGui_ShaderBlobs.cpp similarity index 100% rename from overlay_experimental/ImGui_ShaderBlobs.cpp rename to overlay_experimental/windows/ImGui_ShaderBlobs.cpp diff --git a/overlay_experimental/ImGui_ShaderBlobs.h b/overlay_experimental/windows/ImGui_ShaderBlobs.h similarity index 100% rename from overlay_experimental/ImGui_ShaderBlobs.h rename to overlay_experimental/windows/ImGui_ShaderBlobs.h diff --git a/overlay_experimental/OpenGL_Hook.cpp b/overlay_experimental/windows/OpenGL_Hook.cpp similarity index 100% rename from overlay_experimental/OpenGL_Hook.cpp rename to overlay_experimental/windows/OpenGL_Hook.cpp diff --git a/overlay_experimental/OpenGL_Hook.h b/overlay_experimental/windows/OpenGL_Hook.h similarity index 100% rename from overlay_experimental/OpenGL_Hook.h rename to overlay_experimental/windows/OpenGL_Hook.h diff --git a/overlay_experimental/Windows_Hook.cpp b/overlay_experimental/windows/Windows_Hook.cpp similarity index 100% rename from overlay_experimental/Windows_Hook.cpp rename to overlay_experimental/windows/Windows_Hook.cpp diff --git a/overlay_experimental/Windows_Hook.h b/overlay_experimental/windows/Windows_Hook.h similarity index 97% rename from overlay_experimental/Windows_Hook.h rename to overlay_experimental/windows/Windows_Hook.h index 5fd6d47..a05a339 100644 --- a/overlay_experimental/Windows_Hook.h +++ b/overlay_experimental/windows/Windows_Hook.h @@ -1,7 +1,7 @@ #ifndef __INCLUDED_WINDOWS_HOOK_H__ #define __INCLUDED_WINDOWS_HOOK_H__ -#include "Base_Hook.h" +#include "../Base_Hook.h" #ifdef __WINDOWS__ #ifndef NO_OVERLAY