android-malware-detection / BACKEND /setup_dataset.py
nayab zahoor
Deploy: Full-Stack App without large binary images
9f26583
Raw
History Blame Contribute Delete
4.88 kB
import os
import zipfile
from app.preprocessing.apk_pipeline import apk_to_image_pipeline
# =========================
# SETTINGS
# =========================
RAW_APKS_DIR = "data/raw_apks"
GRAY_IMAGES_DIR = "data/grayscale_images"
TEMP_DIR = "temp"
FINAL_SIZE = (300, 300)
# Target number of grayscale images per family
TARGET_IMAGES_PER_FAMILY = 20
# Families to process
FAMILIES = ["benign", "banking", "smsware", "adware", "riskware"]
def ensure_dir(path: str):
os.makedirs(path, exist_ok=True)
def is_valid_apk(file_path: str) -> bool:
"""
Check file validity by trying to open it as APK/ZIP
and verifying that at least one .dex exists.
Extension does not matter.
"""
try:
with zipfile.ZipFile(file_path, "r") as zip_ref:
names = zip_ref.namelist()
for name in names:
if name.lower().endswith(".dex"):
return True
except Exception:
return False
return False
def count_existing_images(folder: str) -> int:
"""Count PNG files in a directory."""
if not os.path.isdir(folder):
return 0
return len([f for f in os.listdir(folder) if f.lower().endswith(".png")])
def main():
ensure_dir(RAW_APKS_DIR)
ensure_dir(GRAY_IMAGES_DIR)
ensure_dir(TEMP_DIR)
total_files = 0
total_converted = 0
total_skipped = 0
total_failed = 0
print("\n========== APK TO GRAYSCALE DATASET SETUP ==========")
print(f"Target images per family: {TARGET_IMAGES_PER_FAMILY}\n")
for family in FAMILIES:
input_family_dir = os.path.join(RAW_APKS_DIR, family)
output_family_dir = os.path.join(GRAY_IMAGES_DIR, family)
ensure_dir(output_family_dir)
# Count existing images
existing = count_existing_images(output_family_dir)
needed = TARGET_IMAGES_PER_FAMILY - existing
if needed <= 0:
print(f"\n--- Family: {family} ---")
print(f"Already have {existing} images (target {TARGET_IMAGES_PER_FAMILY}). Skipping.")
continue
if not os.path.isdir(input_family_dir):
print(f"[WARNING] Family folder not found: {input_family_dir}")
continue
files = [
f for f in os.listdir(input_family_dir)
if os.path.isfile(os.path.join(input_family_dir, f))
]
print(f"\n--- Processing family: {family} ---")
print(f"Input folder : {input_family_dir}")
print(f"Output folder: {output_family_dir}")
print(f"Existing images: {existing}")
print(f"Need {needed} more to reach {TARGET_IMAGES_PER_FAMILY}")
print(f"Available raw APKs: {len(files)}")
family_converted = 0
family_skipped = 0
family_failed = 0
# Process files until we have enough successful conversions
for file_name in files:
# Stop if we already reached the target
if family_converted >= needed:
break
total_files += 1
file_path = os.path.join(input_family_dir, file_name)
image_name = os.path.splitext(file_name)[0] + ".png"
output_image_path = os.path.join(output_family_dir, image_name)
# Skip if output already exists (to avoid reprocessing)
if os.path.isfile(output_image_path):
print(f"[SKIP] Already exists: {image_name}")
continue
if not is_valid_apk(file_path):
print(f"[SKIPPED] Not a valid APK: {file_name}")
total_skipped += 1
family_skipped += 1
continue
try:
apk_to_image_pipeline(
apk_path=file_path,
temp_dir=TEMP_DIR,
output_image_path=output_image_path,
final_size=FINAL_SIZE,
)
print(f"[OK] {file_name} -> {image_name}")
total_converted += 1
family_converted += 1
except Exception as e:
print(f"[FAILED] {file_name}: {e}")
total_failed += 1
family_failed += 1
print(f"\nFamily summary: {family}")
print(f"Converted this run: {family_converted}")
print(f"Skipped (invalid APK): {family_skipped}")
print(f"Failed (conversion error): {family_failed}")
print(f"Total images now in output: {existing + family_converted} / {TARGET_IMAGES_PER_FAMILY}")
print("\n========== FINAL DATASET REPORT ==========")
print(f"Total files processed (across all families): {total_files}")
print(f"Total converted (new images): {total_converted}")
print(f"Total skipped (invalid APKs): {total_skipped}")
print(f"Total failed (conversion errors): {total_failed}")
print("\nDone.")
if __name__ == "__main__":
main()