Skip to content

Instantly share code, notes, and snippets.

@rand-tech
Last active September 23, 2023 18:39
Show Gist options
  • Select an option

  • Save rand-tech/122d974b0139f67ed84ca0cdf9a89e70 to your computer and use it in GitHub Desktop.

Select an option

Save rand-tech/122d974b0139f67ed84ca0cdf9a89e70 to your computer and use it in GitHub Desktop.
#!/usr/bin/env zsh
emulate -L zsh
set -eau
# usage:
# [INSTALL_DIR=/path/to/dir] [GDBINIT_PATH=/path/to/.gdbinit] [HEADLESS=1] ./lndbg.sh
readonly VERSION="0.1.0"
readonly NAME="ldgdb"
readonly ZSHRC_PATH=${ZSHRC_PATH:-"${ZDOTDIR:-$HOME}/.zshrc"}
HEADLESS=${HEADLESS:-0}
SCRIPT_TARGET_PATH="${SCRIPT_TARGET_PATH:-$ZSHRC_PATH}"
INSTALL_DIR=${INSTALL_DIR:-"$HOME/tools/gdb"}
GDBINIT_PATH=${GDBINIT_PATH:-"$HOME/.config/gdb/gdbinit"}
GDBINIT_TOOL_PATH=${GDBINIT_TOOL_PATH:-"${GDBINIT_PATH}-tools"}
# name = url | path | desc
typeset -A tools=(
["peda"]="https://github.com/longld/peda.git|peda.py|Initializes the PEDA (Python Exploit Development Assistant for GDB) framework"
["peda-intel"]="https://github.com/alset0326/peda-arm.git|peda-intel.py|Initializes the PEDA (Python Exploit Development Assistant for GDB) framework for INTEL."
["peda-arm"]="https://github.com/alset0326/peda-arm.git|peda-arm.py|Initializes the PEDA (Python Exploit Development Assistant for GDB) framework for ARM."
["pwndbg"]="https://github.com/pwndbg/pwndbg.git|gdbinit.py|Initializes PwnDBG"
["gef"]="https://github.com/hugsy/gef.git|gef.py|Initializes GEF (GDB Enhanced Features)"
["bef"]="https://github.com/bata24/gef.git|gef.py|Initializes bata GEF (bata GDB Enhanced Features)"
["splitmind"]="https://github.com/jerdna-regeiz/splitmind.git|gdbinit.py|Split information output of pwndbg output"
["GEP"]="https://github.com/rand-tech/GEP.git|gdbinit-gep.py|GDB command prompt with fzf history search and more!"
)
tool_info() {
local name=$1
echo "${(@s:|:)tools[$name]}" # split string by |
}
update() {
local reponame=$1
git stash save --keep-index --include-untracked
}
download() {
local repo_name="$1"
local repo_url="$2"
local install_path="${INSTALL_DIR}/${repo_name}"
set -x
if [[ ! -d "${install_path}" ]]; then
git clone --depth 1 "${repo_url}" "${install_path}" || {
echo "[-] git clone failed"
return 1
}
else
# Autostash local changes and pull latest with rebase
git -C "${install_path}" pull --rebase --autostash || {
echo "[-] git pull of $repo_name repo failed"
echo " Conflicting files:"
git diff -C "${install_path}" --name-only --diff-filter=U
return 1
}
fi
set +x
}
__shell_template() {
local name=$1
printf "%-15s %s\n" "gdb-$name()" "{ gdb -q -ex init-$name \"\$@\" }"
}
__gdbinit_template() {
local name=$1
local ipath=$2
local desc=$3
echo "define init-$name"
echo " source $INSTALL_DIR/$name/$ipath"
echo "end"
echo "document init-$name"
echo " ${desc}"
echo "end"
}
setup() {
# download and install each gdb tools
for name in "${(@k)tools}"; do
details=($(tool_info $name))
repo_url=$details[1]
ipath=$details[2]
desc=$details[3,-1]
printf "%-72s\n" | tr " " "-"
echo " Name: $name"
echo " URL: $repo_url"
echo " File: $ipath"
echo " Desc: $desc"
download $name $repo_url
# check if the exact same command exist to avoid duplication
local gdbcmd="$(__gdbinit_template $name $ipath $desc)"
if cat $GDBINIT_TOOL_PATH| grep -Fq -f <(echo "${gdbcmd}"|grep source); then
echo "[*] $name is already installed in $GDBINIT_TOOL_PATH. Skipping..."
else
echo "" >> $GDBINIT_TOOL_PATH
echo "$gdbcmd" >> $GDBINIT_TOOL_PATH
fi
__shell_template $name >> $TMP_ZSH_SCRIPT
done
}
premain(){
(( $+commands[gdb] )) || {
echo "[-] gdb not found! Aborting..."
exit 1
}
(( $+commands[git] )) || {
echo "[-] git not found! Aborting..."
exit 1
}
}
postmain(){
echo '\n'
echo '[+] Modified files:'
echo "$GDBINIT_PATH"
echo "$GDBINIT_TOOL_PATH"
if [[ ${UPDATE_ENV:-0} -eq 1 ]]; then
# "install to" SCRIPT_TARGET_PATH(default: ~/.zshrc)
if ! grep -qE "^# BEGIN: ${NAME} v${VERSION}" "${SCRIPT_TARGET_PATH}"; then;
echo "[*] ${NAME} v${VERSION} is already installed in ${SCRIPT_TARGET_PATH}"
else
echo "# BEGIN: ${NAME} v${VERSION}" >> ${SCRIPT_TARGET_PATH}
echo "# ($(date --iso-8601))" >> ${SCRIPT_TARGET_PATH}
echo "# see $INSTALL_DIR to check the source code" >> ${SCRIPT_TARGET_PATH}
echo "# see $GDBINIT_TOOL_PATH to check the commands" >> ${SCRIPT_TARGET_PATH}
cat $TMP_ZSH_SCRIPT >> ${SCRIPT_TARGET_PATH}
echo "# END: ${NAME} v${VERSION}" >> ${SCRIPT_TARGET_PATH}
echo "[!] \`source ${SCRIPT_TARGET_PATH}\` to install the environmental variables"
fi
else
echo '[+] Functions:'
cat $TMP_ZSH_SCRIPT >&2
echo "[!] To install ${SCRIPT_TARGET_PATH} automatically to ${SCRIPT_TARGET_PATH}, run this script with \`UPDATE_ENV=1\` flag."
fi
}
main() {
premain
TMP_ZSH_SCRIPT=$(mktemp)
trap 'rm -f "$TMP_ZSH_SCRIPT"' EXIT
echo "[+] Using install directory: $INSTALL_DIR"
mkdir -p "${INSTALL_DIR}"
mkdir -p "$(dirname ${GDBINIT_PATH})"
setup
: >> $GDBINIT_PATH
if ! grep -qE "^# BEGIN: ldgdb v${VERSION}" "$GDBINIT_PATH"; then;
cat <<EOF >> $GDBINIT_PATH
# BEGIN: ldgdb v${VERSION}
# ($(date --iso-8601))
source $GDBINIT_TOOL_PATH
set startup-quietly on
set disable-randomization off
set history save on
set history remove-duplicates unlimited
set history filename \$HOME/.gdb_history
# END: ldgdb v${VERSION}
EOF
fi
postmain
}
main
__post_gep(){
echo "[+] Installing dependencies for GEP"
local toolname={$1:-GEP}
(( $+commands[gdb] )) || { echo "gdb not found" >&2; exit 1; }
gdbpy() { gdb -batch -q --nx -ex "pi $*" }
py_path=$( gdbpy 'import sys; print(sys.executable)' )
[[ "$OSTYPE" != "darwin"* ]] && py_path="${py_path}$(gdbpy 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
# Create venv, install prompt_toolkit
venv="$INSTALL_DIR/$toolname/.venv"
[[ ! -d "$venv" ]] && {
"$py_path" -m venv "$venv"
}
"$venv/bin/pip" install --no-cache-dir --upgrade -q pip prompt_toolkit
}
# if GEP is in the tools, then install it
[[ -n "${tools[GEP]}" ]] && __post_gep GEP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment