commit 61bf5ce59aa7397b021d2f6f30289b09c1f3c2cb
parent c67705e116fd2a0822c15b284feede3576ea4269
Author: SomberNight <somber.night@protonmail.com>
Date: Wed, 10 Jul 2019 23:44:51 +0200
windows build: calculate COFF checksum ourselves
closes #5504
Diffstat:
2 files changed, 43 insertions(+), 21 deletions(-)
diff --git a/contrib/build-wine/build-electrum-git.sh b/contrib/build-wine/build-electrum-git.sh
@@ -73,4 +73,46 @@ cd dist
mv electrum-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
+)
+
sha256sum dist/electrum*.exe
diff --git a/contrib/build-wine/unsign.sh b/contrib/build-wine/unsign.sh
@@ -24,28 +24,8 @@ for mine in $(ls dist/*.exe); do
echo "Downloading https://download.electrum.org/$version/$f"
wget -q https://download.electrum.org/$version/$f -O signed/$f
out="signed/stripped/$f"
- size=$( wc -c < $mine )
- # Step 1: Remove PE signature from signed binary
+ # Remove PE signature from signed binary
osslsigncode remove-signature -in signed/$f -out $out > /dev/null 2>&1
- # Step 2: Remove checksum and padding from signed binary
- python3 <<EOF
-pe_file = "$out"
-size= $size
-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
-for b in range(4):
- binary[checksum_offset + b] = 0
-l = len(binary)
-n = l - size
-if n > 0:
- if binary[-n:] != bytearray(n):
- print('expecting failure for', str(pe_file))
- binary = binary[:size]
-with open(pe_file, "wb") as f:
- f.write(binary)
-EOF
chmod +x $out
if cmp -s $out $mine; then
echo "Success: $f"