diff --git a/src/Smooth Interior Camera/Game/Hooks.cpp b/src/Smooth Interior Camera/Game/Hooks.cpp index 83777e1..8055d90 100644 --- a/src/Smooth Interior Camera/Game/Hooks.cpp +++ b/src/Smooth Interior Camera/Game/Hooks.cpp @@ -26,7 +26,7 @@ namespace Hooks std::uint16_t gameCamOffset = 0; std::uint16_t gameCamPosOffset = 0; - void __cdecl CameraEvent(uintptr_t gameCamAddr) + void __fastcall CameraEvent(uintptr_t gameCamAddr) { auto pGameCam = reinterpret_cast(gameCamAddr + gameCamOffset); auto pGameCamPos = reinterpret_cast(gameCamAddr + gameCamPosOffset); @@ -89,30 +89,46 @@ namespace Hooks uintptr_t CameraEvent_addr; - uint8_t baseBytes[34] = { 0 }; + uint8_t baseBytes[35] = { 0 }; #if defined(X64) - auto CameraEvent_pattern = "8B 81 ?? ?? 00 00 89 81 ?? ?? 00 00 8B 81 ?? ?? 00 00 89 81 ?? ?? 00 00 C7 81 ?? ?? 00 00 00 00 00 00"; + auto CameraEvent_pattern_V1 = "8B 81 ?? ?? 00 00 89 81 ?? ?? 00 00 8B 81 ?? ?? 00 00 89 81 ?? ?? 00 00 C7 81 ?? ?? 00 00 00 00 00 00"; + auto CameraEvent_pattern_V2 = "F3 0F 10 97 ?? ?? 00 00 F3 0F 10 B7 ?? ?? 00 00 83 F8 01 75 ?? F3 0F 11 97 ?? ?? 00 00 F3 0F 11 B7 ?? ?? 00 00 89 9F ?? ?? 00 00 E9 ?? ?? 00 00"; extern "C" { - uintptr_t CameraEvent_Address = 0; + uintptr_t CameraEvent_CallAddress = 0; uintptr_t CameraEvent_RetnAddress = 0; - void Asm_CameraEvent(); + void Asm_CameraEvent_V1(); + void Asm_CameraEvent_V2(); } #elif defined(X86) - auto CameraEvent_pattern = "8B 81 ?? ?? 00 00 89 81 ?? ?? 00 00 8B 81 ?? ?? 00 00 89 81 ?? ?? 00 00 C7 81 ?? ?? 00 00 00 00 00 00 8B"; - uintptr_t CameraEvent_Address = 0; + auto CameraEvent_pattern_V1 = "8B 81 ?? ?? 00 00 89 81 ?? ?? 00 00 8B 81 ?? ?? 00 00 89 81 ?? ?? 00 00 C7 81 ?? ?? 00 00 00 00 00 00 8B"; + auto CameraEvent_pattern_V2 = "F3 0F 10 9F ?? ?? 00 00 F3 0F 10 97 ?? ?? 00 00 83 F8 01 75 ?? F3 0F 11 9F ?? ?? 00 00 F3 0F 11 97 ?? ?? 00 00 E9 ?? ?? 00 00"; + uintptr_t CameraEvent_CallAddress = 0; uintptr_t CameraEvent_RetnAddress = 0; - void __declspec(naked) Asm_CameraEvent() + void __declspec(naked) Asm_CameraEvent_V1() { __asm { pushad - call CameraEvent_Address + call CameraEvent_CallAddress + popad + + jmp CameraEvent_RetnAddress + } + } + + void __declspec(naked) Asm_CameraEvent_V2() + { + __asm + { + pushad + mov ecx, edi + call CameraEvent_CallAddress popad jmp CameraEvent_RetnAddress @@ -120,26 +136,32 @@ namespace Hooks } #endif + // Temporary code. Just quick fix, I will rewrite it later - bool Hook_CameraEvent() + // ETS2: 1.27 - 1.36 ATS: 1.6 - 1.36 + bool Hook_V1() { - auto pattern = hook::pattern(CameraEvent_pattern); +#ifdef TESTING + printf("Trying HOOK V1...\n"); +#endif + + auto pattern = hook::pattern(CameraEvent_pattern_V1); if (pattern.size() > 0) { CameraEvent_addr = reinterpret_cast(pattern.count(1).get(0).get(0)); - #ifdef TESTING +#ifdef TESTING std::cout << "CameraEvent addr: " << std::hex << CameraEvent_addr << "\n"; - #endif +#endif gameCamOffset = *reinterpret_cast(CameraEvent_addr + 2) - 4; gameCamPosOffset = *reinterpret_cast(CameraEvent_addr + 8); - #ifdef TESTING +#ifdef TESTING printf("Offsets: %i %i\n", gameCamOffset, gameCamPosOffset); printf("Number of bytes to backup: %lld\n", sizeof(baseBytes)); - #endif +#endif // backup bytes for (int i = 0; i < sizeof(baseBytes); ++i) @@ -149,38 +171,100 @@ namespace Hooks MemMgr::UnprotectMemory(CameraEvent_addr, sizeof(baseBytes)); - CameraEvent_Address = reinterpret_cast(CameraEvent); - CameraEvent_RetnAddress = CameraEvent_addr + sizeof(baseBytes); - MemMgr::JmpHook(CameraEvent_addr, (uintptr_t)Asm_CameraEvent); + CameraEvent_CallAddress = reinterpret_cast(CameraEvent); + CameraEvent_RetnAddress = CameraEvent_addr + 34; + MemMgr::JmpHook(CameraEvent_addr, (uintptr_t)Asm_CameraEvent_V1); + +#ifdef TESTING + printf("HOOK V1 activated\n"); +#endif return true; } - else + +#ifdef TESTING + printf("HOOK V1 don't work\n"); +#endif + + return false; + } + + // ETS2: 1.37+, ATS 1.37+ + bool Hook_V2() + { +#ifdef TESTING + printf("Trying HOOK V2...\n"); +#endif + + auto pattern = hook::pattern(CameraEvent_pattern_V2); + + if (pattern.size() > 0) { - Mod::Get()->Log(SCS_LOG_TYPE_error, "Data structure is incorrect!"); - #ifdef TESTING - std::cout << "Hook for CameraEvent not found!\n"; - #endif - return false; + uintptr_t data_addr = reinterpret_cast(pattern.count(1).get(0).get(0)); + CameraEvent_addr = data_addr + 21; + +#ifdef TESTING + std::cout << "CameraEvent addr: " << std::hex << CameraEvent_addr << "\n"; +#endif + + gameCamOffset = *reinterpret_cast(data_addr + 4) - 4; + gameCamPosOffset = *reinterpret_cast(CameraEvent_addr + 4); + +#ifdef TESTING + printf("Offsets: %i %i\n", gameCamOffset, gameCamPosOffset); + printf("Number of bytes to backup: %lld\n", sizeof(baseBytes)); +#endif + + // backup bytes + for (int i = 0; i < sizeof(baseBytes); ++i) + { + baseBytes[i] = *reinterpret_cast(CameraEvent_addr + i); + } + + MemMgr::UnprotectMemory(CameraEvent_addr, sizeof(baseBytes)); + + CameraEvent_CallAddress = reinterpret_cast(CameraEvent); + CameraEvent_RetnAddress = CameraEvent_addr + 16; + MemMgr::JmpHook(CameraEvent_addr, (uintptr_t)Asm_CameraEvent_V2); + +#ifdef TESTING + printf("HOOK V2 activated\n"); +#endif + + return true; } + +#ifdef TESTING + printf("HOOK V2 don't work\n"); +#endif + + return false; } + bool Init() { - #ifdef TESTING + g_pMod = Mod::Get(); + +#ifdef TESTING std::cout << "Initializing hooks...\n"; #endif - if (!Hook_CameraEvent()) - return false; - - #ifdef TESTING - std::cout << "Hooks initialized!\n"; - #endif + if (Hook_V1()) + { + return true; + } - g_pMod = Mod::Get(); + if (Hook_V2()) + { + return true; + } - return true; + Mod::Get()->Log(SCS_LOG_TYPE_error, "Data structure is incorrect!"); +#ifdef TESTING + std::cout << "Hook for CameraEvent not found!\n"; +#endif + return false; } void Unhook() diff --git a/src/Smooth Interior Camera/Game/HooksASM.asm b/src/Smooth Interior Camera/Game/HooksASM.asm index 7fd3951..062d754 100644 --- a/src/Smooth Interior Camera/Game/HooksASM.asm +++ b/src/Smooth Interior Camera/Game/HooksASM.asm @@ -5,12 +5,12 @@ IFDEF RAX -extern CameraEvent_Address: qword +extern CameraEvent_CallAddress: qword extern CameraEvent_RetnAddress: qword .code -Asm_CameraEvent PROC +Asm_CameraEvent_V1 PROC ; backup registers push rax @@ -19,7 +19,7 @@ Asm_CameraEvent PROC push r8 ; call library function - call CameraEvent_Address + call CameraEvent_CallAddress ; restore registers pop r8 @@ -29,7 +29,29 @@ Asm_CameraEvent PROC ; jump to End jmp CameraEvent_RetnAddress -Asm_CameraEvent ENDP +Asm_CameraEvent_V1 ENDP + +Asm_CameraEvent_V2 PROC + + ; backup registers + push rax + push rdx + push r8 + + ; call library function + push rcx + mov rcx, rdi + call CameraEvent_CallAddress + pop rcx + + ; restore registers + pop r8 + pop rdx + pop rax + + ; jump to End + jmp CameraEvent_RetnAddress +Asm_CameraEvent_V2 ENDP ENDIF diff --git a/src/Smooth Interior Camera/Resource.rc b/src/Smooth Interior Camera/Resource.rc index aaa9566..74f0c90 100644 Binary files a/src/Smooth Interior Camera/Resource.rc and b/src/Smooth Interior Camera/Resource.rc differ diff --git a/src/Smooth Interior Camera/Version.hpp b/src/Smooth Interior Camera/Version.hpp index 888fe3e..c366a15 100644 --- a/src/Smooth Interior Camera/Version.hpp +++ b/src/Smooth Interior Camera/Version.hpp @@ -1,9 +1,8 @@ #pragma once -#define CURRENT_VERSION "1.3.1.0" -#define CURRENT_VERSION_SHORT 1310 -#define CURRENT_VERSION_NUMBER 1,3,1,0 - +#define CURRENT_VERSION "1.3.2.0" +#define CURRENT_VERSION_SHORT 1320 +#define CURRENT_VERSION_NUMBER 1,3,2,0 #ifdef _WIN64 # define X64