Skip to content

Instantly share code, notes, and snippets.

@sonic2kk
Created October 24, 2023 20:25
Show Gist options
  • Save sonic2kk/9bf61220ce6650db6cc3eddf5a7bc493 to your computer and use it in GitHub Desktop.
Save sonic2kk/9bf61220ce6650db6cc3eddf5a7bc493 to your computer and use it in GitHub Desktop.
Parse some Steam Shortcut information from shortcuts.vdf using Bash.
#!/usr/bin/env bash
# AppID is a special case I haven't made generic yet since it doesn't have an end byte the same way other fields do afaik
# Adapted from my gist: https://gist.github.com/sonic2kk/4a3383b401931a171a4addc29bdf903f
function get_shortcut_appid {
# Magic that represents 'appid' column
magic_appid="617070696400"
shortcut_hex="$1"
function convert_aid {
hex_aid="$1"
little_endian="$( echo "$hex_aid" | tac -rs .. | tr -d '\n' )"
echo "$((16#${little_endian}))"
}
# Get first 8 characters after magic and convert it from hex to 32bit unsigned integer
found_aid="$( printf "${shortcut_hex}" | grep -oP "${magic_appid}\K.{8}" )"
convert_aid "${found_aid}"
}
# Get value in shortcut entry hex between start and end patterns, with null byte removed, converted to plaintext
function get_shortcut_column_value {
shortcut_hex="$1"
shortcut_pattern_start="$2"
shortcut_pattern_end="0001"
printf "${shortcut_hex}" | grep -oP "${shortcut_pattern_start}\K.*?(?=${shortcut_pattern_end})" | xxd -r -p | tr -d '\0'
}
magic_appname_start="(014170704e616d6500|6170706e616d65)"
magic_exepath_start="000145786500"
# shortcuts.vdf starts with different bytes than all other shortcuts, this magic basically translates to: '00shortcuts000030000002',
# where '0000' is spacing, '30' represents the shortcut index (1), '00' is more spacing, and '0002' is the start of the next column
magic_shortcut_filestart="0073686f7274637574730000300002"
magic_shortcut_blockstart="00080800.*?0002" # How all other shortcut blocks start, with 00080800, then the shortcut number (could be 31,32,even higher for more shortcuts, so we don't care about the value between), then 0002 for the next block start
magic_shortcut_blockend="000808" # How all shortcuts end
# Paste in your Steam UserID
steam_userid=""
shortcuts_vdf="$HOME/.steam/root/userdata/${steam_userid}/config/shortcuts.vdf"
# Get all shortcut blocks from file as hex, then translate them to plaintext
mapfile -t steam_shortcuts_hex < <( xxd -p -c 0 "$shortcuts_vdf" | grep -oP "(${magic_shortcut_filestart}|${magic_shortcut_blockstart})\K.*?(?=${magic_shortcut_blockend})" )
for shortcut in "${steam_shortcuts_hex[@]}"; do
# This could be extended for whatever fields you want to get, this will just return AppName, appid, and Exe for illustrative purposes.
shortcut_appid="$( get_shortcut_appid "${shortcut}" )"
shortcut_name="$( get_shortcut_column_value "${shortcut}" "${magic_appname_start}" )"
shortcut_exepath="$( get_shortcut_column_value "${shortcut}" "${magic_exepath_start}" )"
echo "${shortcut_name} (${shortcut_appid}) -> ${shortcut_exepath}"
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment