snippets/bash/patch_binary.sh

42 lines
1.3 KiB
Bash

# patch_binary(target file, asm payload, destination dynamic symbol, offset)
# The dynamic symbol may also be a hex address.
# offset must be in decimal representation.
function patch_binary() {
file="$1"
payload="$2"
sym="$3"
offset="$4"
payload_file="`mktemp`"
echo "# Patching file $file @ $sym"
echo " Generating payload..."
echo "$payload" | rasm2 -a x86 -b64 -B -f - > "$payload_file"
if [[ $sym = 0x* ]]; then
addr="`echo \"$sym\" | sed \"s/^0x//\"`"
else
echo " Preparing patch of dynamic location $sym + $offset"
addr=`nm -D "$file" 2>/dev/null | grep "$sym" | head -n1 | sed 's/ .*//'`
if [ "$addr" == "" ]; then
echo " Symbol not found. Skipping."
return 1;
fi
echo " Found symbol at $addr"
fi
load=`readelf -l "$file" | grep LOAD | head -n1 | sed 's/.* 0x//'`
load=`echo $((16#$load))`
addr=`echo $((16#$addr))`
addr=`echo $(($addr + $offset))` # This is also the address shown by r2
paddr=`echo $(($addr - $load))` # The offset is added when copying to RAM; we need to subtract that
printf " Patching dynamic address 0x%x\n" "$addr"
printf " Load offset is 0x%x\n" "$load"
printf " Patching $file at physical offset 0x%x...\n" "$paddr"
dd if="$payload_file" of="$file" obs=1 seek="$paddr" conv=notrunc 2>&1 | sed 's/^/ /'
rm "$payload_file"
echo " Done."
return 0
}
patch_binary $@