-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathread_windows_exe_metadata.py
More file actions
executable file
·89 lines (69 loc) · 2.85 KB
/
read_windows_exe_metadata.py
File metadata and controls
executable file
·89 lines (69 loc) · 2.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env python3
"""
Show metadata for a Windows executable.
This script runs on any platform.
Copyright (C) 2025 by Andrew Ziem. All rights reserved.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
"""
import sys
import argparse
try:
import pefile
except ImportError:
print("Error: pefile module is required. Try running: 'pip install pefile'.")
sys.exit(1)
def extract_string_table_metadata(pe, metadata, metadata_fields):
# Extract string table info
if hasattr(pe, 'FileInfo') and pe.FileInfo:
for fileinfo in pe.FileInfo[0]:
if fileinfo.Key.decode() == 'StringFileInfo':
for st in fileinfo.StringTable:
for key, value in st.entries.items():
decoded_key = key.decode()
decoded_value = value.decode()
if decoded_key in metadata_fields:
metadata_key = metadata_fields[decoded_key]
metadata[metadata_key] = decoded_value
else:
print(f"Unknown key: {decoded_key}")
def extract_metadata(file_path):
try:
pe = pefile.PE(file_path)
except pefile.PEFormatError:
print("Error: Not a valid PE file.")
return {}
metadata_fields = {
'FileDescription': 'File description',
'FileVersion': 'File version',
'ProductName': 'Product name',
'ProductVersion': 'Product version',
'LegalCopyright': 'Legal copyright',
'LegalTrademarks': 'Legal trademarks',
'Comments': 'Comments',
'CompanyName': 'Company name'
}
# Initialize metadata with defaults
metadata = {field: 'N/A' for field in metadata_fields.values()}
metadata['Digitally signed'] = 'No'
extract_string_table_metadata(pe, metadata, metadata_fields)
# Check digital signature
if pe.OPTIONAL_HEADER.DATA_DIRECTORY[pefile.DIRECTORY_ENTRY['IMAGE_DIRECTORY_ENTRY_SECURITY']].Size > 0:
metadata['Digitally signed'] = 'Yes'
# Print all metadata
for field_name, value in metadata.items():
print(f"{field_name}: {value}")
return metadata
def main():
parser = argparse.ArgumentParser(
description='Check metadata of Windows executable')
parser.add_argument('file_path', help='Path to the Windows executable')
parser.add_argument('--require-signature', '-r', action='store_true',
help='Exit with code 1 if digital signature is missing')
args = parser.parse_args()
metadata = extract_metadata(args.file_path)
if args.require_signature and metadata.get('Digitally signed', 'No') == 'No':
sys.exit(1)
if __name__ == "__main__":
main()