From 36afed2d2281ef485fb3be5587b12e17727f4468 Mon Sep 17 00:00:00 2001 From: William Ballenthin Date: Wed, 1 Jul 2020 17:35:18 -0600 Subject: [PATCH] pyinstaller working on linux/py2 closes #40 --- ci/hooks/hook-vivisect.py | 13 +++ ci/pyinstaller.spec | 182 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 ci/hooks/hook-vivisect.py create mode 100644 ci/pyinstaller.spec diff --git a/ci/hooks/hook-vivisect.py b/ci/hooks/hook-vivisect.py new file mode 100644 index 00000000..3714cfb0 --- /dev/null +++ b/ci/hooks/hook-vivisect.py @@ -0,0 +1,13 @@ +from PyInstaller.utils.hooks import copy_metadata + +# in order for viv-utils to use pkg_resources to fetch +# the installed version of vivisect, +# we need to instruct pyinstaller to embed this metadata. +# +# so we set the pyinstaller.spec/hookspath to reference +# the directory with this hook. +# +# this hook runs at analysis time and updates the embedded metadata. +# +# ref: https://github.com/pyinstaller/pyinstaller/issues/1713#issuecomment-162682084 +datas = copy_metadata('vivisect') diff --git a/ci/pyinstaller.spec b/ci/pyinstaller.spec new file mode 100644 index 00000000..a5e29f0a --- /dev/null +++ b/ci/pyinstaller.spec @@ -0,0 +1,182 @@ +# -*- mode: python -*- + +block_cipher = None + +a = Analysis( + ['../capa/main.py'], + pathex=['capa'], + binaries=None, + datas=[ + ('../rules', 'rules'), + ], + hiddenimports=[ + # vivisect does manual/runtime importing of its modules, + # so declare the things that could be imported here. + "pycparser", + "vivisect", + "vivisect.analysis", + "vivisect.analysis.amd64", + "vivisect.analysis.amd64", + "vivisect.analysis.amd64.emulation", + "vivisect.analysis.amd64.golang", + "vivisect.analysis.crypto", + "vivisect.analysis.crypto", + "vivisect.analysis.crypto.constants", + "vivisect.analysis.elf", + "vivisect.analysis.elf", + "vivisect.analysis.elf.elfplt", + "vivisect.analysis.elf.libc_start_main", + "vivisect.analysis.generic", + "vivisect.analysis.generic", + "vivisect.analysis.generic.codeblocks", + "vivisect.analysis.generic.emucode", + "vivisect.analysis.generic.entrypoints", + "vivisect.analysis.generic.funcentries", + "vivisect.analysis.generic.impapi", + "vivisect.analysis.generic.mkpointers", + "vivisect.analysis.generic.pointers", + "vivisect.analysis.generic.pointertables", + "vivisect.analysis.generic.relocations", + "vivisect.analysis.generic.strconst", + "vivisect.analysis.generic.switchcase", + "vivisect.analysis.generic.thunks", + "vivisect.analysis.i386", + "vivisect.analysis.i386", + "vivisect.analysis.i386.calling", + "vivisect.analysis.i386.golang", + "vivisect.analysis.i386.importcalls", + "vivisect.analysis.i386.instrhook", + "vivisect.analysis.i386.thunk_bx", + "vivisect.analysis.ms", + "vivisect.analysis.ms", + "vivisect.analysis.ms.hotpatch", + "vivisect.analysis.ms.localhints", + "vivisect.analysis.ms.msvc", + "vivisect.analysis.ms.msvcfunc", + "vivisect.analysis.ms.vftables", + "vivisect.analysis.pe", + "vivisect.impapi.posix.amd64", + "vivisect.impapi.posix.i386", + "vivisect.impapi.windows", + "vivisect.impapi.windows.amd64", + "vivisect.impapi.windows.i386", + "vivisect.parsers.blob", + "vivisect.parsers.elf", + "vivisect.parsers.ihex", + "vivisect.parsers.macho", + "vivisect.parsers.parse_pe", + "vivisect.parsers.utils", + "vivisect.storage", + "vivisect.storage.basicfile", + "vstruct.constants", + "vstruct.constants.ntstatus", + "vstruct.defs", + "vstruct.defs.arm7", + "vstruct.defs.bmp", + "vstruct.defs.dns", + "vstruct.defs.elf", + "vstruct.defs.gif", + "vstruct.defs.ihex", + "vstruct.defs.inet", + "vstruct.defs.java", + "vstruct.defs.kdcom", + "vstruct.defs.macho", + "vstruct.defs.macho.const", + "vstruct.defs.macho.fat", + "vstruct.defs.macho.loader", + "vstruct.defs.macho.stabs", + "vstruct.defs.minidump", + "vstruct.defs.pcap", + "vstruct.defs.pe", + "vstruct.defs.pptp", + "vstruct.defs.rar", + "vstruct.defs.swf", + "vstruct.defs.win32", + "vstruct.defs.windows", + "vstruct.defs.windows.win_5_1_i386", + "vstruct.defs.windows.win_5_1_i386.ntdll", + "vstruct.defs.windows.win_5_1_i386.ntoskrnl", + "vstruct.defs.windows.win_5_1_i386.win32k", + "vstruct.defs.windows.win_5_2_i386", + "vstruct.defs.windows.win_5_2_i386.ntdll", + "vstruct.defs.windows.win_5_2_i386.ntoskrnl", + "vstruct.defs.windows.win_5_2_i386.win32k", + "vstruct.defs.windows.win_6_1_amd64", + "vstruct.defs.windows.win_6_1_amd64.ntdll", + "vstruct.defs.windows.win_6_1_amd64.ntoskrnl", + "vstruct.defs.windows.win_6_1_amd64.win32k", + "vstruct.defs.windows.win_6_1_i386", + "vstruct.defs.windows.win_6_1_i386.ntdll", + "vstruct.defs.windows.win_6_1_i386.ntoskrnl", + "vstruct.defs.windows.win_6_1_i386.win32k", + "vstruct.defs.windows.win_6_1_wow64", + "vstruct.defs.windows.win_6_1_wow64.ntdll", + "vstruct.defs.windows.win_6_2_amd64", + "vstruct.defs.windows.win_6_2_amd64.ntdll", + "vstruct.defs.windows.win_6_2_amd64.ntoskrnl", + "vstruct.defs.windows.win_6_2_amd64.win32k", + "vstruct.defs.windows.win_6_2_i386", + "vstruct.defs.windows.win_6_2_i386.ntdll", + "vstruct.defs.windows.win_6_2_i386.ntoskrnl", + "vstruct.defs.windows.win_6_2_i386.win32k", + "vstruct.defs.windows.win_6_2_wow64", + "vstruct.defs.windows.win_6_2_wow64.ntdll", + "vstruct.defs.windows.win_6_3_amd64", + "vstruct.defs.windows.win_6_3_amd64.ntdll", + "vstruct.defs.windows.win_6_3_amd64.ntoskrnl", + "vstruct.defs.windows.win_6_3_i386", + "vstruct.defs.windows.win_6_3_i386.ntdll", + "vstruct.defs.windows.win_6_3_i386.ntoskrnl", + "vstruct.defs.windows.win_6_3_wow64", + "vstruct.defs.windows.win_6_3_wow64.ntdll", + ], + hookspath=['ci/hooks'], + runtime_hooks=None, + excludes=[ + # ignore packages that would otherwise be bundled with the .exe. + # review: build/pyinstaller/xref-pyinstaller.html + + # we don't do any GUI stuff, so ignore these modules + "tkinter", + "_tkinter", + "Tkinter", + # tqdm provides renderers for ipython, + # however, this drags in a lot of dependencies. + # since we don't spawn a notebook, we can safely remove these. + "IPython", + "ipywidgets", + ], + win_no_prefer_redirects=None, + win_private_assemblies=None, + cipher=block_cipher) + +a.binaries = a.binaries - TOC([ + ('tcl85.dll', None, None), + ('tk85.dll', None, None), + ('_tkinter', None, None)]) + +pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) + +exe = EXE(pyz, + a.scripts, + a.binaries, + a.zipfiles, + a.datas, + exclude_binaries=False, + name='capa', + icon='logo.ico', + debug=False, + strip=None, + upx=True, + console=True ) + +# enable the following to debug the contents of the .exe +# +#coll = COLLECT(exe, +# a.binaries, +# a.zipfiles, +# a.datas, +# strip=None, +# upx=True, +# name='capa-dat') +