Skip to content

Commit 15f6466

Browse files
Add files via upload
1 parent 9686e70 commit 15f6466

8 files changed

Lines changed: 359 additions & 0 deletions

File tree

1.42 KB
Binary file not shown.
860 Bytes
Binary file not shown.
1.56 KB
Binary file not shown.

FileTypeIdentifierV1/exports.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import json
2+
from datetime import datetime
3+
4+
5+
def export_json(data):
6+
7+
filename = f"report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
8+
9+
with open(filename, "w") as f:
10+
json.dump(data, f, indent=4)
11+
12+
return filename
13+
14+
15+
def export_txt(data):
16+
17+
filename = f"report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
18+
19+
with open(filename, "w") as f:
20+
21+
for item in data:
22+
23+
f.write("=" * 60 + "\n")
24+
25+
for k, v in item.items():
26+
f.write(f"{k}: {v}\n")
27+
28+
return filename

FileTypeIdentifierV1/magic_db.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
MAGIC_NUMBERS = {
2+
3+
"exe": [
4+
b"\x4D\x5A"
5+
],
6+
7+
"dll": [
8+
b"\x4D\x5A"
9+
],
10+
11+
"pdf": [
12+
b"\x25\x50\x44\x46"
13+
],
14+
15+
"png": [
16+
b"\x89PNG\r\n\x1a\n"
17+
],
18+
19+
"jpg": [
20+
b"\xFF\xD8\xFF"
21+
],
22+
23+
"gif": [
24+
b"GIF87a",
25+
b"GIF89a"
26+
],
27+
28+
"bmp": [
29+
b"BM"
30+
],
31+
32+
"zip": [
33+
b"\x50\x4B\x03\x04"
34+
],
35+
36+
"rar": [
37+
b"\x52\x61\x72\x21\x1A\x07"
38+
],
39+
40+
"7z": [
41+
b"\x37\x7A\xBC\xAF\x27\x1C"
42+
],
43+
44+
"mp3": [
45+
b"ID3"
46+
],
47+
48+
"wav": [
49+
b"RIFF"
50+
],
51+
52+
"mp4": [
53+
b"ftyp"
54+
],
55+
56+
"avi": [
57+
b"RIFF"
58+
],
59+
60+
"docx": [
61+
b"\x50\x4B\x03\x04"
62+
],
63+
64+
"xlsx": [
65+
b"\x50\x4B\x03\x04"
66+
],
67+
68+
"pptx": [
69+
b"\x50\x4B\x03\x04"
70+
]
71+
}

