Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос ESP

  • Автор темы Автор темы .bin
  • Дата начала Дата начала
Один кряк вам или два другому
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
16 Сен 2025
Сообщения
160
Реакции
13
Через нейронку написал ESP, не рендерится. Дошли до логов:

Код:
Expand Collapse Copy
[*] CS2 Internal loading...

[+] client.dll: 0x7FFD71F20000

[+] Present hooked

[+] Ready. INSERT = menu, G = ESP, F1 = debug

=== DIAG ===

entList=0x3D8E5284800  lc=0x3D968F50600  lp=0x3D9A7090000

-- controllers (1..64) -> pawn handles --

[C04] ctrl=0x3D8E5F4F4CE team=0 ph=0x7453825C idx=604 ch=1 sl=92 pawn=0x0 hp=-1 life=-1 dorm=-1 org=0,0,0 name=remapper

-- chunk pointers used by pawn handles --

  chunk[1] = 0x0

-- localPawn index search (1..0x7FFF) --

localPawn not found in 1..0x7FFF

=== END DIAG ===

=== DIAG ===

entList=0x3D8E5284800  lc=0x3D968F50600  lp=0x3D9A7090000

-- controllers (1..64) -> pawn handles --

[C04] ctrl=0x3D8E5F4F4CE team=0 ph=0x7453825C idx=604 ch=1 sl=92 pawn=0x0 hp=-1 life=-1 dorm=-1 org=0,0,0 name=remapper

-- chunk pointers used by pawn handles --

  chunk[1] = 0x0

-- localPawn index search (1..0x7FFF) --

localPawn not found in 1..0x7FFF

=== END DIAG ===

Сам код дллки:

Код:
Expand Collapse Copy
#undef UNICODE
#undef _UNICODE

#include <Windows.h>
#include <d3d11.h>
#include <string>
#include <vector>
#include <thread>
#include <mutex>

#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui/imgui.h"
#include "imgui/imgui_impl_win32.h"
#include "imgui/imgui_impl_dx11.h"

#include "framework/headers/includes.h"
#include "framework/gui.cpp"
#include "framework/helpers/config.cpp"
#include "framework/helpers/draw.cpp"
#include "framework/helpers/fonts.cpp"
#include "framework/helpers/popups.cpp"
#include "framework/widgets/helpers.cpp"
#include "framework/widgets/notify.cpp"
#include "framework/widgets/widgets.cpp"
#include "framework/widgets/window.cpp"

#include "memory.hpp"
#include "offsets.hpp"

#pragma comment(lib, "d3d11.lib")

// ---- Types ----
struct Vec3 { float x, y, z; };
struct Vec2 { float x, y; };
struct ViewMatrix { float m[4][4]; };

struct Player {
    Vec3        origin;
    Vec3        head;
    int         health;
    int         team;
    std::string name;
};

// ---- Globals ----
static ID3D11Device*           g_pDevice     = nullptr;
static ID3D11DeviceContext*    g_pCtx        = nullptr;
static ID3D11RenderTargetView* g_pRTV        = nullptr;
static IDXGISwapChain*         g_pSwapChain  = nullptr;
static HWND                    g_hWnd        = nullptr;
static bool                    g_ImGuiReady  = false;
static bool                    g_ShowDebug   = false;
static int                     g_Width       = 1920;
static int                     g_Height      = 1080;

static uintptr_t               g_clientBase  = 0;
static std::vector<Player>     g_players;
static ViewMatrix              g_vm{};
static std::mutex              g_playersMtx;

// ---- Present hook ----
using Present_t = HRESULT(__stdcall*)(IDXGISwapChain*, UINT, UINT);
static Present_t oPresent = nullptr;
static void**    g_pVTable = nullptr;

extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND, UINT, WPARAM, LPARAM);
void RunDiag();
static WNDPROC g_oWndProc = nullptr;

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    if (g_ImGuiReady) {
        if (msg == WM_KEYDOWN && wParam == VK_INSERT) {
            var->gui.opened = !var->gui.opened;
            return true;
        }
        if (msg == WM_KEYDOWN && wParam == 'G') {
            var->esp.enabled = !var->esp.enabled;
            return true;
        }
        if (msg == WM_KEYDOWN && wParam == VK_F1) {
            g_ShowDebug = !g_ShowDebug;
            return true;
        }
        if (msg == WM_KEYDOWN && wParam == VK_F2) {
            std::thread(RunDiag).detach();
            return true;
        }
        if (var->gui.opened && ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
            return true;
    }
    return CallWindowProcA(g_oWndProc, hWnd, msg, wParam, lParam);
}

// ---- World to screen ----
bool W2S(const Vec3& pos, Vec2& out) {
    float w = g_vm.m[3][0]*pos.x + g_vm.m[3][1]*pos.y + g_vm.m[3][2]*pos.z + g_vm.m[3][3];
    if (w < 0.001f) return false;
    float x = g_vm.m[0][0]*pos.x + g_vm.m[0][1]*pos.y + g_vm.m[0][2]*pos.z + g_vm.m[0][3];
    float y = g_vm.m[1][0]*pos.x + g_vm.m[1][1]*pos.y + g_vm.m[1][2]*pos.z + g_vm.m[1][3];
    out.x = (g_Width  * 0.5f) + (g_Width  * 0.5f) * x / w;
    out.y = (g_Height * 0.5f) - (g_Height * 0.5f) * y / w;
    return true;
}

// ---- Read entities ----
static bool IsLikelyPtr(uintptr_t p) {
    return p > 0x10000 && p < 0x7FF000000000ULL;
}

static constexpr int kEntityIndexMask  = 0x7FFF;
static constexpr int kEntityChunkShift = 9;      // 512 entries per chunk
static constexpr int kEntityChunkSize  = 1 << kEntityChunkShift;
static constexpr int kEntityMaxIndex   = kEntityIndexMask;
static constexpr int kMaxControllers   = 64;
static constexpr uintptr_t kEntityStride     = 0x78;

struct EntityTraversalMode {
    const char* name;
    uintptr_t   chunkBaseOffset;
    uintptr_t   slotEntityOffset;
};

static constexpr EntityTraversalMode kEntityModes[] = {
    { "chunk+0x10 slot+0x00", 0x10, 0x00 },
    { "chunk+0x10 slot+0x10", 0x10, 0x10 },
    { "chunk+0x00 slot+0x00", 0x00, 0x00 },
    { "chunk+0x00 slot+0x10", 0x00, 0x10 },
};

static int  g_entityMode = 0;
static bool g_entityModeResolved = false;
static DWORD g_lastEntityModeProbeMs = 0;

static int IndexFromHandle(uint32_t handle) {
    return static_cast<int>(handle & kEntityIndexMask);
}

static int ChunkFromIndex(int index) {
    return (index & kEntityIndexMask) >> kEntityChunkShift;
}

static int SlotFromIndex(int index) {
    return index & (kEntityChunkSize - 1);
}

