diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..980e2a3 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "chat.tools.terminal.autoApprove": { + "cargo check": true + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 73881ab..f96d154 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -290,9 +290,7 @@ unsafe extern "C" fn teaminfo(dummy: usize, name: *const c_char, size: i32, buf: if i < PLAYER_TEAM.len() { set_player_team(i, &team); } - if let Some(orig) = ORIG_TEAMINFO { - orig(dummy, name, size, buf) - } else { 1 } + ORIG_TEAMINFO.unwrap()(dummy, name, size, buf) } unsafe extern "C" fn health_hook(dummy: usize, name: *const c_char, size: i32, buf: *mut c_void) -> i32 { @@ -307,9 +305,7 @@ unsafe extern "C" fn health_hook(dummy: usize, name: *const c_char, size: i32, b } } } - if let Some(orig) = ORIG_HEALTH { - orig(dummy, name, size, buf) - } else { 1 } + ORIG_HEALTH.unwrap()(dummy, name, size, buf) } unsafe extern "C" fn scoreattrib_hook(dummy: usize, name: *const c_char, size: i32, buf: *mut c_void) -> i32 { @@ -319,9 +315,7 @@ unsafe extern "C" fn scoreattrib_hook(dummy: usize, name: *const c_char, size: i if idx < PLAYER_DATA.len() { PLAYER_DATA[idx].is_alive = (flags & 1) == 0; } - if let Some(orig) = ORIG_SCOREATTRIB { - orig(dummy, name, size, buf) - } else { 1 } + ORIG_SCOREATTRIB.unwrap()(dummy, name, size, buf) } unsafe extern "C" fn radar_hook(dummy: usize, name: *const c_char, size: i32, buf: *mut c_void) -> i32 { @@ -333,20 +327,18 @@ unsafe extern "C" fn radar_hook(dummy: usize, name: *const c_char, size: i32, bu if idx < PLAYER_DATA.len() { PLAYER_DATA[idx].pos = Vector { x, y, z }; } - if let Some(orig) = ORIG_RADAR { - orig(dummy, name, size, buf) - } else { 1 } + ORIG_RADAR.unwrap()(dummy, name, size, buf) } unsafe extern "C" fn resethud_hook(dummy: usize, name: *const c_char, size: i32, buf: *mut c_void) -> i32 { for i in 0..PLAYER_DATA.len() { PLAYER_DATA[i].health = 0; PLAYER_DATA[i].is_alive = false; + // Keep pos as last known? Or clear it? + // Better clear it to avoid "ghost" ESP. PLAYER_DATA[i].pos = Vector { x: 0.0, y: 0.0, z: 0.0 }; } - if let Some(orig) = ORIG_RESETHUD { - orig(dummy, name, size, buf) - } else { 1 } + ORIG_RESETHUD.unwrap()(dummy, name, size, buf) } fn log(msg: &str) { if let Ok(mut file) = OpenOptions::new().create(true).append(true).open("/tmp/basturma.log") { @@ -1301,9 +1293,11 @@ fn init() { let clientusermsgs_sym = dlsym(hw, b"clientusermsgs\0".as_ptr() as *const c_char); if !clientusermsgs_sym.is_null() { CLIENT_USERMSGS = clientusermsgs_sym as *mut UserMsg; - log("INFO: clientusermsgs found via dlsym"); } else { - log("WARN: clientusermsgs not found, message hooks disabled"); + // Try to extract from CL_ShutDownUsrMessages signature: + // mov clientusermsgs, eax (or similar) + // This is very architecture/build dependent. + CLIENT_USERMSGS = *( (shutdownusermsgs as *mut u8).offset(5) as *mut *mut UserMsg ); } } @@ -1400,7 +1394,7 @@ extern "C" fn hooked_hudredraw(dummy: usize, time: f32, intermission: i32) -> i3 if let Some(orig) = ORIG_CLIENT { let ret = (orig.hudredraw)(dummy, time, intermission); // Render overlay after original HUD. - overlay_render(SETTINGS.show_menu); + // overlay_render(SETTINGS.show_menu); ret } else { 0 } } diff --git a/unload.sh b/unload.sh new file mode 100755 index 0000000..0841239 --- /dev/null +++ b/unload.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +# Попытка выгрузить библиотеку, загруженную через gdb/dlopen в процессе hl_linux. +# Для этого ищем путь модуля в /proc//maps и вызываем dlclose через gdb. + +GAME_PID=$(pidof hl_linux | awk '{print $1}') +if [ -z "$GAME_PID" ]; then + echo "[-] Ошибка: процесс hl_linux не запущен." + exit 1 +fi + +LIB_PATH=$(grep -Eo '/tmp/libahc_rs_[^ ]+\.so|.*/libahc_rs\.so' /proc/$GAME_PID/maps | head -n 1) +if [ -z "$LIB_PATH" ]; then + echo "[-] Не удалось найти загруженную библиотеку libahc_rs в процессе $GAME_PID." + echo " Убедитесь, что вы сначала загрузили библиотеку через load.sh." + exit 1 +fi + +GDB_CMD=$(mktemp) +cat > "$GDB_CMD" <<'EOF' +attach $GAME_PID +set $h = (void*)dlopen("$LIB_PATH", 4) +if $h + call (int)dlclose($h) +end +detach +quit +EOF + +sudo gdb -batch -x "$GDB_CMD" +RESULT=$? +rm -f "$GDB_CMD" + +if [ $RESULT -eq 0 ]; then + echo "[+] Выгрузка библиотеки завершена." +else + echo "[-] Ошибка при выгрузке. Проверьте вывод gdb и права sudo." +fi