Skip to content

Commit 61bf5ce

Browse files
committed
windows build: calculate COFF checksum ourselves
closes #5504
1 parent c67705e commit 61bf5ce

File tree

2 files changed

+43
-21
lines changed

2 files changed

+43
-21
lines changed

contrib/build-wine/build-electrum-git.sh

+42
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,46 @@ cd dist
7373
mv electrum-setup.exe $NAME_ROOT-$VERSION-setup.exe
7474
cd ..
7575

76+
info "Padding binaries to 8-byte boundaries, and fixing COFF image checksum in PE header"
77+
# note: 8-byte boundary padding is what osslsigncode uses:
78+
# https://github.com/mtrojnar/osslsigncode/blob/6c8ec4427a0f27c145973450def818e35d4436f6/osslsigncode.c#L3047
79+
(
80+
cd dist
81+
for binary_file in ./*.exe; do
82+
info ">> fixing $binary_file..."
83+
# code based on https://github.com/erocarrera/pefile/blob/bbf28920a71248ed5c656c81e119779c131d9bd4/pefile.py#L5877
84+
python3 <<EOF
85+
pe_file = "$binary_file"
86+
with open(pe_file, "rb") as f:
87+
binary = bytearray(f.read())
88+
pe_offset = int.from_bytes(binary[0x3c:0x3c+4], byteorder="little")
89+
checksum_offset = pe_offset + 88
90+
checksum = 0
91+
92+
# Pad data to 8-byte boundary.
93+
remainder = len(binary) % 8
94+
binary += bytes(8 - remainder)
95+
96+
for i in range(len(binary) // 4):
97+
if i == checksum_offset // 4: # Skip the checksum field
98+
continue
99+
dword = int.from_bytes(binary[i*4:i*4+4], byteorder="little")
100+
checksum = (checksum & 0xffffffff) + dword + (checksum >> 32)
101+
if checksum > 2 ** 32:
102+
checksum = (checksum & 0xffffffff) + (checksum >> 32)
103+
104+
checksum = (checksum & 0xffff) + (checksum >> 16)
105+
checksum = (checksum) + (checksum >> 16)
106+
checksum = checksum & 0xffff
107+
checksum += len(binary)
108+
109+
# Set the checksum
110+
binary[checksum_offset : checksum_offset + 4] = int.to_bytes(checksum, byteorder="little", length=4)
111+
112+
with open(pe_file, "wb") as f:
113+
f.write(binary)
114+
EOF
115+
done
116+
)
117+
76118
sha256sum dist/electrum*.exe

contrib/build-wine/unsign.sh

+1-21
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,8 @@ for mine in $(ls dist/*.exe); do
2424
echo "Downloading https://download.electrum.org/$version/$f"
2525
wget -q https://download.electrum.org/$version/$f -O signed/$f
2626
out="signed/stripped/$f"
27-
size=$( wc -c < $mine )
28-
# Step 1: Remove PE signature from signed binary
27+
# Remove PE signature from signed binary
2928
osslsigncode remove-signature -in signed/$f -out $out > /dev/null 2>&1
30-
# Step 2: Remove checksum and padding from signed binary
31-
python3 <<EOF
32-
pe_file = "$out"
33-
size= $size
34-
with open(pe_file, "rb") as f:
35-
binary = bytearray(f.read())
36-
pe_offset = int.from_bytes(binary[0x3c:0x3c+4], byteorder="little")
37-
checksum_offset = pe_offset + 88
38-
for b in range(4):
39-
binary[checksum_offset + b] = 0
40-
l = len(binary)
41-
n = l - size
42-
if n > 0:
43-
if binary[-n:] != bytearray(n):
44-
print('expecting failure for', str(pe_file))
45-
binary = binary[:size]
46-
with open(pe_file, "wb") as f:
47-
f.write(binary)
48-
EOF
4929
chmod +x $out
5030
if cmp -s $out $mine; then
5131
echo "Success: $f"

0 commit comments

Comments
 (0)