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 fcc87d5
Show file tree
Hide file tree
Showing 4 changed files with 31 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)
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 fcc87d5

Please sign in to comment.