From 52454e23ea7af3256f6c4b362b8ce0fd59fd6caf Mon Sep 17 00:00:00 2001 From: kedou Date: Fri, 7 Aug 2026 20:42:19 +0800 Subject: [PATCH] fix: update offsets from dump --- CFramework/Cheat/Aim.cpp | 6 +- CFramework/Cheat/Framework.h | 3 + CFramework/Cheat/Menu.cpp | 8 +- CFramework/Cheat/SDK/CPlayer/CPlayer.cpp | 145 +++++++++++++++-------- CFramework/Cheat/SDK/CPlayer/CPlayer.h | 2 +- CFramework/Cheat/SDK/GameSDK/GameSDK.cpp | 48 +++++++- CFramework/Cheat/SDK/GameSDK/Offset.h | 145 ++++++++++++----------- CFramework/Cheat/UpdateList.cpp | 3 +- CFramework/Framework/Config/Config.h | 10 +- CFramework/Framework/Memory/Memory.cpp | 40 ++++--- CFramework/Framework/Memory/Memory.h | 28 ++++- 11 files changed, 278 insertions(+), 160 deletions(-) diff --git a/CFramework/Cheat/Aim.cpp b/CFramework/Cheat/Aim.cpp index dc8d23f..c985038 100644 --- a/CFramework/Cheat/Aim.cpp +++ b/CFramework/Cheat/Aim.cpp @@ -365,8 +365,8 @@ void CFramework::ScanRotationOffset() s_cands.clear(); m_scanResult[0] = 0; - // Player 構造 [0x100, 0x700] 内の 8byte アライン済みポインタ - for (uintptr_t mcOff = 0x100; mcOff <= 0x700; mcOff += 0x8) + // Player 构造 [0x20, 0x700] 内的 8byte アライン済みポインタ + for (uintptr_t mcOff = 0x20; mcOff <= 0x700; mcOff += 0x8) { uintptr_t ptr = m.Read(local.m_address + mcOff); if (!ptr) @@ -392,7 +392,7 @@ void CFramework::ScanRotationOffset() if (s_cands.empty()) { - strcpy_s(m_scanResult, "未找到候选,请扩大扫描范围 (0x100-0x700)"); + strcpy_s(m_scanResult, "未找到候选,请扩大扫描范围 (0x20-0x700)"); m_scanPhase = 0; return; } diff --git a/CFramework/Cheat/Framework.h b/CFramework/Cheat/Framework.h index 948b01b..69b903b 100644 --- a/CFramework/Cheat/Framework.h +++ b/CFramework/Cheat/Framework.h @@ -102,6 +102,9 @@ private: } void HealthBar(float x, float y, float w, float h, int value, int v_max) { + if (v_max <= 0) + return; + RectFilled(x, y, x + w, y + h, ImColor(0.f, 0.f, 0.f, 0.725f), 0.f, 0); RectFilled(x, y, x + w, y + ((h / float(v_max)) * (float)value), ImColor(min(510 * (v_max - value) / 100, 255), min(510 * value / 100, 255), 25, 255), 0.0f, 0); } diff --git a/CFramework/Cheat/Menu.cpp b/CFramework/Cheat/Menu.cpp index 87e5229..de69c62 100644 --- a/CFramework/Cheat/Menu.cpp +++ b/CFramework/Cheat/Menu.cpp @@ -234,11 +234,11 @@ void CFramework::RenderMenu() ImGui::InputInt("MC", &g.g_AimMcOffset, 8, 8, ImGuiInputTextFlags_CharsHexadecimal); ImGui::InputInt("旋转", &g.g_AimRotOffset, 4, 4, ImGuiInputTextFlags_CharsHexadecimal); - // 误改输入框会直接导致 Memory 模式失效, 一键恢复本客户端实测默认值 - if (ImGui::Button("重置偏移 (0x1E0/0x3AC)", ImVec2(ImGui::GetContentRegionAvail().x, 0.f))) + // dump.txt: MovementContext = Player +0x58, Rotation_1 = MovementContext +0x27C + if (ImGui::Button("重置偏移 (0x58/0x27C)", ImVec2(ImGui::GetContentRegionAvail().x, 0.f))) { - g.g_AimMcOffset = 0x1E0; - g.g_AimRotOffset = 0x3AC; + g.g_AimMcOffset = 0x58; + g.g_AimRotOffset = 0x27C; } if (ImGui::Button("扫描旋转偏移(两步)", ImVec2(ImGui::GetContentRegionAvail().x, 0.f))) diff --git a/CFramework/Cheat/SDK/CPlayer/CPlayer.cpp b/CFramework/Cheat/SDK/CPlayer/CPlayer.cpp index 3c8fe9c..4506246 100644 --- a/CFramework/Cheat/SDK/CPlayer/CPlayer.cpp +++ b/CFramework/Cheat/SDK/CPlayer/CPlayer.cpp @@ -4,83 +4,130 @@ std::vector PlayerBoneList{ BONE_PELVIS, BONE_LEFT_THIGH, BONE_LEFT_FOOT, B bool CPlayer::Update() { - // Position - m_vecOrigin = GetBonePosition(BONE_ORIGIN); + m_vecOrigin = GetBonePosition(BONE_ORIGIN); - if (Vec3_Empty(m_vecOrigin)) - return false; - - return true; + return !Vec3_Empty(m_vecOrigin); } void CPlayer::UpdateStatic() { - // Health - uintptr_t m_pHealthController = m.Read(m_address + offset::Player::pHealthController); // HealthController - uintptr_t m_pHealthBody = m.Read(m_pHealthController + 0x68); - m_pBodyController = m.Read(m_pHealthBody + 0x18); + m_pHealthController = 0; + m_pProfile = 0; + m_pInfo = 0; + m_pSetting = 0; + m_pWeaponAnimation = 0; + m_iSpawnType = 0; + m_pBoneArray = {}; + m_vecBoneList.clear(); - // Bone - uintptr_t boneMatrix = m.ReadChain(m_address, { offset::Player::pPlayerBody, 0x30, 0x30, 0x10 }); - m_pBoneArray = m.Read(boneMatrix + 0x20); + if (!m_address) + return; - // Other pointer - m_pProfile = m.Read(m_address + offset::Player::pProfile); - m_pInfo = m.Read(m_pProfile + 0x40); - m_pSetting = m.Read(m_pInfo + 0x50); + // EFT.Player fields from dump.txt. + m_pHealthController = m.Read(m_address + offset::Player::pHealthController); + m_pWeaponAnimation = m.Read(m_address + offset::Player::pWeaponAnimation); - m.Read(m_address + offset::Player::pWeaponAnimation); + m_pProfile = m.Read(m_address + offset::Player::pProfile); + if (m_pProfile) + { + m_pInfo = m.Read(m_pProfile + offset::Profile::pInfoClass); + if (m_pInfo) + { + m_pSetting = m.Read(m_pInfo + offset::InfoClass::profileInfoSettingsClass); + if (m_pSetting) + m_iSpawnType = m.Read(m_pSetting + 0x10); // ProfileInfoSettingsClass.Role + } + } - // Player data - m_iSpawnType = m.Read(m_pSetting + 0x10); // SpawnType + // PlayerBody +0x30 = SkeletonRootJoint; Skeleton +0x30 = values List; + // List +0x10 = Transform[] data pointer, as described by dump.txt. + const uintptr_t boneMatrix = m.ReadChain(m_address, { offset::Player::pPlayerBody, 0x30, 0x30, 0x10 }); + if (boneMatrix) + m_pBoneArray = m.Read(boneMatrix + 0x20); } void CPlayer::UpdateHealth() { - float h{ 0 }; - float max{ 0 }; + m_fHealth = 0.f; + m_fHealthMax = 0.f; - for (int j = 0; j < 7; j++) - { - uintptr_t body_part = m.Read(m_pBodyController + 0x30 + (j * 0x18)); - uintptr_t health_container = m.Read(body_part + 0x10); - h += m.Read(health_container + 0x10); - max += m.Read(health_container + 0x14); - } + if (!m_address) + return; - m_fHealth = h; - m_fHealthMax = max; + const uintptr_t healthController = m_pHealthController != 0 + ? m_pHealthController + : m.Read(m_address + offset::Player::pHealthController); + if (!healthController) + return; + + // GClass3009.Dictionary_0_1 contains BodyPartState entries. + const uintptr_t bodyParts = m.Read(healthController + offset::HealthController::BodyParts); + if (!bodyParts) + return; + + const uintptr_t entries = m.Read(bodyParts + offset::HealthController::DictionaryEntries); + const int entryCount = m.Read(bodyParts + offset::HealthController::DictionaryCount); + if (!entries || entryCount <= 0 || entryCount > 64) + return; + + for (int i = 0; i < entryCount; ++i) + { + const uintptr_t entry = entries + offset::HealthController::ArrayData + + static_cast(i) * offset::HealthController::EntryStride; + const uintptr_t bodyPartState = m.Read(entry + offset::HealthController::EntryValue); + if (!bodyPartState) + continue; + + const uintptr_t healthValue = m.Read(bodyPartState + offset::HealthController::BodyPartHealth); + if (!healthValue) + continue; + + m_fHealth += m.Read(healthValue + offset::HealthController::HealthValue + offset::HealthController::Current); + m_fHealthMax += m.Read(healthValue + offset::HealthController::HealthValue + offset::HealthController::Maximum); + } } void CPlayer::UpdateBone() { - m_vecHeadOrigin = GetBonePosition(BONE_HEAD); - m_vecNeckOrigin = GetBonePosition(BONE_NECK); + m_vecHeadOrigin = GetBonePosition(BONE_HEAD); + m_vecNeckOrigin = GetBonePosition(BONE_NECK); + m_vecBoneList.clear(); - if (g.g_ESP_Skeleton) - { - for (auto& id : PlayerBoneList) - { - Vector3 bone = GetBonePosition(id); + if (!g.g_ESP_Skeleton) + return; - if (Vec3_Empty(bone)) { - m_vecBoneList.clear(); - break; - } + m_vecBoneList.reserve(PlayerBoneList.size()); + for (const auto id : PlayerBoneList) + { + const Vector3 bone = GetBonePosition(id); + if (Vec3_Empty(bone)) + { + m_vecBoneList.clear(); + return; + } - m_vecBoneList.push_back(bone); - } - } + m_vecBoneList.push_back(bone); + } } bool CPlayer::IsAiming() { - return m.Read(m_pWeaponAnimation + offset::WeaponAnimations::isAiming); + return m_pWeaponAnimation != 0 && m.Read(m_pWeaponAnimation + offset::WeaponAnimations::isAiming); } Vector3 CPlayer::GetBonePosition(const int BoneId) { - uintptr_t TransformPtr = m.Read(m_pBoneArray.address[BoneId] + 0x10); + constexpr int kBoneCount = static_cast(sizeof(m_pBoneArray.address) / sizeof(m_pBoneArray.address[0])); + if (BoneId < 0 || BoneId >= kBoneCount) + return {}; - return GetTransformPosition(TransformPtr); -} \ No newline at end of file + const uintptr_t bone = m_pBoneArray.address[BoneId]; + if (!bone) + return {}; + + uintptr_t transform = m.Read(bone + 0x10); + if (!transform) + return {}; + + return GetTransformPosition(transform); +} diff --git a/CFramework/Cheat/SDK/CPlayer/CPlayer.h b/CFramework/Cheat/SDK/CPlayer/CPlayer.h index f0bc349..a60eaff 100644 --- a/CFramework/Cheat/SDK/CPlayer/CPlayer.h +++ b/CFramework/Cheat/SDK/CPlayer/CPlayer.h @@ -13,7 +13,7 @@ public: uintptr_t m_pProfile{ 0 }; uintptr_t m_pInfo{ 0 }; uintptr_t m_pSetting{ 0 }; - uintptr_t m_pBodyController{ 0 }; + uintptr_t m_pHealthController{ 0 }; uintptr_t m_pWeaponAnimation{ 0 }; // データ diff --git a/CFramework/Cheat/SDK/GameSDK/GameSDK.cpp b/CFramework/Cheat/SDK/GameSDK/GameSDK.cpp index 54130c4..2f54d4a 100644 --- a/CFramework/Cheat/SDK/GameSDK/GameSDK.cpp +++ b/CFramework/Cheat/SDK/GameSDK/GameSDK.cpp @@ -21,6 +21,9 @@ float GetDistance(Vector3 value1, Vector3 value2) Vector3 GetTransformPosition(uintptr_t& transform) { + if (!transform) + return {}; + __m128 result{}; const __m128 mulVec0 = { -2.000, 2.000, -2.000, 0.000 }; @@ -29,6 +32,9 @@ Vector3 GetTransformPosition(uintptr_t& transform) TransformAccessReadOnly pTransformAccessReadOnly = m.Read(transform + 0x38); unsigned int Index = m.Read(transform + 0x40); + if (!pTransformAccessReadOnly.pTransformData) + return {}; + TransformData transform_data = m.Read(pTransformAccessReadOnly.pTransformData + 0x18); if (transform_data.pTransformArray && transform_data.pTransformIndices) @@ -96,6 +102,9 @@ bool WorldToScreen(Matrix ViewMatrix, const Vector2& GameSize, Vector3& vIn, Vec uintptr_t GetObjectFromList(uintptr_t listPtr, uintptr_t lastObjectPtr, const char* objectName) { + if (!listPtr || !objectName) + return 0; + char ObjectName[128]{}; uintptr_t classNamePtr = 0; BaseObject activeObject = m.Read(listPtr); @@ -111,7 +120,8 @@ uintptr_t GetObjectFromList(uintptr_t listPtr, uintptr_t lastObjectPtr, const ch if (strcmp(ObjectName, objectName) == 0) return activeObject.object; - Sleep(1); + if (!activeObject.nextObjectLink) + break; activeObject = m.Read(activeObject.nextObjectLink); } @@ -135,13 +145,22 @@ bool CGame::InitAddress() { // GameObjectManager uintptr_t pGOM = m.Read(m.m_gBaseAddress + offset::dwGameObjectManager); + if (!pGOM) + { + m_objGameObjectManager = {}; + return false; + } + m_objGameObjectManager = m.Read(pGOM); - return m_objGameObjectManager.lastActiveObject != NULL ? true : false; + return m_objGameObjectManager.lastActiveObject != 0; } bool CGame::Update() { + m_pGameWorld = 0; + m_pLocalGameWorld = 0; + // GameWorld uintptr_t activeNodes = m.Read(m_objGameObjectManager.ActiveNodes); uintptr_t lastActiveNode = m.Read(m_objGameObjectManager.LastActiveNode); @@ -161,21 +180,30 @@ bool CGame::Update() bool CGame::UpdateCamera() { - Camera all_cameras = m.Read(m.Read(m.m_gBaseAddress + offset::dwAllCamera)); + m_pFpsCamera = 0; - if (all_cameras.count == 0) + uintptr_t all_camera_ptr = m.Read(m.m_gBaseAddress + offset::dwAllCamera); + if (!all_camera_ptr) + return false; + + Camera all_cameras = m.Read(all_camera_ptr); + + if (all_cameras.list == 0 || all_cameras.count == 0) return false; for (int i = 0; i < all_cameras.count; i++) { uintptr_t camera = m.Read(all_cameras.list + (i * 0x8)); - if (camera != NULL) + if (camera != 0) { uintptr_t camera_obj = m.Read(camera + 0x30); + if (!camera_obj) + continue; + uintptr_t camera_name_ptr = m.Read(camera_obj + 0x60); if (!camera_name_ptr) - return false; + continue; char name[64]{}; m.ReadString(camera_name_ptr, name, sizeof(name)); @@ -197,9 +225,17 @@ bool CGame::IsInRaid() Matrix CGame::GetViewMatrix() { + if (!m_pFpsCamera) + return {}; + // ‚±‚±�ȗª‚ł«‚邩ƒ`ƒFƒbƒN uintptr_t dw = m.Read(m_pFpsCamera + 0x30); + if (!dw) + return {}; + uintptr_t viewmatrix_ptr = m.Read(dw + 0x18); + if (!viewmatrix_ptr) + return {}; return m.Read(viewmatrix_ptr + 0x100); } \ No newline at end of file diff --git a/CFramework/Cheat/SDK/GameSDK/Offset.h b/CFramework/Cheat/SDK/GameSDK/Offset.h index af26291..5d8c959 100644 --- a/CFramework/Cheat/SDK/GameSDK/Offset.h +++ b/CFramework/Cheat/SDK/GameSDK/Offset.h @@ -1,81 +1,88 @@ -#pragma once +#pragma once // by Unispect and UC namespace offset { - // Base - constexpr auto dwGameObjectManager = 0x1CF93E0; - constexpr auto dwAllCamera = 0x1BF8BC0; + // Base (not present in dump.txt; keep the native UnityPlayer values used by this build) + constexpr auto dwGameObjectManager = 0x1CF93E0; + constexpr auto dwAllCamera = 0x1BF8BC0; - // EFT.GameWorld - constexpr auto ExfilController = 0x30; - constexpr auto LootList = 0x118; - constexpr auto RegisteredPlayers = 0x140; - constexpr auto MainPlayer = 0x1A8; - constexpr auto GrenadeList = 0x200; + // EFT.GameWorld / EFT.ClientLocalGameWorld + constexpr auto ExfilController = 0x30; + constexpr auto LootList = 0x118; + constexpr auto RegisteredPlayers = 0x140; + constexpr auto MainPlayer = 0x1A8; + constexpr auto GrenadeList = 0x200; - // EFT.Player - namespace Player - { - constexpr auto pPlayerBody = 0xC0; - constexpr auto pMovementContext = 0x1E0; // EXFIL DELTA (Mono 0.16.9) 实测. IL2CPP 0.15.x 是 0x170 - constexpr auto pWeaponAnimation = 0x1E0; // IL2CPP 版定义, Mono 版实际是 MovementContext (框架旧代码保留) - constexpr auto pProfile = 0x600; - constexpr auto pPhysics = 0x610; - constexpr auto pHealthController = 0x640; - } + // EFT.Player (dump.txt: EFT.Player) + namespace Player + { + constexpr auto pPlayerBody = 0xC0; // _playerBody + constexpr auto pMovementContext = 0x58; // k__BackingField + constexpr auto pWeaponAnimation = 0x1E0; // k__BackingField + constexpr auto pProfile = 0x618; // k__BackingField + constexpr auto pPhysics = 0x630; // Physical + constexpr auto pHealthController = 0x660; // _healthController + } - // EFT.MovementContext - namespace MovementContext - { - // Vector2 (x = yaw, y = pitch) [rad] - // EXFIL DELTA (Mono 0.16.9) 实测: +0x3AC = Rotation_1 (视角旋转) - // +0x3A4 = MovementDirection_1 (移动方向, 勿用!) 依据 Mono.Cecil 字段表 - constexpr auto Rotation = 0x3AC; - } + // EFT.MovementContext (dump.txt: EFT.MovementContext) + namespace MovementContext + { + // Vector2 (x = yaw, y = pitch), in radians. + constexpr auto Rotation = 0x27C; // Rotation_1 + } - // EFT.Profile - namespace Profile - { - constexpr auto Id = 0x10; // str - constexpr auto AccountId = 0x18; // str - constexpr auto pInfoClass = 0x40; // pointer - } + // EFT.Profile + namespace Profile + { + constexpr auto Id = 0x10; + constexpr auto AccountId = 0x18; + constexpr auto pInfoClass = 0x40; // Info + } - // EFT.Profile->InfoClass - namespace InfoClass - { - constexpr auto Nickname = 0x10; // str - constexpr auto EntryPoint = 0x18; // str - constexpr auto MainProfileNickname = 0x20; // str - constexpr auto MGroupId = 0x28; // str - constexpr auto TeamId = 0x30; // str - constexpr auto profileInfoSettingsClass = 0x50; // pointer - constexpr auto eplayerSide_0 = 0x90; // int - constexpr auto RegistrationDate = 0x94; // int - constexpr auto Type = 0x98; // int - } + // EFT.Profile -> InfoClass + namespace InfoClass + { + constexpr auto Nickname = 0x10; + constexpr auto EntryPoint = 0x18; + constexpr auto MainProfileNickname = 0x20; + constexpr auto MGroupId = 0x28; + constexpr auto TeamId = 0x30; + constexpr auto profileInfoSettingsClass = 0x48; // ProfileInfoSettingsClass + constexpr auto eplayerSide_0 = 0x88; + constexpr auto RegistrationDate = 0x8C; + constexpr auto Type = 0x90; + } - // EFT.Player->.BasePhysicalClass - namespace Physics - { + // EFT.HealthSystem.ActiveHealthController / GClass3009 + namespace HealthController + { + constexpr auto BodyParts = 0x68; // Dictionary> + constexpr auto DictionaryEntries = 0x18; + constexpr auto DictionaryCount = 0x40; + constexpr auto ArrayData = 0x20; + constexpr auto EntryStride = 0x18; + constexpr auto EntryValue = 0x10; + constexpr auto BodyPartHealth = 0x10; // BodyPartState.Health + constexpr auto HealthValue = 0x10; // HealthValue.Value + constexpr auto Current = 0x00; + constexpr auto Maximum = 0x04; + } - } + // EFT.Animations.ProceduralWeaponAnimation + namespace WeaponAnimations + { + constexpr auto Breath = 0x30; + constexpr auto isAiming = 0x1C5; + } - // EFT.Animations.ProceduralWeaponAnimation - namespace WeaponAnimations - { - constexpr auto Breath = 0x30; - constexpr auto isAiming = 0x1C5; - } - - // .BasePhysicalClass - namespace Physics - { - constexpr auto Stamina = 0x38; - constexpr auto HandsStamina = 0x40; - constexpr auto Oxygen = 0x40; - constexpr auto FallDamageMultiplier = 0xBC; - constexpr auto OxygenRestoreRate = 0xD4; - } -} \ No newline at end of file + // .BasePhysicalClass + namespace Physics + { + constexpr auto Stamina = 0x38; + constexpr auto HandsStamina = 0x40; + constexpr auto Oxygen = 0x48; + constexpr auto FallDamageMultiplier = 0xBC; + constexpr auto OxygenRestoreRate = 0xD4; + } +} diff --git a/CFramework/Cheat/UpdateList.cpp b/CFramework/Cheat/UpdateList.cpp index c4d69ed..ee77edd 100644 --- a/CFramework/Cheat/UpdateList.cpp +++ b/CFramework/Cheat/UpdateList.cpp @@ -91,12 +91,13 @@ void CFramework::UpdateStaticList() // C6262 :( std::vector list_item{}; std::vector list_exfil{}; - const auto GameWorld = tarkov->m_pLocalGameWorld; tarkov->UpdateCamera(); // ItemList if (tarkov->Update()) { + const auto GameWorld = tarkov->m_pLocalGameWorld; + // Exfil if (g.g_ESP_Exfil) { diff --git a/CFramework/Framework/Config/Config.h b/CFramework/Framework/Config/Config.h index 07cb558..af6762c 100644 --- a/CFramework/Framework/Config/Config.h +++ b/CFramework/Framework/Config/Config.h @@ -53,13 +53,11 @@ struct Globals float g_RecoilStrength = 4.f; // 每次下拉的鼠标单位(mickeys) int g_RecoilInterval = 15; // 下拉间隔 [ms] - // Aim Offset (运行时可调, 默认 = 本客户端实测值) + // Aim Offset (运行时可调, 由 F:\desktop\Release\dump.txt 校准) // Memory 模式自瞄用: Player + g_AimMcOffset -> + g_AimRotOffset (Vector2 yaw/pitch) - // EXFIL DELTA (Mono 0.16.9) 实测: Player+0x1E0 = MovementContext - // +0x3A4 = MovementDirection(移动方向, 非视角!), +0x3AC = Rotation_1(视角旋转, 正解) - // 依据: Mono.Cecil 字段表 + 运行时验证 (0x3A4 读出的俯仰恒 0) - int g_AimMcOffset = 0x1E0; - int g_AimRotOffset = 0x3AC; + // EFT.Player: MovementContext = +0x58; EFT.MovementContext: Rotation_1 = +0x27C + int g_AimMcOffset = 0x58; + int g_AimRotOffset = 0x27C; // System bool g_StreamProof = false; diff --git a/CFramework/Framework/Memory/Memory.cpp b/CFramework/Framework/Memory/Memory.cpp index 13881d6..de888f2 100644 --- a/CFramework/Framework/Memory/Memory.cpp +++ b/CFramework/Framework/Memory/Memory.cpp @@ -58,19 +58,24 @@ uintptr_t Memory::GetModuleBase(const std::string moduleName) entry.dwSize = sizeof(MODULEENTRY32); const auto snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, PID); - while (Module32Next(snapShot, &entry)) + if (snapShot == INVALID_HANDLE_VALUE) + return 0; + + if (Module32First(snapShot, &entry)) { - if (!moduleName.compare(entry.szModule)) + do { - CloseHandle(snapShot); - return reinterpret_cast(entry.modBaseAddr); - } + if (!moduleName.compare(entry.szModule)) + { + const auto base = reinterpret_cast(entry.modBaseAddr); + CloseHandle(snapShot); + return base; + } + } while (Module32Next(snapShot, &entry)); } - if (snapShot) - CloseHandle(snapShot); - - return reinterpret_cast(entry.modBaseAddr); + CloseHandle(snapShot); + return 0; } PROCESSENTRY32 Memory::GetProcess(const std::string processName) @@ -79,17 +84,22 @@ PROCESSENTRY32 Memory::GetProcess(const std::string processName) entry.dwSize = sizeof(PROCESSENTRY32); const auto snapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); - while (Process32Next(snapShot, &entry)) + if (snapShot == INVALID_HANDLE_VALUE) + return PROCESSENTRY32(); + + if (Process32First(snapShot, &entry)) { - if (!processName.compare(entry.szExeFile)) + do { - CloseHandle(snapShot); - return entry; - } + if (!processName.compare(entry.szExeFile)) + { + CloseHandle(snapShot); + return entry; + } + } while (Process32Next(snapShot, &entry)); } CloseHandle(snapShot); - return PROCESSENTRY32(); } diff --git a/CFramework/Framework/Memory/Memory.h b/CFramework/Framework/Memory/Memory.h index 95a6475..d6b9959 100644 --- a/CFramework/Framework/Memory/Memory.h +++ b/CFramework/Framework/Memory/Memory.h @@ -48,9 +48,17 @@ public: } uintptr_t ReadChain(uintptr_t address, const std::vector& offsets) { - uintptr_t result = Read(address + offsets.at(0)); - for (int i = 1; i < offsets.size(); i++) - result = Read(result + offsets.at(i)); + if (!address || offsets.empty()) + return 0; + + uintptr_t result = Read(address + offsets.front()); + for (std::size_t i = 1; i < offsets.size(); ++i) + { + if (!result) + return 0; + + result = Read(result + offsets[i]); + } return result; } @@ -62,9 +70,17 @@ public: } std::string ReadString(uintptr_t address, int length) { - static char Buffer[256]{}; - ReadProcessMemory(pHandle, (void*)(address), Buffer, length, nullptr); - + if (!address || length <= 0) + return {}; + + char Buffer[256]{}; + if (length >= static_cast(sizeof(Buffer))) + length = static_cast(sizeof(Buffer)) - 1; + + if (!ReadProcessMemory(pHandle, reinterpret_cast(address), Buffer, length, nullptr)) + return {}; + + Buffer[length] = '\0'; return std::string(Buffer); }; wchar_t* ReadWString(uintptr_t address, int length)