# 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 $@