euler314 commited on
Commit
25a8adb
·
verified ·
1 Parent(s): 3e551d7

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +226 -0
app.py ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ import zipfile
4
+ import tempfile
5
+ import pefile
6
+ import shutil
7
+ from pathlib import Path
8
+
9
+ st.set_page_config(page_title="File Analyzer", page_icon="🔍")
10
+
11
+ st.title("File Analysis Tool")
12
+ st.markdown("""
13
+ This tool allows you to analyze various file types:
14
+ - Extract and view contents of .zip files
15
+ - Unpack .exe files to examine their contents
16
+ - View information about .dll files
17
+ """)
18
+
19
+ # Maximum file size (10MB)
20
+ MAX_FILE_SIZE = 10 * 1024 * 1024
21
+
22
+ def unpack_exe(file_path, output_dir):
23
+ """Extract information from an EXE file using pefile"""
24
+ try:
25
+ pe = pefile.PE(file_path)
26
+
27
+ # Create a basic info dictionary
28
+ info = {
29
+ "Machine": hex(pe.FILE_HEADER.Machine),
30
+ "TimeDateStamp": pe.FILE_HEADER.TimeDateStamp,
31
+ "NumberOfSections": pe.FILE_HEADER.NumberOfSections,
32
+ "Sections": []
33
+ }
34
+
35
+ # Get section information
36
+ for section in pe.sections:
37
+ section_name = section.Name.decode('utf-8', errors='ignore').strip('\x00')
38
+ info["Sections"].append({
39
+ "Name": section_name,
40
+ "VirtualAddress": hex(section.VirtualAddress),
41
+ "SizeOfRawData": section.SizeOfRawData,
42
+ "Entropy": section.get_entropy()
43
+ })
44
+
45
+ # Get imports
46
+ if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
47
+ info["Imports"] = []
48
+ for entry in pe.DIRECTORY_ENTRY_IMPORT:
49
+ dll_name = entry.dll.decode('utf-8', errors='ignore')
50
+ imports = []
51
+ for imp in entry.imports:
52
+ if imp.name:
53
+ imports.append(imp.name.decode('utf-8', errors='ignore'))
54
+ info["Imports"].append({
55
+ "DLL": dll_name,
56
+ "Functions": imports
57
+ })
58
+
59
+ # Extract resources if present
60
+ if hasattr(pe, 'DIRECTORY_ENTRY_RESOURCE'):
61
+ resource_dir = os.path.join(output_dir, "resources")
62
+ os.makedirs(resource_dir, exist_ok=True)
63
+
64
+ for resource_type in pe.DIRECTORY_ENTRY_RESOURCE.entries:
65
+ if hasattr(resource_type, 'directory'):
66
+ for resource_id in resource_type.directory.entries:
67
+ if hasattr(resource_id, 'directory'):
68
+ for resource_lang in resource_id.directory.entries:
69
+ data = pe.get_data(resource_lang.data.struct.OffsetToData, resource_lang.data.struct.Size)
70
+ resource_filename = f"resource_{resource_type.id}_{resource_id.id}_{resource_lang.id}"
71
+ with open(os.path.join(resource_dir, resource_filename), 'wb') as f:
72
+ f.write(data)
73
+
74
+ return info
75
+ except Exception as e:
76
+ return {"Error": str(e)}
77
+
78
+ def analyze_dll(file_path):
79
+ """Extract information from a DLL file using pefile"""
80
+ try:
81
+ pe = pefile.PE(file_path)
82
+
83
+ # Create a basic info dictionary
84
+ info = {
85
+ "Machine": hex(pe.FILE_HEADER.Machine),
86
+ "TimeDateStamp": pe.FILE_HEADER.TimeDateStamp,
87
+ "NumberOfSections": pe.FILE_HEADER.NumberOfSections,
88
+ "Characteristics": hex(pe.FILE_HEADER.Characteristics),
89
+ "DllCharacteristics": hex(pe.OPTIONAL_HEADER.DllCharacteristics),
90
+ "Sections": []
91
+ }
92
+
93
+ # Get section information
94
+ for section in pe.sections:
95
+ section_name = section.Name.decode('utf-8', errors='ignore').strip('\x00')
96
+ info["Sections"].append({
97
+ "Name": section_name,
98
+ "VirtualAddress": hex(section.VirtualAddress),
99
+ "SizeOfRawData": section.SizeOfRawData,
100
+ "Entropy": section.get_entropy()
101
+ })
102
+
103
+ # Get exports if present
104
+ if hasattr(pe, 'DIRECTORY_ENTRY_EXPORT'):
105
+ info["Exports"] = []
106
+ for exp in pe.DIRECTORY_ENTRY_EXPORT.symbols:
107
+ if exp.name:
108
+ info["Exports"].append(exp.name.decode('utf-8', errors='ignore'))
109
+
110
+ # Get imports
111
+ if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
112
+ info["Imports"] = []
113
+ for entry in pe.DIRECTORY_ENTRY_IMPORT:
114
+ dll_name = entry.dll.decode('utf-8', errors='ignore')
115
+ imports = []
116
+ for imp in entry.imports:
117
+ if imp.name:
118
+ imports.append(imp.name.decode('utf-8', errors='ignore'))
119
+ info["Imports"].append({
120
+ "DLL": dll_name,
121
+ "Functions": imports
122
+ })
123
+
124
+ return info
125
+ except Exception as e:
126
+ return {"Error": str(e)}
127
+
128
+ def process_zip_file(file_path, temp_dir):
129
+ """Process a ZIP file and extract its contents"""
130
+ try:
131
+ with zipfile.ZipFile(file_path, 'r') as zip_ref:
132
+ # Get file list before extraction
133
+ file_list = zip_ref.namelist()
134
+
135
+ # Extract to temp directory
136
+ zip_ref.extractall(temp_dir)
137
+
138
+ # Check for nested executables
139
+ nested_files = {}
140
+ for root, _, files in os.walk(temp_dir):
141
+ for file in files:
142
+ full_path = os.path.join(root, file)
143
+ rel_path = os.path.relpath(full_path, temp_dir)
144
+
145
+ if file.endswith('.exe'):
146
+ exe_output_dir = os.path.join(temp_dir, f"{file}_unpacked")
147
+ os.makedirs(exe_output_dir, exist_ok=True)
148
+ nested_files[rel_path] = {
149
+ 'type': 'exe',
150
+ 'info': unpack_exe(full_path, exe_output_dir)
151
+ }
152
+ elif file.endswith('.dll'):
153
+ nested_files[rel_path] = {
154
+ 'type': 'dll',
155
+ 'info': analyze_dll(full_path)
156
+ }
157
+
158
+ return {
159
+ 'file_list': file_list,
160
+ 'nested_files': nested_files
161
+ }
162
+ except Exception as e:
163
+ return {'error': str(e)}
164
+
165
+ # Main app logic
166
+ uploaded_file = st.file_uploader("Upload a file (.zip, .exe, or .dll)", type=["zip", "exe", "dll"])
167
+
168
+ if uploaded_file is not None:
169
+ # Check file size
170
+ if uploaded_file.size > MAX_FILE_SIZE:
171
+ st.error(f"File too large. Maximum size is {MAX_FILE_SIZE/1024/1024}MB.")
172
+ else:
173
+ with tempfile.TemporaryDirectory() as temp_dir:
174
+ # Save the uploaded file to the temporary directory
175
+ file_path = os.path.join(temp_dir, uploaded_file.name)
176
+ with open(file_path, "wb") as f:
177
+ f.write(uploaded_file.getbuffer())
178
+
179
+ st.success(f"File uploaded: {uploaded_file.name}")
180
+
181
+ # Process based on file type
182
+ if uploaded_file.name.lower().endswith('.zip'):
183
+ st.subheader("ZIP File Contents")
184
+ output_dir = os.path.join(temp_dir, "extracted")
185
+ os.makedirs(output_dir, exist_ok=True)
186
+
187
+ result = process_zip_file(file_path, output_dir)
188
+
189
+ if 'error' in result:
190
+ st.error(f"Error processing ZIP file: {result['error']}")
191
+ else:
192
+ with st.expander("ZIP Contents", expanded=True):
193
+ st.write(f"Total files: {len(result['file_list'])}")
194
+ st.json(result['file_list'])
195
+
196
+ if result['nested_files']:
197
+ st.subheader("Detected Executable Files")
198
+ for file_path, file_info in result['nested_files'].items():
199
+ with st.expander(f"{file_path} ({file_info['type'].upper()})"):
200
+ st.json(file_info['info'])
201
+
202
+ elif uploaded_file.name.lower().endswith('.exe'):
203
+ st.subheader("EXE File Analysis")
204
+ output_dir = os.path.join(temp_dir, "exe_unpacked")
205
+ os.makedirs(output_dir, exist_ok=True)
206
+
207
+ try:
208
+ exe_info = unpack_exe(file_path, output_dir)
209
+ st.json(exe_info)
210
+
211
+ # Check if resources were extracted
212
+ resource_dir = os.path.join(output_dir, "resources")
213
+ if os.path.exists(resource_dir) and os.listdir(resource_dir):
214
+ st.subheader("Extracted Resources")
215
+ for resource_file in os.listdir(resource_dir):
216
+ st.text(f"Resource: {resource_file}")
217
+ except Exception as e:
218
+ st.error(f"Error analyzing EXE file: {str(e)}")
219
+
220
+ elif uploaded_file.name.lower().endswith('.dll'):
221
+ st.subheader("DLL File Information")
222
+ try:
223
+ dll_info = analyze_dll(file_path)
224
+ st.json(dll_info)
225
+ except Exception as e:
226
+ st.error(f"Error analyzing DLL file: {str(e)}")