Skip to content

Commit c54b0c9

Browse files
authored
Update program.py
1 parent caf5bf9 commit c54b0c9

File tree

1 file changed

+85
-52
lines changed

1 file changed

+85
-52
lines changed

AutoChain-Mac/program.py

Lines changed: 85 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ def setup_ui(self):
276276
self.image_size_label = ttk.Label(frame, text="0 MB")
277277
self.image_size_label.place(x=120, y=210)
278278

279+
# Add a progress bar for file processing
280+
self.progress_bar = ttk.Progressbar(
281+
frame, orient="horizontal", length=260, mode="determinate")
282+
self.progress_bar.place(x=120, y=240)
283+
279284
large_font = ("Arial", 10)
280285

281286
ttk.Label(frame, text="MD5 Hash:").place(x=10, y=240)
@@ -318,52 +323,61 @@ def update_zip_codes(self, event=None):
318323
def browse_image_file(self):
319324
"""Browse for an image file and ensure paths are handled correctly."""
320325
try:
321-
if not self.winfo_exists(): # Check if widget still exists
322-
return
323-
324326
file_path = filedialog.askopenfilename(
325-
title="Select an Image File",
326-
filetypes=[("Image Files", "*.img *.jpg *.png *.bmp *.tiff")]
327+
filetypes=[
328+
("Image Files", "*.img;*.dd;*.iso;*.bin;*.001;*.raw"), ("All Files", "*.*")]
327329
)
328-
329330
if file_path:
330-
# Store the absolute path
331-
abs_path = os.path.abspath(file_path)
332-
333331
self.image_file_entry.config(state="normal")
334332
self.image_file_entry.delete(0, tk.END)
335-
self.image_file_entry.insert(0, abs_path)
333+
self.image_file_entry.insert(0, file_path)
336334
self.image_file_entry.config(state="readonly")
337-
338-
self.update_image_size(abs_path)
339-
self.calculate_hashes(abs_path)
340-
335+
self.update_image_size(file_path)
336+
# Calculate hashes in a thread to keep UI responsive
337+
threading.Thread(target=self.calculate_hashes,
338+
args=(file_path,), daemon=True).start()
341339
except Exception as e:
342-
messagebox.showerror("Error", f"Failed to access file: {str(e)}")
340+
messagebox.showerror("Error", f"Failed to select file: {str(e)}")
343341

344342
def update_image_size(self, file_path):
345343
"""Update the image size label with the size of the selected file."""
346344
try:
347-
file_size = os.path.getsize(file_path)
348-
file_size_mb = file_size / (1024 * 1024)
349-
self.image_size_label.config(text=f"{file_size_mb:.2f} MB")
345+
size_bytes = os.path.getsize(file_path)
346+
size_mb = size_bytes / (1024 * 1024)
347+
self.image_size_label.config(text=f"{size_mb:.2f} MB")
350348
except Exception as e:
351-
self.image_size_label.config(text="0 MB")
352-
print(f"Error updating image size: {e}")
349+
self.image_size_label.config(text="Error")
353350

354351
def calculate_hashes(self, file_path):
355-
"""Calculate and display the MD5 and SHA-256 hashes of the selected file."""
352+
"""Calculate and display the MD5 and SHA-256 hashes of the selected file, updating the progress bar."""
356353
try:
354+
md5 = hashlib.md5()
355+
sha256 = hashlib.sha256()
356+
file_size = os.path.getsize(file_path)
357+
chunk_size = 1024 * 1024 # 1MB
358+
read_bytes = 0
359+
360+
self.progress_bar["value"] = 0
361+
self.progress_bar["maximum"] = file_size
362+
357363
with open(file_path, "rb") as f:
358-
file_data = f.read()
359-
md5_hash = hashlib.md5(file_data).hexdigest()
360-
sha256_hash = hashlib.sha256(file_data).hexdigest()
361-
self.md5_hash_label.config(text=md5_hash)
362-
self.sha256_hash_label.config(text=sha256_hash)
364+
while True:
365+
chunk = f.read(chunk_size)
366+
if not chunk:
367+
break
368+
md5.update(chunk)
369+
sha256.update(chunk)
370+
read_bytes += len(chunk)
371+
self.progress_bar["value"] = read_bytes
372+
self.progress_bar.update_idletasks()
373+
374+
self.md5_hash_label.config(text=md5.hexdigest())
375+
self.sha256_hash_label.config(text=sha256.hexdigest())
376+
self.progress_bar["value"] = file_size # Ensure bar is full at end
363377
except Exception as e:
364-
self.md5_hash_label.config(text="")
365-
self.sha256_hash_label.config(text="")
366-
print(f"Error calculating hashes: {e}")
378+
self.md5_hash_label.config(text="Error")
379+
self.sha256_hash_label.config(text="Error")
380+
self.progress_bar["value"] = 0
367381

368382
def submit_form(self):
369383
"""Submit the form and log the chain of custody."""
@@ -690,21 +704,46 @@ def read_chain_of_custody():
690704
return log_file.read()
691705

692706

