217 lines
5.3 KiB
Bash
Executable File
217 lines
5.3 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
pid=$(pidof "hl_linux")
|
|
libpath=$(realpath "libhlcheat.so")
|
|
|
|
if [ "$pid" == "" ]; then
|
|
echo "inject-debug.sh: process not running."
|
|
exit 1
|
|
fi
|
|
|
|
show_help() {
|
|
echo "Usage: $0 [OPTIONS]"
|
|
echo "Options:"
|
|
echo " --help Show this help message"
|
|
echo " --unload Debug the unload process interactively"
|
|
echo " --inject Debug the injection process interactively"
|
|
echo ""
|
|
echo "Common GDB commands to use during debugging:"
|
|
echo " bt Show backtrace"
|
|
echo " info locals Show local variables"
|
|
echo " n Step over (next line)"
|
|
echo " s Step into function"
|
|
echo " c Continue execution"
|
|
echo " p expression Print value of expression"
|
|
echo " finish Run until current function returns"
|
|
echo ""
|
|
echo "Without options, the script will inject the cheat normally."
|
|
exit 0
|
|
}
|
|
|
|
UNLOAD_MODE=0
|
|
INJECT_MODE=0
|
|
|
|
for arg in "$@"; do
|
|
case $arg in
|
|
--help)
|
|
show_help
|
|
;;
|
|
--unload)
|
|
UNLOAD_MODE=1
|
|
;;
|
|
--inject)
|
|
INJECT_MODE=1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
cat > /tmp/gdbinit-goldsrc << EOF
|
|
set confirm off
|
|
set pagination off
|
|
set print pretty on
|
|
|
|
define hook-stop
|
|
echo \nBREAKPOINT HIT\n
|
|
bt
|
|
echo \nLOCAL VARIABLES:\n
|
|
info locals
|
|
echo \nSTACK FRAME:\n
|
|
info frame
|
|
echo \nCommands: n (next), s (step), c (continue), bt (backtrace), finish (run until function returns)\n
|
|
end
|
|
|
|
EOF
|
|
|
|
if [ $UNLOAD_MODE -eq 1 ]; then
|
|
echo "Starting interactive unload debugging session..."
|
|
|
|
cat >> /tmp/gdbinit-goldsrc << EOF
|
|
# Set up functions to help with dlopen/dlclose
|
|
set \$dlopen = (void* (*)(char*, int))dlopen
|
|
set \$dlclose = (int (*)(void*))dlclose
|
|
set \$dlerror = (char* (*)(void))dlerror
|
|
|
|
# Set breakpoints on critical functions
|
|
break self_unload
|
|
break unload
|
|
break safe_unload_with_debug
|
|
break UNINJECT_CommandHandler
|
|
break hooks_restore
|
|
break globals_restore
|
|
break GL_UNHOOK
|
|
|
|
# Command to manually invoke the unload from GDB
|
|
define uninject
|
|
set \$self = \$dlopen("$libpath", 6)
|
|
p \$self
|
|
call \$dlclose(\$self)
|
|
call \$dlclose(\$self)
|
|
call \$dlerror()
|
|
end
|
|
|
|
define call_uninject_cmd
|
|
call UNINJECT_CommandHandler()
|
|
end
|
|
|
|
echo \nType 'call_uninject_cmd' to execute the uninject command\n
|
|
echo Type 'uninject' to manually trigger the unload process\n
|
|
EOF
|
|
|
|
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
|
|
|
echo "Interactive unload debugging session ended."
|
|
exit 0
|
|
fi
|
|
|
|
if [ $INJECT_MODE -eq 1 ]; then
|
|
echo "Starting interactive injection debugging session..."
|
|
|
|
cat >> /tmp/gdbinit-goldsrc << EOF
|
|
# Set up functions to help with dlopen/dlclose
|
|
set \$dlopen = (void* (*)(char*, int))dlopen
|
|
set \$dlclose = (int (*)(void*))dlclose
|
|
set \$dlerror = (char* (*)(void))dlerror
|
|
|
|
# Set breakpoints on critical functions
|
|
break load
|
|
break globals_init
|
|
break cvars_init
|
|
break hooks_init
|
|
|
|
# Command to manually inject the library
|
|
define inject
|
|
call \$dlopen("$libpath", 2)
|
|
call \$dlerror()
|
|
end
|
|
|
|
echo \nType 'inject' to load the library\n
|
|
EOF
|
|
|
|
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
|
|
|
echo "Interactive injection debugging session ended."
|
|
exit 0
|
|
fi
|
|
|
|
echo "Injecting cheat..."
|
|
|
|
if grep -q "$libpath" "/proc/$pid/maps"; then
|
|
echo -e "goldsource-cheat already loaded. Reloading...\n"
|
|
|
|
cat > /tmp/gdbinit-goldsrc << EOF
|
|
set confirm off
|
|
set pagination off
|
|
set print pretty on
|
|
set \$dlopen = (void* (*)(char*, int))dlopen
|
|
set \$dlclose = (int (*)(void*))dlclose
|
|
set \$dlerror = (char* (*)(void))dlerror
|
|
|
|
# Reload library
|
|
define reload_lib
|
|
set \$self = \$dlopen("$libpath", 6)
|
|
call \$dlclose(\$self)
|
|
call \$dlclose(\$self)
|
|
call \$dlopen("$libpath", 2)
|
|
call \$dlerror()
|
|
echo "\nReload complete. Library has been reloaded.\n"
|
|
echo "You can now debug interactively.\n"
|
|
echo "Type 'continue' or 'c' to let the game run normally.\n"
|
|
echo "Type 'call_uninject_cmd' to trigger the uninject command.\n"
|
|
end
|
|
|
|
# Command to manually trigger uninject
|
|
define call_uninject_cmd
|
|
call UNINJECT_CommandHandler()
|
|
end
|
|
|
|
# Execute reload automatically
|
|
reload_lib
|
|
|
|
# Break on uninject command
|
|
break UNINJECT_CommandHandler
|
|
break safe_unload_with_debug
|
|
break self_unload
|
|
|
|
echo "\nType 'help' for GDB commands or 'continue' to let the game run.\n"
|
|
EOF
|
|
|
|
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
|
else
|
|
cat > /tmp/gdbinit-goldsrc << EOF
|
|
set confirm off
|
|
set pagination off
|
|
set print pretty on
|
|
set \$dlopen = (void* (*)(char*, int))dlopen
|
|
set \$dlclose = (int (*)(void*))dlclose
|
|
set \$dlerror = (char* (*)(void))dlerror
|
|
|
|
# Initial library load
|
|
define load_lib
|
|
call \$dlopen("$libpath", 2)
|
|
call \$dlerror()
|
|
echo "\nInjection complete. Library has been loaded.\n"
|
|
echo "You can now debug interactively.\n"
|
|
echo "Type 'continue' or 'c' to let the game run normally.\n"
|
|
echo "Type 'call_uninject_cmd' to trigger the uninject command.\n"
|
|
end
|
|
|
|
# Command to manually trigger uninject
|
|
define call_uninject_cmd
|
|
call UNINJECT_CommandHandler()
|
|
end
|
|
|
|
# Execute load automatically
|
|
load_lib
|
|
|
|
# Break on uninject command
|
|
break UNINJECT_CommandHandler
|
|
break safe_unload_with_debug
|
|
break self_unload
|
|
|
|
echo "\nType 'help' for GDB commands or 'continue' to let the game run.\n"
|
|
EOF
|
|
|
|
sudo gdb -x /tmp/gdbinit-goldsrc -p $pid
|
|
fi
|
|
|
|
echo -e "\nDebug session ended." |