static uintptr_t GetEntityByIndexMode(uintptr_t entityList, int index, int mode) {
    if (!IsLikelyPtr(entityList)) return 0;
    if (mode < 0 || mode >= (int)(sizeof(kEntityModes) / sizeof(kEntityModes[0])))
        return 0;

    int maskedIndex = index & kEntityIndexMask;
    if (maskedIndex <= 0) return 0;

    const EntityTraversalMode& cfg = kEntityModes[mode];

    uintptr_t listEntry = Read<uintptr_t>(
        entityList + cfg.chunkBaseOffset + sizeof(uintptr_t) * ChunkFromIndex(maskedIndex)
    );
    if (!IsLikelyPtr(listEntry)) return 0;

    uintptr_t entity = Read<uintptr_t>(
        listEntry + kEntityStride * SlotFromIndex(maskedIndex) + cfg.slotEntityOffset
    );
    return IsLikelyPtr(entity) ? entity : 0;
}

static uintptr_t GetEntityByIndex(uintptr_t entityList, int index) {
    return GetEntityByIndexMode(entityList, index, g_entityMode);
}

static int FindEntityIndexByPtr(uintptr_t entityList, uintptr_t target, int mode, int minIndex, int maxIndex) {
    if (!IsLikelyPtr(entityList) || !IsLikelyPtr(target)) return -1;
    for (int i = minIndex; i <= maxIndex; ++i) {
        if (GetEntityByIndexMode(entityList, i, mode) == target)
            return i;
    }
    return -1;
}

static void ProbeEntityTraversalMode(uintptr_t entityList, uintptr_t localCtrl, uintptr_t localPawn, bool verbose) {
    if (!IsLikelyPtr(entityList) || !IsLikelyPtr(localCtrl) || !IsLikelyPtr(localPawn))
        return;

    int bestMode = -1;
    int bestScore = -1;
    int bestCtrlIdx = -1;
    int bestPawnIdx = -1;

    for (int mode = 0; mode < (int)(sizeof(kEntityModes) / sizeof(kEntityModes[0])); ++mode) {
        int ctrlIdx = FindEntityIndexByPtr(entityList, localCtrl, mode, 1, 2048);
        int pawnIdx = FindEntityIndexByPtr(entityList, localPawn, mode, 1, kEntityMaxIndex);
        int score = (ctrlIdx > 0 ? 1 : 0) + (pawnIdx > 0 ? 1 : 0);

        if (verbose) {
            printf("[mode %d] %-22s ctrlIdx=%d pawnIdx=%d score=%d\n",
                mode, kEntityModes[mode].name, ctrlIdx, pawnIdx, score);
        }

        if (score > bestScore) {
            bestScore = score;
            bestMode = mode;
            bestCtrlIdx = ctrlIdx;
            bestPawnIdx = pawnIdx;
        }
    }

    if (bestMode >= 0 && bestScore > 0) {
        g_entityMode = bestMode;
        g_entityModeResolved = true;
        if (verbose) {
            printf("[mode selected] %d (%s) ctrlIdx=%d pawnIdx=%d\n",
                bestMode, kEntityModes[bestMode].name, bestCtrlIdx, bestPawnIdx);
        }
    } else if (verbose) {
        printf("[mode selected] none (all candidates failed)\n");
    }
}

// Iterate player controllers, resolve pawns by m_hPlayerPawn handle.
void UpdatePlayers() {
    std::vector<Player> tmp;

    uintptr_t localCtrl = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerController);
    if (!IsLikelyPtr(localCtrl)) return;

    uint8_t   localTeam = Read<uint8_t>(localCtrl + offsets::m_iTeamNum);
    uintptr_t localPawn = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerPawn);
    uintptr_t entList   = Read<uintptr_t>(g_clientBase + offsets::dwEntityList);
    if (!IsLikelyPtr(entList)) return;

    DWORD now = GetTickCount();
    if (!g_entityModeResolved || now - g_lastEntityModeProbeMs > 3000) {
        ProbeEntityTraversalMode(entList, localCtrl, localPawn, false);
        g_lastEntityModeProbeMs = now;
    }
    if (!g_entityModeResolved) return;

    for (int ctrlIdx = 1; ctrlIdx <= kMaxControllers; ++ctrlIdx) {
        uintptr_t ctrl = GetEntityByIndex(entList, ctrlIdx);
        if (!ctrl || ctrl == localCtrl) continue;

        uint8_t team = Read<uint8_t>(ctrl + offsets::m_iTeamNum);
        if (team != 2 && team != 3) continue;
        if (team == localTeam) continue;

        uint32_t pawnHandle = Read<uint32_t>(ctrl + offsets::m_hPlayerPawn);
        int pawnIdx = IndexFromHandle(pawnHandle);
        if (pawnIdx <= 0) continue;

        uintptr_t pawn = GetEntityByIndex(entList, pawnIdx);
        if (!pawn || pawn == localPawn) continue;

        int hp = Read<int>(pawn + offsets::m_iHealth);
        if (hp <= 0 || hp > 100) continue;
        if (Read<uint8_t>(pawn + offsets::m_lifeState) != 0) continue;

        uintptr_t node = Read<uintptr_t>(pawn + offsets::m_pGameSceneNode);
        if (!IsLikelyPtr(node)) continue;
        if (Read<bool>(node + offsets::m_bDormant)) continue;

        Vec3 origin = Read<Vec3>(node + offsets::m_vecAbsOrigin);

        Vec3 head = { origin.x, origin.y, origin.z + 75.f };
        std::string name = ReadString(ctrl + offsets::m_iszPlayerName, 128);
        tmp.push_back({ origin, head, hp, team, name });
    }

    std::lock_guard<std::mutex> lk(g_playersMtx);
    g_players = std::move(tmp);
}

// ---- Draw ESP ----
void DrawESP(ImDrawList* dl) {
    if (!var->esp.enabled) return;

    std::lock_guard<std::mutex> lk(g_playersMtx);
    for (auto& p : g_players) {
        Vec2 feet, head;
        if (!W2S(p.origin, feet)) continue;
        if (!W2S(p.head,   head))  continue;

        float h = feet.y - head.y;
        if (h < 5.f || h > (float)g_Height) continue;

        float w  = h / 2.f;
        float cx = (feet.x + head.x) * 0.5f;
        float hf = p.health / 100.f;

        ImU32 boxCol = IM_COL32(255, 50,  50,  220);
        ImU32 hpCol  = IM_COL32((int)(255*(1-hf)), (int)(255*hf), 0, 255);
        ImU32 white  = IM_COL32(255, 255, 255, 255);
        ImU32 black  = IM_COL32(0,   0,   0,   180);

        if (var->esp.boxes)
            dl->AddRect({ cx-w/2, head.y }, { cx+w/2, feet.y }, boxCol, 0.f, 0, 1.5f);

        if (var->esp.health_bar) {
            float bx   = cx - w/2 - 6;
            float fill = feet.y - h * hf;
            dl->AddRectFilled({ bx-2, head.y }, { bx+2, feet.y }, black);
            dl->AddRectFilled({ bx-2, fill   }, { bx+2, feet.y }, hpCol);
            if (var->esp.health_num) {
                char buf[8]; sprintf_s(buf, "%d", p.health);
                dl->AddText(nullptr, 11.f, { bx-14, fill-1 }, hpCol, buf);
            }
        }

        if (var->esp.names) {
            const char* n = p.name.empty() ? "unknown" : p.name.c_str();
            dl->AddText(nullptr, 13.f, { cx-w/2+1, head.y-16 }, black,  n);
            dl->AddText(nullptr, 13.f, { cx-w/2,   head.y-17 }, white,  n);
        }
    }
}

