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."  |