693-
def create_disk_image(disk_device, output_image, disk_size_gb, progress_callback, progress_bar, mb_label, speed_label, time_label):
694-
"""Create a forensic disk image using dd."""
707+
def create_disk_image(disk_device, output_image, progress_callback, progress_bar, mb_label, speed_label, time_label):
708+
"""Create a forensic disk image using dd, auto-detecting device size."""
695709
try:
696-
697710
log_chain_of_custody("Disk Imaging Started",
698711
f"Device: {disk_device}, Output: {output_image}")
712+
713+
# --- Get device size in bytes ---
714+
size_bytes = 0
715+
try:
716+
# Use diskutil info for macOS
717+
output = subprocess.check_output(
718+
["diskutil", "info", disk_device], text=True)
719+
print("DISKUTIL OUTPUT:\n", output) # Add this line for debugging
720+
for line in output.splitlines():
721+
if "disk size:" in line.lower() and "bytes" in line.lower():
722+
# Find the part like (15728640000 Bytes)
723+
parts = line.split("(")
724+
for part in parts:
725+
if "bytes" in part.lower():
726+
size_str = part.split(" ")[0].replace(",", "")
727+
size_bytes = int(size_str)
728+
break
729+
if size_bytes > 0:
730+
break
731+
except Exception as e:
732+
progress_callback(f"Could not determine device size: {e}")
733+
return
734+
735+
if size_bytes == 0:
736+
progress_callback("Could not determine device size.")
737+
return
738+
739+
total_size_mb = size_bytes / (1024 * 1024)
740+
699741
command = ["sudo", "dd", f"if={disk_device}",
700742
f"of={output_image}", "bs=4M", "status=progress"]
701743
process = subprocess.Popen(
702744
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
703745

704746
start_time = datetime.now()
705-
total_size_bytes = disk_size_gb * 1024 * 1024 * 1024
706-
total_size_mb = disk_size_gb * 1024
707-
708747
progress = 0
709748

710749
while True:
@@ -717,7 +756,7 @@ def create_disk_image(disk_device, output_image, disk_size_gb, progress_callback
717756
copied_bytes = int(match.group(1))
718757
copied_mb = copied_bytes / (1024 * 1024)
719758

720-
progress = (copied_bytes / total_size_bytes) * 100
759+
progress = (copied_bytes / size_bytes) * 100
721760
progress_bar["value"] = progress
722761

723762
elapsed_time = datetime.now() - start_time
@@ -732,7 +771,7 @@ def create_disk_image(disk_device, output_image, disk_size_gb, progress_callback
732771

733772
if copied_bytes > 0 and elapsed_time.total_seconds() > 0:
734773
remaining_time = (elapsed_time.total_seconds(
735-
) / copied_bytes) * (total_size_bytes - copied_bytes)
774+
) / copied_bytes) * (size_bytes - copied_bytes)
736775
time_label.config(
737776
text=f"Estimated Time Remaining: {str(timedelta(seconds=int(remaining_time)))}")
738777
else:
@@ -1198,11 +1237,12 @@ def setup_disk_imaging_tab(self):
11981237
highlightthickness=0)
11991238
browse_btn.place(x=700, y=350)
12001239

1201-
tk.Label(self.tab1, text="Disk Size (GB):",
1202-
font=label_font, bg="#530a0a", fg=label_color).place(x=330, y=400)
1203-
1204-
self.disk_size_entry = tk.Entry(self.tab1, width=20, font=label_font)
1205-
self.disk_size_entry.place(x=480, y=400)
1240+
# --- REMOVE Disk Size (GB) FIELD ---
1241+
# tk.Label(self.tab1, text="Disk Size (GB):",
1242+
# font=label_font, bg="#530a0a", fg=label_color).place(x=330, y=400)
1243+
# self.disk_size_entry = tk.Entry(self.tab1, width=20, font=label_font)
1244+
# self.disk_size_entry.place(x=480, y=400)
1245+
# ------------------------------------
12061246

12071247
self.progress_label = tk.Label(self.tab1, text="",
12081248
font=label_font, bg="#530a0a", fg=label_color)
@@ -1243,17 +1283,10 @@ def start_disk_imaging(self):
12431283
"""Start the disk imaging process in a background thread."""
12441284
disk_device = self.drive_var.get()
12451285
output_image = self.output_image_entry.get()
1246-
disk_size_gb = self.disk_size_entry.get()
12471286

1248-
if not disk_device or not output_image or not disk_size_gb:
1287+
if not disk_device or not output_image:
12491288
messagebox.showerror(
1250-
"Error", "Please select a flash drive, provide an output image path, and enter the disk size.")
1251-
return
1252-
1253-
try:
1254-
disk_size_gb = float(disk_size_gb)
1255-
except ValueError:
1256-
messagebox.showerror("Error", "Disk size must be a valid number.")
1289+
"Error", "Please select a flash drive and provide an output image path.")
12571290
return
12581291

12591292
self.mb_label.place(x=460, y=450)
@@ -1268,7 +1301,7 @@ def start_disk_imaging(self):
12681301

12691302
imaging_thread = threading.Thread(
12701303
target=create_disk_image,
1271-
args=(disk_device, output_image, disk_size_gb, self.update_progress,
1304+
args=(disk_device, output_image, self.update_progress,
12721305
self.progress_bar, self.mb_label, self.speed_label, self.time_label),
12731306
daemon=True
12741307
)

0 commit comments

Comments
 (0)