// ---- Debug overlay ----
void DrawDebug() {
    if (!g_ShowDebug) return;
    ImGui::SetNextWindowBgAlpha(0.85f);
    ImGui::SetNextWindowSize({ 360, 220 }, ImGuiCond_Once);
    ImGui::SetNextWindowPos({ (float)g_Width - 370.f, 10.f }, ImGuiCond_Once);
    ImGui::Begin("Debug [F1]", &g_ShowDebug);
    ImGui::Text("clientBase:  0x%llX", (unsigned long long)g_clientBase);
    uintptr_t el = Read<uintptr_t>(g_clientBase + offsets::dwEntityList);
    uintptr_t lc = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerController);
    uintptr_t lp = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerPawn);
    ImGui::Text("entityList:  0x%llX", (unsigned long long)el);
    ImGui::Text("localCtrl:   0x%llX", (unsigned long long)lc);
    ImGui::Text("localPawn:   0x%llX", (unsigned long long)lp);
    ImGui::Text("entMode:     %s", g_entityModeResolved ? kEntityModes[g_entityMode].name : "unresolved");
    ImGui::Text("vmCheck:     %.4f", g_vm.m[0][0]);
    {
        std::lock_guard<std::mutex> lk(g_playersMtx);
        ImGui::Text("players:     %d", (int)g_players.size());
    }
    ImGui::Text("screen:      %dx%d", g_Width, g_Height);
    ImGui::Separator();
    if (el && lc) {
        uint8_t localTeamDbg = Read<uint8_t>(lc + offsets::m_iTeamNum);
        ImGui::Text("localTeam:   %d", (int)localTeamDbg);

        // Scan for first controller with a valid pawn handle.
        uintptr_t foundCtrl = 0; int foundIdx = -1;
        for (int i = 1; i <= kMaxControllers && !foundCtrl; ++i) {
            uintptr_t c = GetEntityByIndex(el, i);
            if (!c) continue;
            uint32_t ph = Read<uint32_t>(c + offsets::m_hPlayerPawn);
            if (IndexFromHandle(ph) > 0) {
                foundCtrl = c; foundIdx = i;
            }
        }

        ImGui::Text("firstCtrl:   [%d] 0x%llX", foundIdx, (unsigned long long)foundCtrl);
        if (foundCtrl) {
            uint8_t t = Read<uint8_t>(foundCtrl + offsets::m_iTeamNum);
            uint32_t ph = Read<uint32_t>(foundCtrl + offsets::m_hPlayerPawn);
            int pawnIdx = IndexFromHandle(ph);
            uintptr_t pw = GetEntityByIndex(el, pawnIdx);
            ImGui::Text("team:%d ph:0x%X idx:%d ch:%d sl:%d", (int)t, ph, pawnIdx, ChunkFromIndex(pawnIdx), SlotFromIndex(pawnIdx));
            ImGui::Text("pawn:        0x%llX", (unsigned long long)pw);
            if (pw) {
                uintptr_t nd = Read<uintptr_t>(pw + offsets::m_pGameSceneNode);
                Vec3 org = nd ? Read<Vec3>(nd + offsets::m_vecAbsOrigin) : Vec3{};
                ImGui::Text("hp: %d  life: %d  dormant: %d",
                    Read<int>(pw + offsets::m_iHealth),
                    (int)Read<uint8_t>(pw + offsets::m_lifeState),
                    nd ? (int)Read<bool>(nd + offsets::m_bDormant) : -1);
                ImGui::Text("origin: %.1f %.1f %.1f", org.x, org.y, org.z);
            }
        }
    }
    ImGui::End();
}

// ---- ImGui init ----
void InitImGui() {
    if (g_ImGuiReady) return;

    DXGI_SWAP_CHAIN_DESC sd{};
    g_pSwapChain->GetDesc(&sd);
    g_hWnd = sd.OutputWindow;

    g_pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&g_pDevice);
    g_pDevice->GetImmediateContext(&g_pCtx);

    ID3D11Texture2D* pBack = nullptr;
    g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBack);
    if (pBack) {
        D3D11_TEXTURE2D_DESC desc{};
        pBack->GetDesc(&desc);
        g_Width  = (int)desc.Width;
        g_Height = (int)desc.Height;
        g_pDevice->CreateRenderTargetView(pBack, nullptr, &g_pRTV);
        pBack->Release();
    }

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGui::GetIO().IniFilename = nullptr;
    ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
    ImGui_ImplWin32_Init(g_hWnd);
    ImGui_ImplDX11_Init(g_pDevice, g_pCtx);

    // Hook WndProc to get keyboard/mouse input
    g_oWndProc = (WNDPROC)SetWindowLongPtrA(g_hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc);

    cfg->init_config();

    // DPI for 2K
    int sh = GetSystemMetrics(SM_CYSCREEN);
    int dpi = (sh >= 2160) ? 175 : (sh >= 1440) ? 133 : 100;
    var->gui.stored_dpi  = dpi;
    var->gui.dpi_changed = true;
    var->gui.target_w    = var->gui.base_w * dpi / 100.f;
    var->gui.target_h    = var->gui.base_h * dpi / 100.f;

    g_ImGuiReady = true;
}

// ---- Hooked Present ----
static c_gui* g_gui = nullptr;

HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags) {
    if (!g_pSwapChain) g_pSwapChain = pSwapChain;

    InitImGui();
    if (!g_ImGuiReady) return oPresent(pSwapChain, SyncInterval, Flags);

    // Keys handled in WndProc

    // Update VM
    g_vm = Read<ViewMatrix>(g_clientBase + offsets::dwViewMatrix);

    // Update RTV if needed (window resize)
    if (!g_pRTV) {
        ID3D11Texture2D* pBack = nullptr;
        pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBack);
        if (pBack) {
            D3D11_TEXTURE2D_DESC desc{};
            pBack->GetDesc(&desc);
            g_Width  = (int)desc.Width;
            g_Height = (int)desc.Height;
            g_pDevice->CreateRenderTargetView(pBack, nullptr, &g_pRTV);
            pBack->Release();
        }
    }

    ImGui_ImplDX11_NewFrame();
    ImGui_ImplWin32_NewFrame();
    ImGui::NewFrame();

    // Fullscreen ESP backdrop
    ImGui::SetNextWindowPos({ 0, 0 });
    ImGui::SetNextWindowSize({ (float)g_Width, (float)g_Height });
    ImGui::SetNextWindowBgAlpha(0.f);
    ImGui::Begin("##esp", nullptr,
        ImGuiWindowFlags_NoTitleBar     | ImGuiWindowFlags_NoResize |
        ImGuiWindowFlags_NoMove         | ImGuiWindowFlags_NoInputs |
        ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar
    );
    DrawESP(ImGui::GetWindowDrawList());
    ImGui::End();

    if (g_gui) g_gui->render();
    DrawDebug();

    ImGui::Render();
    g_pCtx->OMSetRenderTargets(1, &g_pRTV, nullptr);
    ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

    return oPresent(pSwapChain, SyncInterval, Flags);
}

