DLL-Extractor/main.py
2024-12-29 14:07:54 -06:00

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()