Skip to content

Commit

Permalink
Building: Windows: Set EXE checksums (pyinstaller#5579).
Browse files Browse the repository at this point in the history
Windows executables contain an optional checksum to protect
against corruption. It turns out that several of antiviral programs
raise false positives if this checksum is missing or wrong.
Setting this checksum appeases McAfee and inconsistently fixes
MS Defender which are probably the most common (and also dumbest)
AVs for Windows.
  • Loading branch information
bwoodsend committed Feb 22, 2021
1 parent 58db420 commit c0d4e3f
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 0 deletions.
4 changes: 4 additions & 0 deletions PyInstaller/building/api.py
Expand Up @@ -640,6 +640,10 @@ def assemble(self):
logger.info("Fixing EXE for code signing %s", self.name)
import PyInstaller.utils.osx as osxutils
osxutils.fix_exe_for_code_signing(self.name)
if is_win:
# Set checksum to appease antiviral software.
from PyInstaller.utils.win32.winutils import set_exe_checksum
set_exe_checksum(self.name)

os.chmod(self.name, 0o755)
# get mtime for storing into the guts
Expand Down
14 changes: 14 additions & 0 deletions PyInstaller/utils/win32/winutils.py
Expand Up @@ -155,3 +155,17 @@ def convert_dll_name_to_str(dll_name):
return str(dll_name, encoding='UTF-8')
else:
return dll_name


def set_exe_checksum(exe_path):
"""Set executable's checksum in its metadata.
This optional checksum is supposed to protect the executable against
corruption but some anti-viral software have taken to flagging anything
without it set correctly as malware. See issue #5579.
"""
import pefile
pe = pefile.PE(exe_path)
pe.OPTIONAL_HEADER.CheckSum = pe.generate_checksum()
pe.close()
pe.write(exe_path)
2 changes: 2 additions & 0 deletions bootloader/wscript
Expand Up @@ -311,6 +311,8 @@ def set_arch_flags(ctx):
ctx.env.append_value('CFLAGS', '/D_CRT_SECURE_NO_WARNINGS')
# We use SEH exceptions in winmain.c; make sure they are activated.
ctx.env.append_value('CFLAGS', '/EHa')
# Set the PE checksum on resulting binary
ctx.env.append_value('LINKFLAGS', '/RELEASE')

# Ensure proper architecture flags on Mac OS X.
elif ctx.env.DEST_OS == 'darwin':
Expand Down
1 change: 1 addition & 0 deletions news/5579.feature.rst
@@ -0,0 +1 @@
Windows: Set EXE checksums. Reduces false-positive detection from antiviral software.
12 changes: 12 additions & 0 deletions tests/functional/test_basic.py
Expand Up @@ -585,3 +585,15 @@ def test_several_scripts2(pyi_builder_spec):
Verify each script has it's own global vars (basic test).
"""
pyi_builder_spec.test_spec('several-scripts2.spec')


@pytest.mark.win32
def test_pe_checksum(pyi_builder):
import pefile

pyi_builder.test_source("print('hello')")
exes = pyi_builder._find_executables('test_source')
assert exes
for exe in exes:
pe = pefile.PE(exe)
assert pe.verify_checksum()

0 comments on commit c0d4e3f

Please sign in to comment.