// ---- VTable hook ----
bool HookPresent() {
    // Create dummy D3D11 device+swapchain to get vtable
    DXGI_SWAP_CHAIN_DESC sd{};
    sd.BufferCount        = 1;
    sd.BufferDesc.Format  = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferUsage        = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow       = GetForegroundWindow();
    sd.SampleDesc.Count   = 1;
    sd.Windowed           = TRUE;
    sd.SwapEffect         = DXGI_SWAP_EFFECT_DISCARD;

    ID3D11Device*        pDev  = nullptr;
    ID3D11DeviceContext* pCtx  = nullptr;
    IDXGISwapChain*      pSC   = nullptr;
    D3D_FEATURE_LEVEL    fl;

    if (FAILED(D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0,
        nullptr, 0, D3D11_SDK_VERSION, &sd, &pSC, &pDev, &fl, &pCtx)))
        return false;

    g_pVTable = *reinterpret_cast<void***>(pSC);

    // Unprotect vtable page and patch Present (index 8)
    DWORD old;
    VirtualProtect(&g_pVTable[8], sizeof(void*), PAGE_EXECUTE_READWRITE, &old);
    oPresent = reinterpret_cast<Present_t>(g_pVTable[8]);
    g_pVTable[8] = reinterpret_cast<void*>(hkPresent);
    VirtualProtect(&g_pVTable[8], sizeof(void*), old, &old);

    pSC->Release();
    pDev->Release();
    pCtx->Release();
    return true;
}

// ---- Diagnostic (call on demand) ----
void RunDiag() {
    uintptr_t entList = Read<uintptr_t>(g_clientBase + offsets::dwEntityList);
    uintptr_t lc      = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerController);
    uintptr_t lp      = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerPawn);
    printf("=== DIAG ===\n");
    printf("entList=0x%llX  lc=0x%llX  lp=0x%llX\n", entList, lc, lp);
    if (!IsLikelyPtr(entList)) { printf("entList NULL/invalid\n"); return; }

    bool usedChunks[64] = {};

    // Controllers live in low indices; pawns are resolved from handles.
    printf("-- controllers (1..%d) -> pawn handles --\n", kMaxControllers);
    for (int i = 1; i <= kMaxControllers; ++i) {
        uintptr_t ctrl = GetEntityByIndex(entList, i);
        if (!ctrl) continue;

        uint32_t pawnHandle = Read<uint32_t>(ctrl + offsets::m_hPlayerPawn);
        int pawnIdx = IndexFromHandle(pawnHandle);
        if (pawnIdx <= 0) continue;

        int chunk = ChunkFromIndex(pawnIdx);
        int slot  = SlotFromIndex(pawnIdx);
        if (chunk >= 0 && chunk < 64) usedChunks[chunk] = true;

        uintptr_t pawn = GetEntityByIndex(entList, pawnIdx);
        uint8_t team   = Read<uint8_t>(ctrl + offsets::m_iTeamNum);
        std::string name = ReadString(ctrl + offsets::m_iszPlayerName, 128);

        int hp = -1;
        int life = -1;
        int dorm = -1;
        Vec3 org{};
        if (pawn) {
            hp = Read<int>(pawn + offsets::m_iHealth);
            life = (int)Read<uint8_t>(pawn + offsets::m_lifeState);
            uintptr_t nd = Read<uintptr_t>(pawn + offsets::m_pGameSceneNode);
            if (IsLikelyPtr(nd)) {
                dorm = (int)Read<bool>(nd + offsets::m_bDormant);
                org = Read<Vec3>(nd + offsets::m_vecAbsOrigin);
            }
        }

        printf("[C%02d] ctrl=0x%llX team=%d ph=0x%X idx=%d ch=%d sl=%d pawn=0x%llX hp=%d life=%d dorm=%d org=%.0f,%.0f,%.0f name=%s\n",
            i, ctrl, (int)team, pawnHandle, pawnIdx, chunk, slot, pawn, hp, life, dorm, org.x, org.y, org.z, name.c_str());
    }

    printf("-- chunk pointers used by pawn handles --\n");
    for (int ch = 0; ch < 64; ++ch) {
        if (!usedChunks[ch]) continue;
        uintptr_t le = Read<uintptr_t>(entList + kEntityListOffset + sizeof(uintptr_t) * ch);
        printf("  chunk[%d] = 0x%llX\n", ch, le);
    }

    printf("-- localPawn index search (1..0x%X) --\n", kEntityMaxIndex);
    int localPawnIndex = -1;
    for (int i = 1; i <= kEntityMaxIndex; ++i) {
        if (GetEntityByIndex(entList, i) == lp) {
            localPawnIndex = i;
            break;
        }
    }
    if (localPawnIndex > 0) {
        printf("localPawn idx=%d ch=%d sl=%d\n",
            localPawnIndex, ChunkFromIndex(localPawnIndex), SlotFromIndex(localPawnIndex));
    } else {
        printf("localPawn not found in 1..0x%X\n", kEntityMaxIndex);
    }

    printf("=== END DIAG ===\n");
}

// ---- Entity reader thread ----
void ReaderThread() {
    while (true) {
        if (g_clientBase) UpdatePlayers();
        Sleep(10);
    }
}

// ---- DLL Entry ----
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) {
    if (reason == DLL_PROCESS_ATTACH) {
        DisableThreadLibraryCalls(hInst);

        std::thread([]() {
            AllocConsole();
            FILE* f;
            freopen_s(&f, "CONOUT$", "w", stdout);
            printf("[*] CS2 Internal loading...\n");

            // Wait for client.dll
            while (!(g_clientBase = GetModuleBase("client.dll")))
                Sleep(500);
            printf("[+] client.dll: 0x%llX\n", (unsigned long long)g_clientBase);

            if (!HookPresent()) {
                printf("[-] HookPresent failed\n");
                return;
            }
            printf("[+] Present hooked\n");

            g_gui = new c_gui();

            std::thread(ReaderThread).detach();
            printf("[+] Ready. INSERT = menu, G = ESP, F1 = debug\n");
        }).detach();
    }

    if (reason == DLL_PROCESS_DETACH) {
        // Unhook
        if (g_pVTable && oPresent) {
            DWORD old;
            VirtualProtect(&g_pVTable[8], sizeof(void*), PAGE_EXECUTE_READWRITE, &old);
            g_pVTable[8] = reinterpret_cast<void*>(oPresent);
            VirtualProtect(&g_pVTable[8], sizeof(void*), old, &old);
        }
        if (g_ImGuiReady) {
            if (g_oWndProc) SetWindowLongPtrA(g_hWnd, GWLP_WNDPROC, (LONG_PTR)g_oWndProc);
            ImGui_ImplDX11_Shutdown();
            ImGui_ImplWin32_Shutdown();
            ImGui::DestroyContext();
        }
        if (g_pRTV) g_pRTV->Release();
    }

    return TRUE;
}

Перепробовали много всего. В чем заключается проблема? Умные люди помогите, пожалуйста
 
Через нейронку написал ESP, не рендерится. Дошли до логов:

Код:
Expand Collapse Copy
[*] CS2 Internal loading...

[+] client.dll: 0x7FFD71F20000