FileTypeIdentifierV1/main.py

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
import os
2+
import threading
3+
import tkinter as tk
4+
from tkinter import filedialog
5+
from tkinter import ttk
6+
7+
import customtkinter as ctk
8+
9+
from scanner import get_file_info
10+
from exports import export_json, export_txt
11+
12+
ctk.set_appearance_mode("dark")
13+
ctk.set_default_color_theme("blue")
14+
15+
16+
class FileTypeIdentifier(ctk.CTk):
17+
18+
def __init__(self):
19+
20+
super().__init__()
21+
22+
self.title("Magic Number File Type Identifier")
23+
24+
self.geometry("1400x850")
25+
26+
self.minsize(1200, 700)
27+
28+
self.scan_results = []
29+
30+
self.build_ui()
31+
32+
def build_ui(self):
33+
34+
self.grid_columnconfigure(1, weight=1)
35+
self.grid_rowconfigure(0, weight=1)
36+
37+
sidebar = ctk.CTkFrame(self, width=260)
38+
39+
sidebar.grid(row=0, column=0, sticky="ns")
40+
41+
title = ctk.CTkLabel(
42+
sidebar,
43+
text="FILE TYPE\nIDENTIFIER",
44+
font=("Segoe UI", 26, "bold")
45+
)
46+
47+
title.pack(pady=25)
48+
49+
ctk.CTkButton(
50+
sidebar,
51+
text="Scan File",
52+
command=self.scan_file
53+
).pack(fill="x", padx=15, pady=8)
54+
55+
ctk.CTkButton(
56+
sidebar,
57+
text="Scan Folder",
58+
command=self.scan_folder
59+
).pack(fill="x", padx=15, pady=8)
60+
61+
ctk.CTkButton(
62+
sidebar,
63+
text="Export JSON",
64+
command=self.save_json
65+
).pack(fill="x", padx=15, pady=8)
66+
67+
ctk.CTkButton(
68+
sidebar,
69+
text="Export TXT",
70+
command=self.save_txt
71+
).pack(fill="x", padx=15, pady=8)
72+
73+
self.stats = ctk.CTkLabel(
74+
sidebar,
75+
text="Files: 0\nThreats: 0"
76+
)
77+
78+
self.stats.pack(pady=20)
79+
80+
main = ctk.CTkFrame(self)
81+
82+
main.grid(row=0, column=1, sticky="nsew")
83+
84+
self.progress = ttk.Progressbar(
85+
main,
86+
mode="determinate"
87+
)
88+
89+
self.progress.pack(fill="x", padx=10, pady=10)
90+
91+
columns = (
92+
"File",
93+
"Extension",
94+
"Actual",
95+
"Mismatch",
96+
"Size"
97+
)
98+
99+
self.tree = ttk.Treeview(
100+
main,
101+
columns=columns,
102+
show="headings"
103+
)
104+
105+
for col in columns:
106+
107+
self.tree.heading(col, text=col)
108+
109+
self.tree.column(col, width=200)
110+
111+
self.tree.pack(
112+
fill="both",
113+
expand=True,
114+
padx=10,
115+
pady=10
116+
)
117+
118+
def add_result(self, data):
119+
120+
self.scan_results.append(data)
121+
122+
self.tree.insert(
123+
"",
124+
"end",
125+
values=(
126+
os.path.basename(data["path"]),
127+
data["extension"],
128+
data["actual"],
129+
"YES" if data["mismatch"] else "NO",
130+
data["size"]
131+
)
132+
)
133+
134+
threats = sum(
135+
1 for x in self.scan_results
136+
if x["mismatch"]
137+
)
138+
139+
self.stats.configure(
140+
text=f"Files: {len(self.scan_results)}\nThreats: {threats}"
141+
)
142+
143+
def scan_file(self):
144+
145+
path = filedialog.askopenfilename()
146+
147+
if not path:
148+
return
149+
150+
result = get_file_info(path)
151+
152+
self.add_result(result)
153+
154+
def scan_folder(self):
155+
156+
folder = filedialog.askdirectory()
157+
158+
if not folder:
159+
return
160+
161+
threading.Thread(
162+
target=self.folder_scan_worker,
163+
args=(folder,),
164+
daemon=True
165+
).start()
166+
167+
def folder_scan_worker(self, folder):
168+
169+
files = []
170+
171+
for root, dirs, filenames in os.walk(folder):
172+
173+
for file in filenames:
174+
files.append(
175+
os.path.join(root, file)
176+
)
177+
178+
total = len(files)
179+
180+
self.progress["maximum"] = total
181+
182+
for index, file in enumerate(files):
183+
184+
try:
185+
186+
info = get_file_info(file)
187+
188+
self.after(
189+
0,
190+
lambda i=info:
191+
self.add_result(i)
192+
)
193+
194+
except:
195+
pass
196+
197+
self.progress["value"] = index + 1
198+
199+
def save_json(self):
200+
201+
export_json(self.scan_results)
202+
203+
def save_txt(self):
204+
205+
export_txt(self.scan_results)
206+
207+
208+
if __name__ == "__main__":
209+
210+
app = FileTypeIdentifier()
211+
212+
app.mainloop()
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
customtkinter
2+
tkinterdnd2
3+
Pillow
4+
file

FileTypeIdentifierV1/scanner.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import os
2+
from magic_db import MAGIC_NUMBERS
3+
4+
5+
def detect_type(filepath):
6+
7+
try:
8+
9+
with open(filepath, "rb") as f:
10+
header = f.read(64)
11+
12+
for filetype, signatures in MAGIC_NUMBERS.items():
13+
14+
for sig in signatures:
15+
16+
if header.startswith(sig):
17+
return filetype
18+
19+
if sig == b"ftyp" and b"ftyp" in header:
20+
return filetype
21+
22+
return "unknown"
23+
24+
except Exception:
25+
return "error"
26+
27+
28+
def get_file_info(filepath):
29+
30+
size = os.path.getsize(filepath)
31+
32+
ext = os.path.splitext(filepath)[1].replace(".", "").lower()
33+
34+
actual = detect_type(filepath)
35+
36+
mismatch = ext != actual
37+
38+
return {
39+
"path": filepath,
40+
"extension": ext,
41+
"actual": actual,
42+
"size": size,
43+
"mismatch": mismatch
44+
}

0 commit comments

Comments
 (0)