Skip to content

Commit

Permalink
windows build: calculate COFF checksum ourselves
Browse files Browse the repository at this point in the history
  • Loading branch information
dalijolijo committed Aug 6, 2019
1 parent 7e977e5 commit 22de126
Showing 1 changed file with 47 additions and 13 deletions.
60 changes: 47 additions & 13 deletions contrib/build-wine/build-electrum-git.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ PYTHON="wine $PYHOME/python.exe -OO -B"
# Let's begin!
set -e

mkdir -p tmp
cd tmp
here="$(dirname "$(readlink -e "$0")")"

pushd $WINEPREFIX/drive_c/electrum
. "$CONTRIB"/build_tools_util.sh

# Load electrum-locale for this release
git submodule init
git submodule update
pushd $WINEPREFIX/drive_c/electrum

VERSION=`git describe --tags --dirty --always`
echo "Last commit: $VERSION"
info "Last commit: $VERSION"

# Load electrum-locale for this release
git submodule update --init

pushd ./contrib/deterministic-build/electrum-locale
if ! which msgfmt > /dev/null 2>&1; then
Expand All @@ -41,24 +41,21 @@ popd
find -exec touch -d '2000-11-11T11:11:11+00:00' {} +
popd

cp -f ../../../LICENSE .

# Install frozen dependencies
$PYTHON -m pip install -r ../../deterministic-build/requirements.txt
$PYTHON -m pip install --no-warn-script-location -r "$CONTRIB"/deterministic-build/requirements.txt

$PYTHON -m pip install -r ../../deterministic-build/requirements-hw.txt
$PYTHON -m pip install --no-warn-script-location -r "$CONTRIB"/deterministic-build/requirements-hw.txt

pushd $WINEPREFIX/drive_c/electrum
# see https://github.com/pypa/pip/issues/2195 -- pip makes a copy of the entire directory
info "Pip installing Electrum. This might take a long time if the project folder is large."
$PYTHON -m pip install --no-warn-script-location .
popd

cd ..

rm -rf dist/

# build standalone and portable versions
info "Running pyinstaller..."
wine "$PYHOME/scripts/pyinstaller.exe" --noconfirm --ascii --clean --name $NAME_ROOT-$VERSION -w deterministic.spec

# set timestamps in dist, in order to make the installer reproducible
Expand All @@ -74,5 +71,42 @@ cd dist
mv $NAME_ROOT-setup.exe $NAME_ROOT-$VERSION-setup.exe
cd ..

info "Padding binaries to 8-byte boundaries, and fixing COFF image checksum in PE header"
# note: 8-byte boundary padding is what osslsigncode uses:
# https://github.com/mtrojnar/osslsigncode/blob/6c8ec4427a0f27c145973450def818e35d4436f6/osslsigncode.c#L3047
(
cd dist
for binary_file in ./*.exe; do
info ">> fixing $binary_file..."
# code based on https://github.com/erocarrera/pefile/blob/bbf28920a71248ed5c656c81e119779c131d9bd4/pefile.py#L5877
python3 <<EOF
pe_file = "$binary_file"
with open(pe_file, "rb") as f:
binary = bytearray(f.read())
pe_offset = int.from_bytes(binary[0x3c:0x3c+4], byteorder="little")
checksum_offset = pe_offset + 88
checksum = 0
# Pad data to 8-byte boundary.
remainder = len(binary) % 8
binary += bytes(8 - remainder)
for i in range(len(binary) // 4):
if i == checksum_offset // 4: # Skip the checksum field
continue
dword = int.from_bytes(binary[i*4:i*4+4], byteorder="little")
checksum = (checksum & 0xffffffff) + dword + (checksum >> 32)
if checksum > 2 ** 32:
checksum = (checksum & 0xffffffff) + (checksum >> 32)
checksum = (checksum & 0xffff) + (checksum >> 16)
checksum = (checksum) + (checksum >> 16)
checksum = checksum & 0xffff
checksum += len(binary)
# Set the checksum
binary[checksum_offset : checksum_offset + 4] = int.to_bytes(checksum, byteorder="little", length=4)
with open(pe_file, "wb") as f:
f.write(binary)
EOF
done
)

echo "Done."
sha256sum dist/electrum*exe

0 comments on commit 22de126

Please sign in to comment.