[+] Present hooked

[+] Ready. INSERT = menu, G = ESP, F1 = debug

=== DIAG ===

entList=0x3D8E5284800  lc=0x3D968F50600  lp=0x3D9A7090000

-- controllers (1..64) -> pawn handles --

[C04] ctrl=0x3D8E5F4F4CE team=0 ph=0x7453825C idx=604 ch=1 sl=92 pawn=0x0 hp=-1 life=-1 dorm=-1 org=0,0,0 name=remapper

-- chunk pointers used by pawn handles --

  chunk[1] = 0x0

-- localPawn index search (1..0x7FFF) --

localPawn not found in 1..0x7FFF

=== END DIAG ===

=== DIAG ===

entList=0x3D8E5284800  lc=0x3D968F50600  lp=0x3D9A7090000

-- controllers (1..64) -> pawn handles --

[C04] ctrl=0x3D8E5F4F4CE team=0 ph=0x7453825C idx=604 ch=1 sl=92 pawn=0x0 hp=-1 life=-1 dorm=-1 org=0,0,0 name=remapper

-- chunk pointers used by pawn handles --

  chunk[1] = 0x0

-- localPawn index search (1..0x7FFF) --

localPawn not found in 1..0x7FFF

=== END DIAG ===

Сам код дллки:

Код:
Expand Collapse Copy
#undef UNICODE
#undef _UNICODE

#include <Windows.h>
#include <d3d11.h>
#include <string>
#include <vector>
#include <thread>
#include <mutex>

#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui/imgui.h"
#include "imgui/imgui_impl_win32.h"
#include "imgui/imgui_impl_dx11.h"

#include "framework/headers/includes.h"
#include "framework/gui.cpp"
#include "framework/helpers/config.cpp"
#include "framework/helpers/draw.cpp"
#include "framework/helpers/fonts.cpp"
#include "framework/helpers/popups.cpp"
#include "framework/widgets/helpers.cpp"
#include "framework/widgets/notify.cpp"
#include "framework/widgets/widgets.cpp"
#include "framework/widgets/window.cpp"

#include "memory.hpp"
#include "offsets.hpp"

#pragma comment(lib, "d3d11.lib")

// ---- Types ----
struct Vec3 { float x, y, z; };
struct Vec2 { float x, y; };
struct ViewMatrix { float m[4][4]; };

struct Player {
    Vec3        origin;
    Vec3        head;
    int         health;
    int         team;
    std::string name;
};

// ---- Globals ----
static ID3D11Device*           g_pDevice     = nullptr;
static ID3D11DeviceContext*    g_pCtx        = nullptr;
static ID3D11RenderTargetView* g_pRTV        = nullptr;
static IDXGISwapChain*         g_pSwapChain  = nullptr;
static HWND                    g_hWnd        = nullptr;
static bool                    g_ImGuiReady  = false;
static bool                    g_ShowDebug   = false;
static int                     g_Width       = 1920;
static int                     g_Height      = 1080;

static uintptr_t               g_clientBase  = 0;
static std::vector<Player>     g_players;
static ViewMatrix              g_vm{};
static std::mutex              g_playersMtx;

// ---- Present hook ----
using Present_t = HRESULT(__stdcall*)(IDXGISwapChain*, UINT, UINT);
static Present_t oPresent = nullptr;
static void**    g_pVTable = nullptr;

extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND, UINT, WPARAM, LPARAM);
void RunDiag();
static WNDPROC g_oWndProc = nullptr;

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    if (g_ImGuiReady) {
        if (msg == WM_KEYDOWN && wParam == VK_INSERT) {
            var->gui.opened = !var->gui.opened;
            return true;
        }
        if (msg == WM_KEYDOWN && wParam == 'G') {
            var->esp.enabled = !var->esp.enabled;
            return true;
        }
        if (msg == WM_KEYDOWN && wParam == VK_F1) {
            g_ShowDebug = !g_ShowDebug;
            return true;
        }
        if (msg == WM_KEYDOWN && wParam == VK_F2) {
            std::thread(RunDiag).detach();
            return true;
        }
        if (var->gui.opened && ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam))
            return true;
    }
    return CallWindowProcA(g_oWndProc, hWnd, msg, wParam, lParam);
}

// ---- World to screen ----
bool W2S(const Vec3& pos, Vec2& out) {
    float w = g_vm.m[3][0]*pos.x + g_vm.m[3][1]*pos.y + g_vm.m[3][2]*pos.z + g_vm.m[3][3];
    if (w < 0.001f) return false;
    float x = g_vm.m[0][0]*pos.x + g_vm.m[0][1]*pos.y + g_vm.m[0][2]*pos.z + g_vm.m[0][3];
    float y = g_vm.m[1][0]*pos.x + g_vm.m[1][1]*pos.y + g_vm.m[1][2]*pos.z + g_vm.m[1][3];
    out.x = (g_Width  * 0.5f) + (g_Width  * 0.5f) * x / w;
    out.y = (g_Height * 0.5f) - (g_Height * 0.5f) * y / w;
    return true;
}

// ---- Read entities ----
static bool IsLikelyPtr(uintptr_t p) {
    return p > 0x10000 && p < 0x7FF000000000ULL;
}

static constexpr int kEntityIndexMask  = 0x7FFF;
static constexpr int kEntityChunkShift = 9;      // 512 entries per chunk
static constexpr int kEntityChunkSize  = 1 << kEntityChunkShift;
static constexpr int kEntityMaxIndex   = kEntityIndexMask;
static constexpr int kMaxControllers   = 64;
static constexpr uintptr_t kEntityStride     = 0x78;

struct EntityTraversalMode {
    const char* name;
    uintptr_t   chunkBaseOffset;
    uintptr_t   slotEntityOffset;
};

static constexpr EntityTraversalMode kEntityModes[] = {
    { "chunk+0x10 slot+0x00", 0x10, 0x00 },
    { "chunk+0x10 slot+0x10", 0x10, 0x10 },
    { "chunk+0x00 slot+0x00", 0x00, 0x00 },
    { "chunk+0x00 slot+0x10", 0x00, 0x10 },
};

static int  g_entityMode = 0;
static bool g_entityModeResolved = false;
static DWORD g_lastEntityModeProbeMs = 0;

static int IndexFromHandle(uint32_t handle) {
    return static_cast<int>(handle & kEntityIndexMask);
}

static int ChunkFromIndex(int index) {
    return (index & kEntityIndexMask) >> kEntityChunkShift;
}

static int SlotFromIndex(int index) {
    return index & (kEntityChunkSize - 1);
}

static uintptr_t GetEntityByIndexMode(uintptr_t entityList, int index, int mode) {
    if (!IsLikelyPtr(entityList)) return 0;
    if (mode < 0 || mode >= (int)(sizeof(kEntityModes) / sizeof(kEntityModes[0])))
        return 0;

    int maskedIndex = index & kEntityIndexMask;
    if (maskedIndex <= 0) return 0;

    const EntityTraversalMode& cfg = kEntityModes[mode];

    uintptr_t listEntry = Read<uintptr_t>(
        entityList + cfg.chunkBaseOffset + sizeof(uintptr_t) * ChunkFromIndex(maskedIndex)
    );
    if (!IsLikelyPtr(listEntry)) return 0;

    uintptr_t entity = Read<uintptr_t>(
        listEntry + kEntityStride * SlotFromIndex(maskedIndex) + cfg.slotEntityOffset
    );
    return IsLikelyPtr(entity) ? entity : 0;
}

