From 33f5ed9ef58f26c6b3b52cf605dd4311d658a60d Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 6 Nov 2026 16:09:55 +0100 Subject: Fix audit findings: crash safety, correctness, rendering, performance Crash/UB: - gate every hook behind an init-stage flag until config/surface/input are ready - publish module maps as immutable atomic snapshots instead of reallocating shared vectors under unlocked readers - validate the %ebp walk in the RandomSeed/RandomFloat hooks against the stack - bounds-check every RecvTable/RecvProp/string dereference with module_range() - preserve the Itanium vtable header when cloning (client, CInput, model render, studio render) - reject negative usercmd sequence numbers; guard config_load against a null section target; cap the bone parent walk; check mprotect; drop PROT_EXEC on the GOT patch; absorb server.so .bss tail Correctness: - filter dormant entities across ESP, aimbot, triggerbot, melee, items and projectiles (slot self-tested against the local player) - reset the server-health latch per map and only latch on valid model indices - bone cache sized for the 128-target scan; set valid=false on every failure; head_position keeps searching past an invalid bone - vischeck steps past glass by probing until clear, and ignores entities owned by the target (held weapons, bone followers) - aimbot: maxs no longer disables it, AABB-aware FOV prefilter, lock hysteresis, lead point re-checked for FOV and visibility - spread: seed hook arms on the no-spread toggle alone; engine toggle only controls the RandomFloat zeroing - resolve m_hOwnerEntity/m_hOwner; NPC lead velocity from the server entity - vector_angles pitch range, point_ground normal test, underwater jump+duck no longer skips combat, semi-auto press/release edge for synthetic fire - item/projectile markers and blast rings refresh origin per frame while discovery stays at 10 Hz; trajectory uses the real m_DmgRadius and honours the blast-radius toggle Rendering/GUI: - one overlay draw per engine frame (FRAME_RENDER_START boundary), fixing alpha stacking and the speed-graph flicker - clipped lines/outlines and ellipsised text instead of drawing past the content pane or shifting over neighbours - dropdown dismissal consumes the click; hover ignores hidden controls - chams: reset AlphaModulate, reference shared materials once, restore prop tint colour; fonts created once per handle - projection uses Source's 4:3 aspect scaling and roll; screen size refreshed each frame; FOV circle gated on the aim toggles, not the bind Performance: - TTL caches for NPC relation, friendly/neutral and damage class - model names memoised per model index - entity pointer -> index cache for the triggerbot (was a 4096-slot walk/tick) Build: - real Makefile with -MMD dependency tracking, debug/release objects and an always-relink rule; build.sh kept as a thin wrapper --- src/overlay.cpp | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/overlay.cpp (limited to 'src/overlay.cpp') diff --git a/src/overlay.cpp b/src/overlay.cpp new file mode 100644 index 0000000..2445d95 --- /dev/null +++ b/src/overlay.cpp @@ -0,0 +1,140 @@ +// overlay.cpp — the single ISurface access layer. +#include "hl2h.h" +#include + +ISurface *g_surface = nullptr; + +// --------------------------------------------------------------------------- +// per-frame draw budget +// --------------------------------------------------------------------------- + +static bool g_drawn_this_frame = false; +static double g_frame_mark_at = 0.0; + +static double overlay_now() { + timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (double)ts.tv_sec + (double)ts.tv_nsec * 1e-9; +} + +void overlay_frame_mark() { + g_drawn_this_frame = false; + g_frame_mark_at = overlay_now(); +} + +bool overlay_should_draw() { + if (g_drawn_this_frame && overlay_now() - g_frame_mark_at < 0.10) + return false; + g_drawn_this_frame = true; + return true; +} + +void overlay_color(int r, int g, int b, int a) { + if (!g_surface) + return; + using Fn = void (*)(void *, int, int, int, int); + vfunc(g_surface, SURF_DrawSetColor)(g_surface, r, g, b, a); +} + +void overlay_fill(int x0, int y0, int x1, int y1) { + if (!g_surface) + return; + using Fn = void (*)(void *, int, int, int, int); + vfunc(g_surface, SURF_DrawFilledRect)(g_surface, x0, y0, x1, y1); +} + +void overlay_outline_rect(int x0, int y0, int x1, int y1) { + if (!g_surface) + return; + using Fn = void (*)(void *, int, int, int, int); + vfunc(g_surface, SURF_DrawOutlinedRect)(g_surface, x0, y0, x1, y1); +} + +void overlay_line(int x0, int y0, int x1, int y1) { + if (!g_surface) + return; + using Fn = void (*)(void *, int, int, int, int); + vfunc(g_surface, SURF_DrawLine)(g_surface, x0, y0, x1, y1); +} + +void overlay_text_font(HFont f) { + if (!g_surface) + return; + using Fn = void (*)(void *, HFont); + vfunc(g_surface, SURF_DrawSetTextFont)(g_surface, f); +} + +void overlay_text_color(int r, int g, int b, int a) { + if (!g_surface) + return; + using Fn = void (*)(void *, int, int, int, int); + vfunc(g_surface, SURF_DrawSetTextColor)(g_surface, r, g, b, a); +} + +void overlay_text_pos(int x, int y) { + if (!g_surface) + return; + using Fn = void (*)(void *, int, int); + vfunc(g_surface, SURF_DrawSetTextPos)(g_surface, x, y); +} + +void overlay_print_text(const wchar_t *text, int count, int draw_type) { + if (!g_surface || !text || count <= 0) + return; + using Fn = void (*)(void *, const wchar_t *, int, int); + vfunc(g_surface, SURF_DrawPrintText)(g_surface, text, count, draw_type); +} + +HFont overlay_create_font() { + if (!g_surface) + return 0; + using Fn = HFont (*)(void *); + return vfunc(g_surface, SURF_CreateFont)(g_surface); +} + +bool overlay_add_glyph_set(HFont f, const char *name, int tall, int weight, + int blur, int scanlines, int flags, int range_min, + int range_max) { + if (!g_surface || !name) + return false; + using Fn = bool (*)(void *, HFont, const char *, int, int, int, int, int, int, + int); + return vfunc(g_surface, SURF_AddGlyphSetToFont)( + g_surface, f, name, tall, weight, blur, scanlines, flags, range_min, + range_max); +} + +void overlay_screen_size(int &w, int &h) { + if (!g_surface) + return; + using Fn = void (*)(void *, int &, int &); + vfunc(g_surface, SURF_GetScreenSize)(g_surface, w, h); +} + +void overlay_text_size(HFont f, const wchar_t *text, int &w, int &h) { + if (!g_surface || !text) + return; + using Fn = void (*)(void *, HFont, const wchar_t *, int &, int &); + vfunc(g_surface, SURF_GetTextSize)(g_surface, f, text, w, h); +} + +int overlay_embedded_panel() { + if (!g_surface) + return 0; + using Fn = int (*)(void *); + return vfunc(g_surface, SURF_GetEmbeddedPanel)(g_surface); +} + +void overlay_push_make_current(int panel, bool use_insets) { + if (!g_surface) + return; + using Fn = void (*)(void *, int, bool); + vfunc(g_surface, SURF_PushMakeCurrent)(g_surface, panel, use_insets); +} + +void overlay_pop_make_current(int panel) { + if (!g_surface) + return; + using Fn = void (*)(void *, int); + vfunc(g_surface, SURF_PopMakeCurrent)(g_surface, panel); +} -- cgit v1.2.3