158 lines
6.5 KiB
Python
158 lines
6.5 KiB
Python
import os
|
|
import pefile
|
|
import shutil
|
|
import tkinter as tk
|
|
from tkinter import filedialog, messagebox, ttk
|
|
|
|
# Common DLLs that come with the OS
|
|
OS_DLLS = {
|
|
"KERNEL32.dll", "USER32.dll", "GDI32.dll", "ADVAPI32.dll",
|
|
"SHELL32.dll", "OLE32.dll", "OLEAUT32.dll", "COMDLG32.dll",
|
|
"SHLWAPI.dll", "MSVCRT.dll", "NTDLL.dll", "RPCRT4.dll",
|
|
"WININET.dll", "WS2_32.dll", "CRYPT32.dll", "OPENGL32.dll"
|
|
}
|
|
|
|
class DLLExtractorApp:
|
|
def __init__(self, root):
|
|
self.root = root
|
|
self.root.title("DLL Extractor")
|
|
self.root.geometry("700x500")
|
|
self.root.minsize(700, 500)
|
|
|
|
# Configure Dark Mode
|
|
style = ttk.Style()
|
|
style.theme_use("clam")
|
|
style.configure("TFrame", background="#2b2b2b")
|
|
style.configure("TLabel", background="#2b2b2b", foreground="#ffffff", font=("Arial", 10))
|
|
style.configure("TButton", background="#0078d7", foreground="#ffffff", font=("Arial", 10), borderwidth=1)
|
|
style.configure("TEntry", font=("Arial", 10), fieldbackground="#3c3c3c", foreground="#ffffff")
|
|
style.configure("TScrollbar", background="#3c3c3c", troughcolor="#3c3c3c", arrowcolor="#ffffff")
|
|
style.configure("Listbox", background="#3c3c3c", foreground="#ffffff", font=("Arial", 10))
|
|
style.map("TButton", background=[("active", "#005499")])
|
|
|
|
self.exe_path = tk.StringVar()
|
|
self.dependencies = []
|
|
|
|
self.setup_ui()
|
|
|
|
def setup_ui(self):
|
|
frame = ttk.Frame(self.root, padding="10")
|
|
frame.pack(fill=tk.BOTH, expand=True)
|
|
|
|
# File Selection
|
|
file_frame = ttk.Frame(frame)
|
|
file_frame.pack(fill=tk.X, pady=10)
|
|
|
|
ttk.Label(file_frame, text="Select EXE File:").grid(row=0, column=0, sticky="w", padx=5)
|
|
ttk.Entry(file_frame, textvariable=self.exe_path, width=60, state="readonly").grid(row=0, column=1, padx=5)
|
|
ttk.Button(file_frame, text="Browse", command=self.browse_file).grid(row=0, column=2, padx=5)
|
|
|
|
# Dependencies List
|
|
ttk.Label(frame, text="DLL Dependencies:").pack(anchor="w", pady=(10, 5))
|
|
|
|
list_frame = ttk.Frame(frame)
|
|
list_frame.pack(fill=tk.BOTH, expand=True, pady=5)
|
|
|
|
self.dependencies_list = tk.Listbox(list_frame, height=15, selectmode=tk.SINGLE, bg="#3c3c3c", fg="#ffffff", font=("Arial", 10))
|
|
self.dependencies_list.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=5)
|
|
|
|
scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.dependencies_list.yview)
|
|
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
|
|
self.dependencies_list.config(yscrollcommand=scrollbar.set)
|
|
|
|
# Buttons
|
|
button_frame = ttk.Frame(frame)
|
|
button_frame.pack(fill=tk.X, pady=(10, 0))
|
|
|
|
ttk.Button(button_frame, text="Extract DLLs", command=self.extract_dlls).pack(side=tk.LEFT, padx=5)
|
|
ttk.Button(button_frame, text="Export DLLs", command=self.export_dlls).pack(side=tk.LEFT, padx=5)
|
|
|
|
# Log Section
|
|
ttk.Label(frame, text="Operation Log:").pack(anchor="w", pady=(10, 5))
|
|
|
|
self.log = tk.Text(frame, height=6, state="disabled", bg="#3c3c3c", fg="#ffffff", font=("Arial", 10), wrap=tk.WORD)
|
|
self.log.pack(fill=tk.BOTH, expand=False, padx=5)
|
|
|
|
def log_message(self, message):
|
|
"""Log a message to the log box."""
|
|
self.log.config(state="normal")
|
|
self.log.insert(tk.END, message + "\n")
|
|
self.log.config(state="disabled")
|
|
self.log.see(tk.END)
|
|
|
|
def browse_file(self):
|
|
"""Browse for an executable file."""
|
|
file_path = filedialog.askopenfilename(
|
|
title="Select an Executable",
|
|
filetypes=[("Executable Files", "*.exe"), ("All Files", "*.*")]
|
|
)
|
|
if file_path:
|
|
self.exe_path.set(file_path)
|
|
self.log_message(f"Selected EXE: {file_path}")
|
|
self.get_dll_dependencies(file_path)
|
|
|
|
def get_dll_dependencies(self, exe_path):
|
|
"""Extract DLL dependencies from the selected executable."""
|
|
self.dependencies = []
|
|
self.dependencies_list.delete(0, tk.END)
|
|
try:
|
|
pe = pefile.PE(exe_path)
|
|
if hasattr(pe, 'DIRECTORY_ENTRY_IMPORT'):
|
|
all_dlls = [entry.dll.decode('utf-8') for entry in pe.DIRECTORY_ENTRY_IMPORT]
|
|
self.dependencies = [dll for dll in all_dlls if dll.upper() not in OS_DLLS]
|
|
self.log_message("Extracted DLL dependencies.")
|
|
for dll in self.dependencies:
|
|
self.dependencies_list.insert(tk.END, dll)
|
|
else:
|
|
self.log_message("No DLL dependencies found.")
|
|
except Exception as e:
|
|
messagebox.showerror("Error", f"Failed to read the executable: {e}")
|
|
self.log_message(f"Error reading executable: {e}")
|
|
|
|
def extract_dlls(self):
|
|
"""Extract and copy found DLLs to a folder."""
|
|
if not self.dependencies:
|
|
messagebox.showwarning("Warning", "No DLL dependencies to extract.")
|
|
return
|
|
|
|
folder = "found_dlls"
|
|
os.makedirs(folder, exist_ok=True)
|
|
copied_dlls = []
|
|
for dll in self.dependencies:
|
|
for path in os.environ['PATH'].split(os.pathsep):
|
|
dll_path = os.path.join(path, dll)
|
|
if os.path.exists(dll_path):
|
|
shutil.copy(dll_path, os.path.join(folder, dll))
|
|
copied_dlls.append(dll)
|
|
break
|
|
|
|
self.log_message(f"Copied {len(copied_dlls)} DLLs to {folder}.")
|
|
messagebox.showinfo("Success", f"Copied {len(copied_dlls)} DLLs to {folder}.")
|
|
|
|
def export_dlls(self):
|
|
"""Export DLL dependencies to a file."""
|
|
if not self.dependencies:
|
|
messagebox.showwarning("Warning", "No DLL dependencies to export.")
|
|
return
|
|
|
|
export_file = filedialog.asksaveasfilename(
|
|
title="Export DLL List",
|
|
defaultextension=".txt",
|
|
filetypes=[("Text Files", "*.txt"), ("All Files", "*.*")]
|
|
)
|
|
if export_file:
|
|
try:
|
|
with open(export_file, "w") as f:
|
|
f.write("\n".join(self.dependencies))
|
|
self.log_message(f"Exported DLL dependencies to {export_file}.")
|
|
messagebox.showinfo("Success", f"Exported DLL dependencies to {export_file}.")
|
|
except Exception as e:
|
|
messagebox.showerror("Error", f"Failed to export DLL dependencies: {e}")
|
|
self.log_message(f"Error exporting DLL dependencies: {e}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
root = tk.Tk()
|
|
app = DLLExtractorApp(root)
|
|
root.mainloop()
|