static uintptr_t GetEntityByIndex(uintptr_t entityList, int index) {
    return GetEntityByIndexMode(entityList, index, g_entityMode);
}

static int FindEntityIndexByPtr(uintptr_t entityList, uintptr_t target, int mode, int minIndex, int maxIndex) {
    if (!IsLikelyPtr(entityList) || !IsLikelyPtr(target)) return -1;
    for (int i = minIndex; i <= maxIndex; ++i) {
        if (GetEntityByIndexMode(entityList, i, mode) == target)
            return i;
    }
    return -1;
}

static void ProbeEntityTraversalMode(uintptr_t entityList, uintptr_t localCtrl, uintptr_t localPawn, bool verbose) {
    if (!IsLikelyPtr(entityList) || !IsLikelyPtr(localCtrl) || !IsLikelyPtr(localPawn))
        return;

    int bestMode = -1;
    int bestScore = -1;
    int bestCtrlIdx = -1;
    int bestPawnIdx = -1;

    for (int mode = 0; mode < (int)(sizeof(kEntityModes) / sizeof(kEntityModes[0])); ++mode) {
        int ctrlIdx = FindEntityIndexByPtr(entityList, localCtrl, mode, 1, 2048);
        int pawnIdx = FindEntityIndexByPtr(entityList, localPawn, mode, 1, kEntityMaxIndex);
        int score = (ctrlIdx > 0 ? 1 : 0) + (pawnIdx > 0 ? 1 : 0);

        if (verbose) {
            printf("[mode %d] %-22s ctrlIdx=%d pawnIdx=%d score=%d\n",
                mode, kEntityModes[mode].name, ctrlIdx, pawnIdx, score);
        }

        if (score > bestScore) {
            bestScore = score;
            bestMode = mode;
            bestCtrlIdx = ctrlIdx;
            bestPawnIdx = pawnIdx;
        }
    }

    if (bestMode >= 0 && bestScore > 0) {
        g_entityMode = bestMode;
        g_entityModeResolved = true;
        if (verbose) {
            printf("[mode selected] %d (%s) ctrlIdx=%d pawnIdx=%d\n",
                bestMode, kEntityModes[bestMode].name, bestCtrlIdx, bestPawnIdx);
        }
    } else if (verbose) {
        printf("[mode selected] none (all candidates failed)\n");
    }
}

// Iterate player controllers, resolve pawns by m_hPlayerPawn handle.
void UpdatePlayers() {
    std::vector<Player> tmp;

    uintptr_t localCtrl = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerController);
    if (!IsLikelyPtr(localCtrl)) return;

    uint8_t   localTeam = Read<uint8_t>(localCtrl + offsets::m_iTeamNum);
    uintptr_t localPawn = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerPawn);
    uintptr_t entList   = Read<uintptr_t>(g_clientBase + offsets::dwEntityList);
    if (!IsLikelyPtr(entList)) return;

    DWORD now = GetTickCount();
    if (!g_entityModeResolved || now - g_lastEntityModeProbeMs > 3000) {
        ProbeEntityTraversalMode(entList, localCtrl, localPawn, false);
        g_lastEntityModeProbeMs = now;
    }
    if (!g_entityModeResolved) return;

    for (int ctrlIdx = 1; ctrlIdx <= kMaxControllers; ++ctrlIdx) {
        uintptr_t ctrl = GetEntityByIndex(entList, ctrlIdx);
        if (!ctrl || ctrl == localCtrl) continue;

        uint8_t team = Read<uint8_t>(ctrl + offsets::m_iTeamNum);
        if (team != 2 && team != 3) continue;
        if (team == localTeam) continue;

        uint32_t pawnHandle = Read<uint32_t>(ctrl + offsets::m_hPlayerPawn);
        int pawnIdx = IndexFromHandle(pawnHandle);
        if (pawnIdx <= 0) continue;

        uintptr_t pawn = GetEntityByIndex(entList, pawnIdx);
        if (!pawn || pawn == localPawn) continue;

        int hp = Read<int>(pawn + offsets::m_iHealth);
        if (hp <= 0 || hp > 100) continue;
        if (Read<uint8_t>(pawn + offsets::m_lifeState) != 0) continue;

        uintptr_t node = Read<uintptr_t>(pawn + offsets::m_pGameSceneNode);
        if (!IsLikelyPtr(node)) continue;
        if (Read<bool>(node + offsets::m_bDormant)) continue;

        Vec3 origin = Read<Vec3>(node + offsets::m_vecAbsOrigin);

        Vec3 head = { origin.x, origin.y, origin.z + 75.f };
        std::string name = ReadString(ctrl + offsets::m_iszPlayerName, 128);
        tmp.push_back({ origin, head, hp, team, name });
    }

    std::lock_guard<std::mutex> lk(g_playersMtx);
    g_players = std::move(tmp);
}

// ---- Draw ESP ----
void DrawESP(ImDrawList* dl) {
    if (!var->esp.enabled) return;

    std::lock_guard<std::mutex> lk(g_playersMtx);
    for (auto& p : g_players) {
        Vec2 feet, head;
        if (!W2S(p.origin, feet)) continue;
        if (!W2S(p.head,   head))  continue;

        float h = feet.y - head.y;
        if (h < 5.f || h > (float)g_Height) continue;

        float w  = h / 2.f;
        float cx = (feet.x + head.x) * 0.5f;
        float hf = p.health / 100.f;

        ImU32 boxCol = IM_COL32(255, 50,  50,  220);
        ImU32 hpCol  = IM_COL32((int)(255*(1-hf)), (int)(255*hf), 0, 255);
        ImU32 white  = IM_COL32(255, 255, 255, 255);
        ImU32 black  = IM_COL32(0,   0,   0,   180);

        if (var->esp.boxes)
            dl->AddRect({ cx-w/2, head.y }, { cx+w/2, feet.y }, boxCol, 0.f, 0, 1.5f);

        if (var->esp.health_bar) {
            float bx   = cx - w/2 - 6;
            float fill = feet.y - h * hf;
            dl->AddRectFilled({ bx-2, head.y }, { bx+2, feet.y }, black);
            dl->AddRectFilled({ bx-2, fill   }, { bx+2, feet.y }, hpCol);
            if (var->esp.health_num) {
                char buf[8]; sprintf_s(buf, "%d", p.health);
                dl->AddText(nullptr, 11.f, { bx-14, fill-1 }, hpCol, buf);
            }
        }

        if (var->esp.names) {
            const char* n = p.name.empty() ? "unknown" : p.name.c_str();
            dl->AddText(nullptr, 13.f, { cx-w/2+1, head.y-16 }, black,  n);
            dl->AddText(nullptr, 13.f, { cx-w/2,   head.y-17 }, white,  n);
        }
    }
}

