Skip to content

Instantly share code, notes, and snippets.

@scivision
Last active February 16, 2026 15:38
Show Gist options
  • Select an option

  • Save scivision/2c2058315b2cbf591f2d22a28f02fecd to your computer and use it in GitHub Desktop.

Select an option

Save scivision/2c2058315b2cbf591f2d22a28f02fecd to your computer and use it in GitHub Desktop.
Detect Windows .exe CPU arch (ARM64, x86_64, ...)

Windows .exe CPU arch detection and DLL import list

Use LIEF with Python for introspection of executable files.

Print Windows DLL imports

python print_imports.py $Env:WINDIR/System32/notepad.exe

Detect the CPU arch an .exe Windows executable was built for.

python detect_windows_exe_arch.py c:/path/to/my.exe

ARM64 CPU examples

From Windows PowerShell invoking Python:

python detect_windows_exe_arch.py $Env:WINDIR/System32/ntdll.dll

Architecture: ARM64 (native) (ARM64X hybrid - native ARM64 + Arm64EC/x64 interop)

python detect_windows_exe_arch.py $Env:WINDIR/System32/notepad.exe

Architecture: ARM64 (native)

python detect_windows_exe_arch.py "$Env:ProgramFiles/MATLAB/R2026a/bin/matlab.exe"

On an ARM64 laptop:

Architecture: x86 (32-bit Intel)

GNU Octave installer:

python detect_windows_exe_arch.py octave-11.0.92-w64-installer.exe

Architecture: x64 (64-bit)

#!/usr/bin/env python3
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "lief >= 0.14.0"
# ]
# ///
import argparse
from pathlib import Path
import lief
def detect_exe_arch(file_path: str) -> str:
p = Path(file_path).resolve(strict=True)
mt = lief.PE.Header.MACHINE_TYPES
binary = lief.PE.parse(p)
machine = binary.header.machine
match machine:
case mt.I386:
return "x86 (32-bit Intel)"
case mt.AMD64:
desc = "x64 (64-bit)"
if binary.is_arm64x:
desc += " (ARM64X hybrid)"
elif binary.is_arm64ec:
desc += " (ARM64EC)"
return desc
case mt.ARM64:
desc = "ARM64 (native)"
if binary.is_arm64x:
desc += " (ARM64X hybrid - native ARM64 + Arm64EC/x64 interop)"
elif binary.is_arm64ec:
desc += " (ARM64EC - emulation compatible)"
return desc
case _:
return mt.name
if __name__ == "__main__":
p = argparse.ArgumentParser(description="Detect CPU arch of Windows .exe file")
p.add_argument("exe", help="path to Windows .exe file")
args = p.parse_args()
path = args.exe
arch = detect_exe_arch(path)
print(f"Architecture: {arch}")
#!/usr/bin/env python3
# /// script
# dependencies = [
# "lief"
# ]
# ///
"""
Prints the names of the imported DLLs from a Windows executable using the lief library.
"""
import lief
import argparse
import shutil
p = argparse.ArgumentParser(description="Print imported DLLs from a Windows executable")
p.add_argument("exe", help="path to executable file")
args = p.parse_args()
cmd = shutil.which(args.exe)
if cmd is None:
raise FileNotFoundError(f"{args.exe} not found in PATH")
pe = lief.PE.parse(cmd)
for imp in pe.imports:
print(imp.name)
[tool.black]
line-length = 100
[tool.mypy]
files = ["."]
ignore_missing_imports = true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment