Начинающий
-
Автор темы
- #1
Обычно я подключаю createmove idx 21, когда использую Patternscan. Но когда я использую VTABLE, это не работает. Что делает это странным, так это то, что я могу прекрасно подключить createmove к idx 5, используя VTABLE и Patternscan. Так почему же idx 21 не подключается?
CREATEMOVE1 = 5U
CREATEMOVE2 = 21U
CREATEMOVE1 = 5U
CREATEMOVE2 = 21U
C++:
auto pattern = MEM::FindPattern(CLIENT_DLL, "48 8B C4 4C 89 40 18 48 89 48 08 55 53 56 57 48 8D A8 ? ? ? ?");
if (!pattern)
return NULL;
MH_Initialize();
MH_CreateHook((LPVOID)MEM::GetVFunc(I::Input, VTABLE::CLIENT::CREATEMOVE2), (LPVOID)CreateMoveHook, (LPVOID*)&oCreateMove);
MH_EnableHook(MH_ALL_HOOKS);
C++:
/// get pointer to function of virtual-function table
/// @returns: pointer to virtual function
template <typename T = void*>
[[nodiscard]] CS_INLINE T GetVFunc(const void* thisptr, std::size_t nIndex)
{
return (*static_cast<T* const*>(thisptr))[nIndex];
}
/// call virtual function of specified class at given index
/// @note: reference and const reference arguments must be forwarded as pointers or wrapped with 'std::ref'/'std::cref' calls!
/// @returns: result of virtual function call
template <typename T, std::size_t nIndex, class CBaseClass, typename... Args_t>
static CS_INLINE T CallVFunc(CBaseClass* thisptr, Args_t... argList)
{
using VirtualFn_t = T(__thiscall*)(const void*, decltype(argList)...);
return (*reinterpret_cast<VirtualFn_t* const*>(reinterpret_cast<std::uintptr_t>(thisptr)))[nIndex](thisptr, argList...);
}
C++:
typedef char(__fastcall* oCreateMoveFn)(CCSGOInput*, unsigned int, CUserCmd*);
oCreateMoveFn oCreateMove = nullptr;
// Static variable to keep track of the previous z position
static float previousZ = 0.0f;
char __fastcall CreateMoveHook(CCSGOInput* csInput, unsigned int edx, CUserCmd* cmd)
{
// Output to console to confirm hook is called
std::cout << "hook" << std::endl;
// Get the base address of client.dll
const uintptr_t client = (uintptr_t)(GetModuleHandle(L"client.dll"));
if (!client)
{
printf("Failed to get client.dll base address.\n");
return oCreateMove(csInput, edx, cmd);
}
// Get the pointer to the local player pawn
const uintptr_t pawn = *(uintptr_t*)(client + O::dwLocalPlayerPawn);
if (!pawn)
{
printf("Local player pawn is null.\n");
return oCreateMove(csInput, edx, cmd);
}
// Get the flags value
int32_t flags = *(int32_t*)(pawn + O::m_fFlags);
// Print the flags value
//printf("Flags: %d\n", flags);
Vector_t position = *(Vector_t*)(pawn + O::m_vOldOrigin);
//PrintVector(position);
//// Check if the player is holding crouch
//bool isCrouching = cmd->nButtons.nValue & ECommandButtons::IN_DUCK;
//bool isFalling = position.z < previousZ;
//cmd->csgoUserCmd.pBaseCmd->flForwardMove = 1.0f;
//// Example bunny-hop logic: only jump if the player is on the ground
//if (cmd->nButtons.nValue & IN_JUMP && flags & FL_ONGROUND)
//{
// cmd->nButtons.nValue &= ~IN_JUMP;
// std::cout << cmd->csgoUserCmd.pBaseCmd->nClientTick << std::endl;
//}
//// Check if the player is falling
//if (isCrouching && flags & FL_ONGROUND)
//{
// printf("JumpBug :D");
// //printf("Player is falling! Previous Z: %.2f, Current Z: %.2f\n", previousZ, position.z);
// // Uncrouch
// cmd->nButtons.nValue &= ~IN_DUCK; // Release crouch
//}
//// Update previous Z position for the next tick
//previousZ = position.z;
return oCreateMove(csInput, edx, cmd);
}