// ---- Debug overlay ----
void DrawDebug() {
    if (!g_ShowDebug) return;
    ImGui::SetNextWindowBgAlpha(0.85f);
    ImGui::SetNextWindowSize({ 360, 220 }, ImGuiCond_Once);
    ImGui::SetNextWindowPos({ (float)g_Width - 370.f, 10.f }, ImGuiCond_Once);
    ImGui::Begin("Debug [F1]", &g_ShowDebug);
    ImGui::Text("clientBase:  0x%llX", (unsigned long long)g_clientBase);
    uintptr_t el = Read<uintptr_t>(g_clientBase + offsets::dwEntityList);
    uintptr_t lc = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerController);
    uintptr_t lp = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerPawn);
    ImGui::Text("entityList:  0x%llX", (unsigned long long)el);
    ImGui::Text("localCtrl:   0x%llX", (unsigned long long)lc);
    ImGui::Text("localPawn:   0x%llX", (unsigned long long)lp);
    ImGui::Text("entMode:     %s", g_entityModeResolved ? kEntityModes[g_entityMode].name : "unresolved");
    ImGui::Text("vmCheck:     %.4f", g_vm.m[0][0]);
    {
        std::lock_guard<std::mutex> lk(g_playersMtx);
        ImGui::Text("players:     %d", (int)g_players.size());
    }
    ImGui::Text("screen:      %dx%d", g_Width, g_Height);
    ImGui::Separator();
    if (el && lc) {
        uint8_t localTeamDbg = Read<uint8_t>(lc + offsets::m_iTeamNum);
        ImGui::Text("localTeam:   %d", (int)localTeamDbg);

        // Scan for first controller with a valid pawn handle.
        uintptr_t foundCtrl = 0; int foundIdx = -1;
        for (int i = 1; i <= kMaxControllers && !foundCtrl; ++i) {
            uintptr_t c = GetEntityByIndex(el, i);
            if (!c) continue;
            uint32_t ph = Read<uint32_t>(c + offsets::m_hPlayerPawn);
            if (IndexFromHandle(ph) > 0) {
                foundCtrl = c; foundIdx = i;
            }
        }

        ImGui::Text("firstCtrl:   [%d] 0x%llX", foundIdx, (unsigned long long)foundCtrl);
        if (foundCtrl) {
            uint8_t t = Read<uint8_t>(foundCtrl + offsets::m_iTeamNum);
            uint32_t ph = Read<uint32_t>(foundCtrl + offsets::m_hPlayerPawn);
            int pawnIdx = IndexFromHandle(ph);
            uintptr_t pw = GetEntityByIndex(el, pawnIdx);
            ImGui::Text("team:%d ph:0x%X idx:%d ch:%d sl:%d", (int)t, ph, pawnIdx, ChunkFromIndex(pawnIdx), SlotFromIndex(pawnIdx));
            ImGui::Text("pawn:        0x%llX", (unsigned long long)pw);
            if (pw) {
                uintptr_t nd = Read<uintptr_t>(pw + offsets::m_pGameSceneNode);
                Vec3 org = nd ? Read<Vec3>(nd + offsets::m_vecAbsOrigin) : Vec3{};
                ImGui::Text("hp: %d  life: %d  dormant: %d",
                    Read<int>(pw + offsets::m_iHealth),
                    (int)Read<uint8_t>(pw + offsets::m_lifeState),
                    nd ? (int)Read<bool>(nd + offsets::m_bDormant) : -1);
                ImGui::Text("origin: %.1f %.1f %.1f", org.x, org.y, org.z);
            }
        }
    }
    ImGui::End();
}

// ---- ImGui init ----
void InitImGui() {
    if (g_ImGuiReady) return;

    DXGI_SWAP_CHAIN_DESC sd{};
    g_pSwapChain->GetDesc(&sd);
    g_hWnd = sd.OutputWindow;

    g_pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&g_pDevice);
    g_pDevice->GetImmediateContext(&g_pCtx);

    ID3D11Texture2D* pBack = nullptr;
    g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBack);
    if (pBack) {
        D3D11_TEXTURE2D_DESC desc{};
        pBack->GetDesc(&desc);
        g_Width  = (int)desc.Width;
        g_Height = (int)desc.Height;
        g_pDevice->CreateRenderTargetView(pBack, nullptr, &g_pRTV);
        pBack->Release();
    }

    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGui::GetIO().IniFilename = nullptr;
    ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange;
    ImGui_ImplWin32_Init(g_hWnd);
    ImGui_ImplDX11_Init(g_pDevice, g_pCtx);

    // Hook WndProc to get keyboard/mouse input
    g_oWndProc = (WNDPROC)SetWindowLongPtrA(g_hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc);

    cfg->init_config();

    // DPI for 2K
    int sh = GetSystemMetrics(SM_CYSCREEN);
    int dpi = (sh >= 2160) ? 175 : (sh >= 1440) ? 133 : 100;
    var->gui.stored_dpi  = dpi;
    var->gui.dpi_changed = true;
    var->gui.target_w    = var->gui.base_w * dpi / 100.f;
    var->gui.target_h    = var->gui.base_h * dpi / 100.f;

    g_ImGuiReady = true;
}

// ---- Hooked Present ----
static c_gui* g_gui = nullptr;

HRESULT __stdcall hkPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags) {
    if (!g_pSwapChain) g_pSwapChain = pSwapChain;

    InitImGui();
    if (!g_ImGuiReady) return oPresent(pSwapChain, SyncInterval, Flags);

    // Keys handled in WndProc

    // Update VM
    g_vm = Read<ViewMatrix>(g_clientBase + offsets::dwViewMatrix);

    // Update RTV if needed (window resize)
    if (!g_pRTV) {
        ID3D11Texture2D* pBack = nullptr;
        pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBack);
        if (pBack) {
            D3D11_TEXTURE2D_DESC desc{};
            pBack->GetDesc(&desc);
            g_Width  = (int)desc.Width;
            g_Height = (int)desc.Height;
            g_pDevice->CreateRenderTargetView(pBack, nullptr, &g_pRTV);
            pBack->Release();
        }
    }

    ImGui_ImplDX11_NewFrame();
    ImGui_ImplWin32_NewFrame();
    ImGui::NewFrame();

    // Fullscreen ESP backdrop
    ImGui::SetNextWindowPos({ 0, 0 });
    ImGui::SetNextWindowSize({ (float)g_Width, (float)g_Height });
    ImGui::SetNextWindowBgAlpha(0.f);
    ImGui::Begin("##esp", nullptr,
        ImGuiWindowFlags_NoTitleBar     | ImGuiWindowFlags_NoResize |
        ImGuiWindowFlags_NoMove         | ImGuiWindowFlags_NoInputs |
        ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoScrollbar
    );
    DrawESP(ImGui::GetWindowDrawList());
    ImGui::End();

    if (g_gui) g_gui->render();
    DrawDebug();

    ImGui::Render();
    g_pCtx->OMSetRenderTargets(1, &g_pRTV, nullptr);
    ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());

    return oPresent(pSwapChain, SyncInterval, Flags);
}

// ---- VTable hook ----
bool HookPresent() {
    // Create dummy D3D11 device+swapchain to get vtable
    DXGI_SWAP_CHAIN_DESC sd{};
    sd.BufferCount        = 1;
    sd.BufferDesc.Format  = DXGI_FORMAT_R8G8B8A8_UNORM;
    sd.BufferUsage        = DXGI_USAGE_RENDER_TARGET_OUTPUT;
    sd.OutputWindow       = GetForegroundWindow();
    sd.SampleDesc.Count   = 1;
    sd.Windowed           = TRUE;
    sd.SwapEffect         = DXGI_SWAP_EFFECT_DISCARD;

    ID3D11Device*        pDev  = nullptr;
    ID3D11DeviceContext* pCtx  = nullptr;
    IDXGISwapChain*      pSC   = nullptr;
    D3D_FEATURE_LEVEL    fl;

    if (FAILED(D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0,
        nullptr, 0, D3D11_SDK_VERSION, &sd, &pSC, &pDev, &fl, &pCtx)))
        return false;

    g_pVTable = *reinterpret_cast<void***>(pSC);

    // Unprotect vtable page and patch Present (index 8)
    DWORD old;
    VirtualProtect(&g_pVTable[8], sizeof(void*), PAGE_EXECUTE_READWRITE, &old);
    oPresent = reinterpret_cast<Present_t>(g_pVTable[8]);
    g_pVTable[8] = reinterpret_cast<void*>(hkPresent);
    VirtualProtect(&g_pVTable[8], sizeof(void*), old, &old);

    pSC->Release();
    pDev->Release();
    pCtx->Release();
    return true;
}

// ---- Diagnostic (call on demand) ----
void RunDiag() {
    uintptr_t entList = Read<uintptr_t>(g_clientBase + offsets::dwEntityList);
    uintptr_t lc      = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerController);
    uintptr_t lp      = Read<uintptr_t>(g_clientBase + offsets::dwLocalPlayerPawn);
    printf("=== DIAG ===\n");
    printf("entList=0x%llX  lc=0x%llX  lp=0x%llX\n", entList, lc, lp);
    if (!IsLikelyPtr(entList)) { printf("entList NULL/invalid\n"); return; }

    bool usedChunks[64] = {};

    // Controllers live in low indices; pawns are resolved from handles.
    printf("-- controllers (1..%d) -> pawn handles --\n", kMaxControllers);
    for (int i = 1; i <= kMaxControllers; ++i) {
        uintptr_t ctrl = GetEntityByIndex(entList, i);
        if (!ctrl) continue;

        uint32_t pawnHandle = Read<uint32_t>(ctrl + offsets::m_hPlayerPawn);
        int pawnIdx = IndexFromHandle(pawnHandle);
        if (pawnIdx <= 0) continue;

        int chunk = ChunkFromIndex(pawnIdx);
        int slot  = SlotFromIndex(pawnIdx);
        if (chunk >= 0 && chunk < 64) usedChunks[chunk] = true;

        uintptr_t pawn = GetEntityByIndex(entList, pawnIdx);
        uint8_t team   = Read<uint8_t>(ctrl + offsets::m_iTeamNum);
        std::string name = ReadString(ctrl + offsets::m_iszPlayerName, 128);

        int hp = -1;
        int life = -1;
        int dorm = -1;
        Vec3 org{};
        if (pawn) {
            hp = Read<int>(pawn + offsets::m_iHealth);
            life = (int)Read<uint8_t>(pawn + offsets::m_lifeState);
            uintptr_t nd = Read<uintptr_t>(pawn + offsets::m_pGameSceneNode);
            if (IsLikelyPtr(nd)) {
                dorm = (int)Read<bool>(nd + offsets::m_bDormant);
                org = Read<Vec3>(nd + offsets::m_vecAbsOrigin);
            }
        }

        printf("[C%02d] ctrl=0x%llX team=%d ph=0x%X idx=%d ch=%d sl=%d pawn=0x%llX hp=%d life=%d dorm=%d org=%.0f,%.0f,%.0f name=%s\n",
            i, ctrl, (int)team, pawnHandle, pawnIdx, chunk, slot, pawn, hp, life, dorm, org.x, org.y, org.z, name.c_str());
    }

    printf("-- chunk pointers used by pawn handles --\n");
    for (int ch = 0; ch < 64; ++ch) {
        if (!usedChunks[ch]) continue;
        uintptr_t le = Read<uintptr_t>(entList + kEntityListOffset + sizeof(uintptr_t) * ch);
        printf("  chunk[%d] = 0x%llX\n", ch, le);
    }

    printf("-- localPawn index search (1..0x%X) --\n", kEntityMaxIndex);
    int localPawnIndex = -1;
    for (int i = 1; i <= kEntityMaxIndex; ++i) {
        if (GetEntityByIndex(entList, i) == lp) {
            localPawnIndex = i;
            break;
        }
    }
    if (localPawnIndex > 0) {
        printf("localPawn idx=%d ch=%d sl=%d\n",
            localPawnIndex, ChunkFromIndex(localPawnIndex), SlotFromIndex(localPawnIndex));
    } else {
        printf("localPawn not found in 1..0x%X\n", kEntityMaxIndex);
    }

    printf("=== END DIAG ===\n");
}

// ---- Entity reader thread ----
void ReaderThread() {
    while (true) {
        if (g_clientBase) UpdatePlayers();
        Sleep(10);
    }
}

// ---- DLL Entry ----
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD reason, LPVOID) {
    if (reason == DLL_PROCESS_ATTACH) {
        DisableThreadLibraryCalls(hInst);

        std::thread([]() {
            AllocConsole();
            FILE* f;
            freopen_s(&f, "CONOUT$", "w", stdout);
            printf("[*] CS2 Internal loading...\n");

            // Wait for client.dll
            while (!(g_clientBase = GetModuleBase("client.dll")))
                Sleep(500);
            printf("[+] client.dll: 0x%llX\n", (unsigned long long)g_clientBase);

            if (!HookPresent()) {
                printf("[-] HookPresent failed\n");
                return;
            }
            printf("[+] Present hooked\n");

            g_gui = new c_gui();

            std::thread(ReaderThread).detach();
            printf("[+] Ready. INSERT = menu, G = ESP, F1 = debug\n");
        }).detach();
    }

    if (reason == DLL_PROCESS_DETACH) {
        // Unhook
        if (g_pVTable && oPresent) {
            DWORD old;
            VirtualProtect(&g_pVTable[8], sizeof(void*), PAGE_EXECUTE_READWRITE, &old);
            g_pVTable[8] = reinterpret_cast<void*>(oPresent);
            VirtualProtect(&g_pVTable[8], sizeof(void*), old, &old);
        }
        if (g_ImGuiReady) {
            if (g_oWndProc) SetWindowLongPtrA(g_hWnd, GWLP_WNDPROC, (LONG_PTR)g_oWndProc);
            ImGui_ImplDX11_Shutdown();
            ImGui_ImplWin32_Shutdown();
            ImGui::DestroyContext();
        }
        if (g_pRTV) g_pRTV->Release();
    }

    return TRUE;
}

Перепробовали много всего. В чем заключается проблема? Умные люди помогите, пожалуйста
фух, исправил. проблема была в обходе entity list, IsLikelyPtr был сломан и валидные адреса ломал (отбрасывал), изза этого client + dwEntityList вообще не попадал в проверку
 
Назад
Сверху Снизу