Çözüldü Windows Gezgini üzerinde tıklanan programların gerçek zamanlı olarak dosya yolunu edinme

Bu konu çözüldü olarak işaretlenmiştir. Çözülmediğini düşünüyorsanız konuyu rapor edebilirsiniz.
Katılım
12 Mayıs 2016
Mesajlar
1.558
Çözümler
5
Python:
import os
import win32file
import win32con
import win32gui
import win32api
import win32process
from parseJson import ParseJson
import pygetwindow as gw
import pynput.mouse
import threading
from queue import Queue

FILE_ACTION_ADDED = 0x00000001
FILE_ACTION_REMOVED = 0x00000002
FILE_ACTION_MODIFIED = 0x00000003

def systemWatcher(XylentScanner, SYSTEM_DRIVE, thread_resume):
    XYLENT_SCAN_CACHE = ParseJson('./config', 'xylent_scancache', {})
    XYLENT_CACHE_MAXSIZE = 500000  # 500KB
    file_queue = Queue()

    def on_mouse_click(x, y, button, pressed):
        if pressed:
            path_to_scan = get_file_path_from_click(x, y)
            print(f"Mouse clicked at ({x}, {y}) on file: {path_to_scan}")

            # Add file to the queue for processing in the main thread
            file_queue.put(path_to_scan)

    def get_file_path_from_click(x, y):
        hwnd = win32gui.WindowFromPoint((x, y))
        pid = win32process.GetWindowThreadProcessId(hwnd)[1]
        handle = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, False, pid)
        return win32process.GetModuleFileNameEx(handle, 0)

    def process_file_queue():
        while thread_resume.is_set():
            try:
                path_to_scan = file_queue.get(timeout=1)  # Timeout to avoid blocking indefinitely
                print(f"Processing file: {path_to_scan}")

                try:
                    if os.path.isfile(path_to_scan):
                        verdict = XylentScanner.scanFile(path_to_scan)
                        XYLENT_SCAN_CACHE.setVal(path_to_scan, verdict)
                except Exception as e:
                    print(e)
                    print(f"Error scanning {path_to_scan}")

            except Queue.Empty:
                pass  # Queue is empty, continue checking

            if os.path.getsize(XYLENT_SCAN_CACHE.PATH) >= XYLENT_CACHE_MAXSIZE:
                XYLENT_SCAN_CACHE.purge()
                print("Purging")

    def file_monitor():
        while thread_resume.is_set():
            # File monitoring
            path_to_watch = SYSTEM_DRIVE + "\\"
            hDir = win32file.CreateFile(
                path_to_watch,
                1,
                win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE | win32con.FILE_SHARE_DELETE,
                None,
                win32con.OPEN_EXISTING,
                win32con.FILE_FLAG_BACKUP_SEMANTICS,
                None
            )

            results = win32file.ReadDirectoryChangesW(
                hDir,
                1024,
                True,
                win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
                win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
                win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
                win32con.FILE_NOTIFY_CHANGE_SIZE |
                win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
                win32con.FILE_NOTIFY_CHANGE_SECURITY |
                FILE_ACTION_ADDED |
                FILE_ACTION_MODIFIED |
                FILE_ACTION_REMOVED,
                None,
                None
            )

            for action, file in results:
                path_to_scan = os.path.join(path_to_watch, file)
                print(path_to_scan)  # Print the path for debugging purposes

                # Add file to the queue for processing in the main thread
                file_queue.put(path_to_scan)

            if os.path.getsize(XYLENT_SCAN_CACHE.PATH) >= XYLENT_CACHE_MAXSIZE:
                XYLENT_SCAN_CACHE.purge()
                print("Purging")

    mouse_listener = threading.Thread(target=lambda: pynput.mouse.Listener(on_click=on_mouse_click).start())
    mouse_listener.start()

    monitor_thread = threading.Thread(target=file_monitor)
    monitor_thread.start()

    process_queue_thread = threading.Thread(target=process_file_queue)
    process_queue_thread.start()

    mouse_listener.join()  # Wait for mouse listener to finish (shouldn't happen in this case)
    monitor_thread.join()  # Wait for file monitor to finish
    process_queue_thread.join()  # Wait for file processing thread to finish

    print("RTP waiting to start...")

Mesela Windows Gezgini üzerinde a.exe'ye tıkladım. Bunu antivirüs motoru nasıl elde edebilir? Antivirüs motoru yapıyorum da. Antivirüs böyle:
1703498450007.png
 
Çözüm
Python ile yapılamaz, çözümü kaldırman sadece bu konuyu okuyan başka kişilere boş ümitler verip yanlış yere yönlendirecektir. Python asla Low-level call hooking için kullanılamaz, özellikle bahsedilen fonksiyonlar yukarıdaki gibi kritik fonksiyonlarsa C/++ harici alternatifin yok.
Python ile bunu yapabileceğini iddia ederek sadece konuya ne kadar uzak olduğunu gösteriyorsun.

"Bu kadar bilgiliysen neden yazmıyorsun" derken yazmadığımı nereden biliyorsun? Veya neden yazayım? Belki zaten benim işim budur? Veya tam tersi?
Benim amacım dosya açılıp açılmadığı kontrol etmek tıklanıp tıklanmadığını kontrol etmek saçmaymış onu fark ettim. Antivirüsler bunu yapmıyor. clamonacc bunu Linux üzerinde yapıyor. Windows üzerinde yapmak mümkünmüş. Monitör ediyorsun C:\ klasörünü öyle.

Kod:
import os
import psutil
import time

def find_processes_opening_files(folder_path):
    processes = []
    for process in psutil.process_iter(['pid', 'name']):
        try:
            open_files = process.open_files()
            for file in open_files:
                if folder_path.lower() in file.path.lower():
                    processes.append({
                        'pid': process.info['pid'],
                        'name': process.info['name'],
                        'file_path': file.path,
                    })
        except (psutil.AccessDenied, psutil.NoSuchProcess, psutil.ZombieProcess):
            pass
    return processes

if __name__ == "__main__":
    target_folder_path = r'C:\Users'

    print(f"Monitoring for processes opening files in the {target_folder_path} directory")

    try:
        while True:
            processes = find_processes_opening_files(target_folder_path)
            if processes:
                print("Processes opening files:")
                for proc in processes:
                    print(f"- PID: {proc['pid']}, Name: {proc['name']}, File Path: {proc['file_path']}")
            else:
                print("No processes opening files.")
            time.sleep(1)
    except KeyboardInterrupt:
        pass
Konu çözülmüştür.

Kodu biraz geliştirince yenisini atacağım sürekli ama öne çıkarmayacağım konuyu.

Python:
import psutil
import time
import json
from notifypy import Notify

NEW_PROCESSES_FILE = "new_processes.json"

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    return set((p.info['name'], p.info['exe']) for p in psutil.process_iter(['name', 'exe']))

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            message = "\n".join([f"Path: {exe}" for name, exe in newly_started_processes])
            print("Newly started processes:", newly_started_processes)
            send_notification("New Processes", message)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()
Bu kadar yeter.

Kardeşim şimdi bu yapanı bulamaz diyenlere:
Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import win32security

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    return set((p.info['name'], p.info['exe'], p.pid, p.ppid()) for p in psutil.process_iter(['name', 'exe', 'pid', 'ppid']))

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        print(f"Error getting parent process info for PID {pid}: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        # Get the security identifier (SID) of the user
                        user_sid = data[1]

                        # Convert the SID to a username
                        username, _, _ = win32security.LookupAccountSid(None, win32security.GetBinarySid(user_sid))

                        return username

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            messages = []
            for name, exe, pid, parent_pid in newly_started_processes:
                if exe not in printed_processes:
                    # Print the running file only once
                    print(f"Running File: {exe}")
                    printed_processes.add(exe)

                parent_process_info = get_parent_process_info(pid)
                if parent_process_info is None:
                    continue  # Skip printing if parent process info is None

                parent_path = parent_process_info['exe']

                # Check if parent and child have the same location
                if parent_path != "Unknown" and exe.startswith(parent_path):
                    continue  # Skip printing if they have the same location

                # Check if parent and child have the same full path
                if os.path.abspath(exe) == os.path.abspath(parent_path):
                    continue  # Skip printing if they have the same full path

                # Retrieve the username from Windows logs
                user = get_user_from_event_log(exe)

                messages.append(f"Path: {exe}, Parent Process Path: {parent_path}, User: {user}")

                # Send notification
                send_notification("New Process Detected", f"Path: {exe}, Parent Process Path: {parent_path}, User: {user}")

            console_output = "\n".join(messages)
            print("Console Output:", console_output)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()

Abi şaka mı ya wscript.exe'yi başlatan explorer.exe evet doğru ama onun kodu prank.vbs'den geliyor.

Konu kesin olarak çözüldü: New Process Detected: Path: C:\Windows\System32\wscript.exe, Parent Process Path: C:\Windows\explorer.exe, Command Line: ('C:\\Windows\\System32\\WScript.exe', 'C:\\Users\\victim\\Desktop\\prank.vbs') Oha işe yaradı. Sonunda be.
Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import win32security

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)
        
def get_running_processes():
    processes = set()
    for p in psutil.process_iter(['name', 'exe', 'cmdline', 'pid', 'ppid']):
        try:
            if p.info is not None and 'name' in p.info and 'exe' in p.info:
                name = p.info['name']
                exe = p.info['exe']
                cmdline = tuple(p.info.get('cmdline', []))
                pid = p.pid
                ppid = p.ppid()
                processes.add((name, exe, cmdline, pid, ppid))
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass  # Skip processes that are inaccessible or no longer exist
        except Exception as e:
            print(f"Error getting process info: {e}")
    return processes

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'cmdline': parent_process.cmdline(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        print(f"Error getting parent process info for PID {pid}: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        return "Unknown"

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            messages = []
            for name, exe, cmdline, pid, parent_pid in newly_started_processes:
                if exe not in printed_processes:
                    # Print the running file only once
                    print(f"Running File: {exe}")
                    printed_processes.add(exe)

                parent_process_info = get_parent_process_info(pid)
                if parent_process_info is None:
                    continue  # Skip printing if parent process info is None

                parent_path = parent_process_info['exe']

                # Check if parent and child have the same location
                if parent_path != "Unknown" and exe.startswith(parent_path):
                    continue  # Skip printing if they have the same location

                # Check if parent and child have the same full path
                if os.path.abspath(exe) == os.path.abspath(parent_path):
                    continue  # Skip printing if they have the same full path

                # Retrieve the username from Windows logs
                user = get_user_from_event_log(exe)

                message = f"Path: {exe}, Parent Process Path: {parent_path}, Command Line: {cmdline}"

                # Print to the console
                print("New Process Detected:", message)

                messages.append(message)

            # Send notification
            if messages:
                console_output = "\n".join(messages)
                send_notification("New Process Detected", console_output)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()

Python ile yapılamaz, çözümü kaldırman sadece bu konuyu okuyan başka kişilere boş ümitler verip yanlış yere yönlendirecektir. Python asla Low-level call hooking için kullanılamaz, özellikle bahsedilen fonksiyonlar yukarıdaki gibi kritik fonksiyonlarsa C/++ harici alternatifin yok.
Python ile bunu yapabileceğini iddia ederek sadece konuya ne kadar uzak olduğunu gösteriyorsun.

"Bu kadar bilgiliysen neden yazmıyorsun" derken yazmadığımı nereden biliyorsun? Veya neden yazayım? Belki zaten benim işim budur? Veya tam tersi?
Yardımın için teşekkür ederim ama sorunu çözdüm pythonla, inanmıyorsan bakabilirsin. Ben inanmıyorum nasıl becerdiğime. Hala şoktayım. Bugün olan ikinci şokum.

Cachy OS geliştiricis jomo'ya teşekkür ederim. Log alma fikrini o söylemişti aylar önce ama ben pratiğe geçirmemiştim.

Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import concurrent.futures

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    processes = set()
    for p in psutil.process_iter(['name', 'exe', 'cmdline', 'pid', 'ppid']):
        try:
            if p.info is not None and 'name' in p.info and 'exe' in p.info:
                name = p.info['name']
                exe = p.info['exe']
                cmdline = tuple(p.info.get('cmdline', []))
                pid = p.pid
                ppid = p.ppid()
                processes.add((name, exe, cmdline, pid, ppid))
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass  # Skip processes that are inaccessible or no longer exist
        except Exception as e:
            print(f"Error getting process info: {e}")
    return processes

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'cmdline': parent_process.cmdline(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        pass
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        return "Unknown"

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def process_checker(process_info, printed_processes):
    name, exe, cmdline, pid, parent_pid = process_info

    if exe not in printed_processes:
        # Print the running file only once
        print(f"Running File: {exe}")
        printed_processes.add(exe)

    parent_process_info = get_parent_process_info(pid)
    if parent_process_info is None or parent_process_info.get('exe') is None:
        return  # Skip processing if parent process info is None or has no executable information

    parent_path = parent_process_info['exe']

    # Check if parent and child have the same location
    if parent_path != "Unknown" and exe.startswith(parent_path):
        return  # Skip processing if they have the same location

    # Check if parent and child have the same full path
    if os.path.abspath(exe) == os.path.abspath(parent_path):
        return  # Skip processing if they have the same full path

    # Retrieve the username from Windows logs
    user = get_user_from_event_log(exe)

    message = f"Path: {exe}, Parent Process Path: {parent_path}, Command Line: {cmdline}"

    # Print to the console
    print("New Process Detected:", message)

    # Send notification
    send_notification("New Process Detected", message)

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            with concurrent.futures.ThreadPoolExecutor() as executor:
                executor.map(lambda info: process_checker(info, printed_processes), newly_started_processes)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()
Çok fazla bildirim geliyor birde sanki yeni işlemler yerine eskiden yürütülmüş yeni işlemleri bakıyor yani loga göre bakıyor gibi. Onu düzeltmek zaman alır neyse benden bu kadar yeter daha uzatmayacağım. Bundan daha iyi kod arıyorsanız kodun son halini atabilirim. Şu anlık elimde olan son kod bu ama ileride değişecektir illa.

Pardon yokmuş öyle bir şey meğerse prank.vbs null hatası vermiş ondan böyle bir ekran çıkmış. Neyse kodda sorun yok gibi.
Python ile yapılabilecek bir iş değil, en fazla şu an kodunda yaptığın gibi SystemWatcher eklenip yeni işlem (process) başlatıldığında tarama yaparsın ama "antivirüs"ün bundan haberi olduğu zaman iş işten geçmiş oluyor.

Eğer bu tür spesifik Windows davranışlarını yakalamak istiyorsan öncelikle Python'u bırakman lazım çünkü Python saniyede belki de binlerce fonksiyon çağrısını intercept edemez.

Python'u bıraktıktan sonra C++ öğrenip ntdll içerisindeki NtCreateUserProcess metodunu hook'layıp antivirüsün işlemi üzerinden proxy etmen lazım.



1703499367973.png


Bu proxy işlemi sırasında çalışma yolu, dosya adı gibi bilgiler bulunabilir ve antivirüs tarafından izin verilirse; call, Ntdll'den Ntoskrnl'ye aktarılır ve Windows tarafından işlem başlatılır.

Konuyu C++ kategorisinde açsan belki daha detaylı yardım alabilirdin.
 
Son düzenleyen: Moderatör:
Python ile yapılabilecek bir iş değil, en fazla şu an kodunda yaptığın gibi SystemWatcher eklenip yeni işlem (process) başlatıldığında tarama yaparsın ama "antivirüs"ün bundan haberi olduğu zaman iş işten geçmiş oluyor.

Eğer bu tür spesifik Windows davranışlarını yakalamak istiyorsan öncelikle Python'u bırakman lazım çünkü Python saniyede belki de binlerce fonksiyon çağrısını intercept edemez.

Python'u bıraktıktan sonra C++ öğrenip ntdll içerisindeki NtCreateUserProcess metodunu hook'layıp antivirüsün işlemi üzerinden proxy etmen lazım

Bu proxy işlemi sırasında çalışma yolu, dosya adı gibi bilgiler bulunabilir ve antivirüs tarafından izin verilirse; call, Ntdll'den Ntoskrnl'ye aktarılır ve Windows tarafından işlem başlatılır.

Konuyu C++ kategorisinde açsan belki daha detaylı yardım alabilirdin
Sanırım Rust kullanmak lazım ve entegrasyon yapmak lazım bunun üzerine.
 
Sanırım Rust kullanmak lazım ve entegrasyon yapmak lazım bunun üzerine.

Hayır, C veya C++ kullanmak lazım. Rust'u nereden duydun bilmiyorum ama Win API ile uğraşıyorsan Windows'un yazıldığı C/++ dillerinde kod yazman lazım, Rust'da yazarsan ffi gibi modüller kullanman gerekebiliyor, ve hiçbir Windows documentation'u Rust ile yazılmadığı için tek bir satır anlamayacaksın.
 
Hayır, C veya C++ kullanmak lazım. Rust'u nereden duydun bilmiyorum ama Win API ile uğraşıyorsan Windows'un yazıldığı C/++ dillerinde kod yazman lazım, Rust'da yazarsan ffi gibi modüller kullanman gerekebiliyor, ve hiçbir Windows documentation'u Rust ile yazılmadığı için tek bir satır anlamayacaksın.
C++'da YARA dilini kullanan şeyi bulamadım birde Hintli arkadaş ona geçecekti ve Micah öneriyordu Rust'u. GitHub - Hugal31/yara-rust: Rust bindings for VirusTotal/Yara Birde buna muhtaç kalırsam diye düşünüyordum ama C++'da olur sorun değil. Güvenlik sorunlarını hallederim.
 
Son düzenleyen: Moderatör:
YARA mı? 😂 Normal RegEx'in biraz farklısı işte, kendi başına bir dil değil. Bu tür pattern matching işlemleri ile zaman kaybediyorsun.

Tek o yok. SIGMA vb.'de var ama onları kullanmıyorum. Bir sürü kural topladığım için tespit oranı yüksek.

Bir de bu kadar bilgiliysen niye kendin yazmıyorsun?

Bu arada Python ile yapılabiliyormuş ondan çözümü kaldırıyım.
 
Son düzenleyen: Moderatör:
Bir de bu kadar bilgiliysen niye kendin yazmıyorsun?

Bu arada Python ile yapılabiliyormuş ondan çözümü kaldırıyım.

Python ile yapılamaz, çözümü kaldırman sadece bu konuyu okuyan başka kişilere boş ümitler verip yanlış yere yönlendirecektir. Python asla Low-level call hooking için kullanılamaz, özellikle bahsedilen fonksiyonlar yukarıdaki gibi kritik fonksiyonlarsa C/++ harici alternatifin yok.
Python ile bunu yapabileceğini iddia ederek sadece konuya ne kadar uzak olduğunu gösteriyorsun.

"Bu kadar bilgiliysen neden yazmıyorsun" derken yazmadığımı nereden biliyorsun? Veya neden yazayım? Belki zaten benim işim budur? Veya tam tersi?
 
Python ile yapılamaz, çözümü kaldırman sadece bu konuyu okuyan başka kişilere boş ümitler verip yanlış yere yönlendirecektir. Python asla Low-level call hooking için kullanılamaz, özellikle bahsedilen fonksiyonlar yukarıdaki gibi kritik fonksiyonlarsa C/++ harici alternatifin yok.
Python ile bunu yapabileceğini iddia ederek sadece konuya ne kadar uzak olduğunu gösteriyorsun.

"Bu kadar bilgiliysen neden yazmıyorsun" derken yazmadığımı nereden biliyorsun? Veya neden yazayım? Belki zaten benim işim budur? Veya tam tersi?
Benim amacım dosya açılıp açılmadığı kontrol etmek tıklanıp tıklanmadığını kontrol etmek saçmaymış onu fark ettim. Antivirüsler bunu yapmıyor. clamonacc bunu Linux üzerinde yapıyor. Windows üzerinde yapmak mümkünmüş. Monitör ediyorsun C:\ klasörünü öyle.

Kod:
import os
import psutil
import time

def find_processes_opening_files(folder_path):
    processes = []
    for process in psutil.process_iter(['pid', 'name']):
        try:
            open_files = process.open_files()
            for file in open_files:
                if folder_path.lower() in file.path.lower():
                    processes.append({
                        'pid': process.info['pid'],
                        'name': process.info['name'],
                        'file_path': file.path,
                    })
        except (psutil.AccessDenied, psutil.NoSuchProcess, psutil.ZombieProcess):
            pass
    return processes

if __name__ == "__main__":
    target_folder_path = r'C:\Users'

    print(f"Monitoring for processes opening files in the {target_folder_path} directory")

    try:
        while True:
            processes = find_processes_opening_files(target_folder_path)
            if processes:
                print("Processes opening files:")
                for proc in processes:
                    print(f"- PID: {proc['pid']}, Name: {proc['name']}, File Path: {proc['file_path']}")
            else:
                print("No processes opening files.")
            time.sleep(1)
    except KeyboardInterrupt:
        pass
Konu çözülmüştür.

Kodu biraz geliştirince yenisini atacağım sürekli ama öne çıkarmayacağım konuyu.

Python:
import psutil
import time
import json
from notifypy import Notify

NEW_PROCESSES_FILE = "new_processes.json"

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    return set((p.info['name'], p.info['exe']) for p in psutil.process_iter(['name', 'exe']))

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            message = "\n".join([f"Path: {exe}" for name, exe in newly_started_processes])
            print("Newly started processes:", newly_started_processes)
            send_notification("New Processes", message)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()
Bu kadar yeter.

Kardeşim şimdi bu yapanı bulamaz diyenlere:
Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import win32security

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    return set((p.info['name'], p.info['exe'], p.pid, p.ppid()) for p in psutil.process_iter(['name', 'exe', 'pid', 'ppid']))

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        print(f"Error getting parent process info for PID {pid}: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        # Get the security identifier (SID) of the user
                        user_sid = data[1]

                        # Convert the SID to a username
                        username, _, _ = win32security.LookupAccountSid(None, win32security.GetBinarySid(user_sid))

                        return username

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            messages = []
            for name, exe, pid, parent_pid in newly_started_processes:
                if exe not in printed_processes:
                    # Print the running file only once
                    print(f"Running File: {exe}")
                    printed_processes.add(exe)

                parent_process_info = get_parent_process_info(pid)
                if parent_process_info is None:
                    continue  # Skip printing if parent process info is None

                parent_path = parent_process_info['exe']

                # Check if parent and child have the same location
                if parent_path != "Unknown" and exe.startswith(parent_path):
                    continue  # Skip printing if they have the same location

                # Check if parent and child have the same full path
                if os.path.abspath(exe) == os.path.abspath(parent_path):
                    continue  # Skip printing if they have the same full path

                # Retrieve the username from Windows logs
                user = get_user_from_event_log(exe)

                messages.append(f"Path: {exe}, Parent Process Path: {parent_path}, User: {user}")

                # Send notification
                send_notification("New Process Detected", f"Path: {exe}, Parent Process Path: {parent_path}, User: {user}")

            console_output = "\n".join(messages)
            print("Console Output:", console_output)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()

Abi şaka mı ya wscript.exe'yi başlatan explorer.exe evet doğru ama onun kodu prank.vbs'den geliyor.

Konu kesin olarak çözüldü: New Process Detected: Path: C:\Windows\System32\wscript.exe, Parent Process Path: C:\Windows\explorer.exe, Command Line: ('C:\\Windows\\System32\\WScript.exe', 'C:\\Users\\victim\\Desktop\\prank.vbs') Oha işe yaradı. Sonunda be.
Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import win32security

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)
        
def get_running_processes():
    processes = set()
    for p in psutil.process_iter(['name', 'exe', 'cmdline', 'pid', 'ppid']):
        try:
            if p.info is not None and 'name' in p.info and 'exe' in p.info:
                name = p.info['name']
                exe = p.info['exe']
                cmdline = tuple(p.info.get('cmdline', []))
                pid = p.pid
                ppid = p.ppid()
                processes.add((name, exe, cmdline, pid, ppid))
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass  # Skip processes that are inaccessible or no longer exist
        except Exception as e:
            print(f"Error getting process info: {e}")
    return processes

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'cmdline': parent_process.cmdline(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        print(f"Error getting parent process info for PID {pid}: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        return "Unknown"

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            messages = []
            for name, exe, cmdline, pid, parent_pid in newly_started_processes:
                if exe not in printed_processes:
                    # Print the running file only once
                    print(f"Running File: {exe}")
                    printed_processes.add(exe)

                parent_process_info = get_parent_process_info(pid)
                if parent_process_info is None:
                    continue  # Skip printing if parent process info is None

                parent_path = parent_process_info['exe']

                # Check if parent and child have the same location
                if parent_path != "Unknown" and exe.startswith(parent_path):
                    continue  # Skip printing if they have the same location

                # Check if parent and child have the same full path
                if os.path.abspath(exe) == os.path.abspath(parent_path):
                    continue  # Skip printing if they have the same full path

                # Retrieve the username from Windows logs
                user = get_user_from_event_log(exe)

                message = f"Path: {exe}, Parent Process Path: {parent_path}, Command Line: {cmdline}"

                # Print to the console
                print("New Process Detected:", message)

                messages.append(message)

            # Send notification
            if messages:
                console_output = "\n".join(messages)
                send_notification("New Process Detected", console_output)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()

Python ile yapılamaz, çözümü kaldırman sadece bu konuyu okuyan başka kişilere boş ümitler verip yanlış yere yönlendirecektir. Python asla Low-level call hooking için kullanılamaz, özellikle bahsedilen fonksiyonlar yukarıdaki gibi kritik fonksiyonlarsa C/++ harici alternatifin yok.
Python ile bunu yapabileceğini iddia ederek sadece konuya ne kadar uzak olduğunu gösteriyorsun.

"Bu kadar bilgiliysen neden yazmıyorsun" derken yazmadığımı nereden biliyorsun? Veya neden yazayım? Belki zaten benim işim budur? Veya tam tersi?
Yardımın için teşekkür ederim ama sorunu çözdüm pythonla, inanmıyorsan bakabilirsin. Ben inanmıyorum nasıl becerdiğime. Hala şoktayım. Bugün olan ikinci şokum.

Cachy OS geliştiricis jomo'ya teşekkür ederim. Log alma fikrini o söylemişti aylar önce ama ben pratiğe geçirmemiştim.

Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import concurrent.futures

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    processes = set()
    for p in psutil.process_iter(['name', 'exe', 'cmdline', 'pid', 'ppid']):
        try:
            if p.info is not None and 'name' in p.info and 'exe' in p.info:
                name = p.info['name']
                exe = p.info['exe']
                cmdline = tuple(p.info.get('cmdline', []))
                pid = p.pid
                ppid = p.ppid()
                processes.add((name, exe, cmdline, pid, ppid))
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass  # Skip processes that are inaccessible or no longer exist
        except Exception as e:
            print(f"Error getting process info: {e}")
    return processes

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'cmdline': parent_process.cmdline(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        pass
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        return "Unknown"

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def process_checker(process_info, printed_processes):
    name, exe, cmdline, pid, parent_pid = process_info

    if exe not in printed_processes:
        # Print the running file only once
        print(f"Running File: {exe}")
        printed_processes.add(exe)

    parent_process_info = get_parent_process_info(pid)
    if parent_process_info is None or parent_process_info.get('exe') is None:
        return  # Skip processing if parent process info is None or has no executable information

    parent_path = parent_process_info['exe']

    # Check if parent and child have the same location
    if parent_path != "Unknown" and exe.startswith(parent_path):
        return  # Skip processing if they have the same location

    # Check if parent and child have the same full path
    if os.path.abspath(exe) == os.path.abspath(parent_path):
        return  # Skip processing if they have the same full path

    # Retrieve the username from Windows logs
    user = get_user_from_event_log(exe)

    message = f"Path: {exe}, Parent Process Path: {parent_path}, Command Line: {cmdline}"

    # Print to the console
    print("New Process Detected:", message)

    # Send notification
    send_notification("New Process Detected", message)

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            with concurrent.futures.ThreadPoolExecutor() as executor:
                executor.map(lambda info: process_checker(info, printed_processes), newly_started_processes)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()
Çok fazla bildirim geliyor birde sanki yeni işlemler yerine eskiden yürütülmüş yeni işlemleri bakıyor yani loga göre bakıyor gibi. Onu düzeltmek zaman alır neyse benden bu kadar yeter daha uzatmayacağım. Bundan daha iyi kod arıyorsanız kodun son halini atabilirim. Şu anlık elimde olan son kod bu ama ileride değişecektir illa.

Pardon yokmuş öyle bir şey meğerse prank.vbs null hatası vermiş ondan böyle bir ekran çıkmış. Neyse kodda sorun yok gibi.
 
Son düzenleme:
Çözüm
Benim amacım dosya açılıp açılmadığı kontrol etmek tıklanıp tıklanmadığını kontrol etmek saçmaymış onu fark ettim. Antivirüsler bunu yapmıyor. clamonacc bunu Linux üzerinde yapıyor. Windows üzerinde yapmak mümkünmüş. Monitör ediyorsun C:\ klasörünü öyle.

Kod:
import os
import psutil
import time

def find_processes_opening_files(folder_path):
    processes = []
    for process in psutil.process_iter(['pid', 'name']):
        try:
            open_files = process.open_files()
            for file in open_files:
                if folder_path.lower() in file.path.lower():
                    processes.append({
                        'pid': process.info['pid'],
                        'name': process.info['name'],
                        'file_path': file.path,
                    })
        except (psutil.AccessDenied, psutil.NoSuchProcess, psutil.ZombieProcess):
            pass
    return processes

if __name__ == "__main__":
    target_folder_path = r'C:\Users'

    print(f"Monitoring for processes opening files in the {target_folder_path} directory")

    try:
        while True:
            processes = find_processes_opening_files(target_folder_path)
            if processes:
                print("Processes opening files:")
                for proc in processes:
                    print(f"- PID: {proc['pid']}, Name: {proc['name']}, File Path: {proc['file_path']}")
            else:
                print("No processes opening files.")
            time.sleep(1)
    except KeyboardInterrupt:
        pass
Konu çözülmüştür.

Kodu biraz geliştirince yenisini atacağım sürekli ama öne çıkarmayacağım konuyu.

Python:
import psutil
import time
import json
from notifypy import Notify

NEW_PROCESSES_FILE = "new_processes.json"

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    return set((p.info['name'], p.info['exe']) for p in psutil.process_iter(['name', 'exe']))

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            message = "\n".join([f"Path: {exe}" for name, exe in newly_started_processes])
            print("Newly started processes:", newly_started_processes)
            send_notification("New Processes", message)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()
Bu kadar yeter.

Kardeşim şimdi bu yapanı bulamaz diyenlere:
Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import win32security

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    return set((p.info['name'], p.info['exe'], p.pid, p.ppid()) for p in psutil.process_iter(['name', 'exe', 'pid', 'ppid']))

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        print(f"Error getting parent process info for PID {pid}: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        # Get the security identifier (SID) of the user
                        user_sid = data[1]

                        # Convert the SID to a username
                        username, _, _ = win32security.LookupAccountSid(None, win32security.GetBinarySid(user_sid))

                        return username

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            messages = []
            for name, exe, pid, parent_pid in newly_started_processes:
                if exe not in printed_processes:
                    # Print the running file only once
                    print(f"Running File: {exe}")
                    printed_processes.add(exe)

                parent_process_info = get_parent_process_info(pid)
                if parent_process_info is None:
                    continue  # Skip printing if parent process info is None

                parent_path = parent_process_info['exe']

                # Check if parent and child have the same location
                if parent_path != "Unknown" and exe.startswith(parent_path):
                    continue  # Skip printing if they have the same location

                # Check if parent and child have the same full path
                if os.path.abspath(exe) == os.path.abspath(parent_path):
                    continue  # Skip printing if they have the same full path

                # Retrieve the username from Windows logs
                user = get_user_from_event_log(exe)

                messages.append(f"Path: {exe}, Parent Process Path: {parent_path}, User: {user}")

                # Send notification
                send_notification("New Process Detected", f"Path: {exe}, Parent Process Path: {parent_path}, User: {user}")

            console_output = "\n".join(messages)
            print("Console Output:", console_output)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()

Abi şaka mı ya wscript.exe'yi başlatan explorer.exe evet doğru ama onun kodu prank.vbs'den geliyor.

Konu kesin olarak çözüldü: New Process Detected: Path: C:\Windows\System32\wscript.exe, Parent Process Path: C:\Windows\explorer.exe, Command Line: ('C:\\Windows\\System32\\WScript.exe', 'C:\\Users\\victim\\Desktop\\prank.vbs') Oha işe yaradı. Sonunda be.
Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import win32security

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)
      
def get_running_processes():
    processes = set()
    for p in psutil.process_iter(['name', 'exe', 'cmdline', 'pid', 'ppid']):
        try:
            if p.info is not None and 'name' in p.info and 'exe' in p.info:
                name = p.info['name']
                exe = p.info['exe']
                cmdline = tuple(p.info.get('cmdline', []))
                pid = p.pid
                ppid = p.ppid()
                processes.add((name, exe, cmdline, pid, ppid))
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass  # Skip processes that are inaccessible or no longer exist
        except Exception as e:
            print(f"Error getting process info: {e}")
    return processes

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'cmdline': parent_process.cmdline(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        print(f"Error getting parent process info for PID {pid}: {e}")
        return None
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        return "Unknown"

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            messages = []
            for name, exe, cmdline, pid, parent_pid in newly_started_processes:
                if exe not in printed_processes:
                    # Print the running file only once
                    print(f"Running File: {exe}")
                    printed_processes.add(exe)

                parent_process_info = get_parent_process_info(pid)
                if parent_process_info is None:
                    continue  # Skip printing if parent process info is None

                parent_path = parent_process_info['exe']

                # Check if parent and child have the same location
                if parent_path != "Unknown" and exe.startswith(parent_path):
                    continue  # Skip printing if they have the same location

                # Check if parent and child have the same full path
                if os.path.abspath(exe) == os.path.abspath(parent_path):
                    continue  # Skip printing if they have the same full path

                # Retrieve the username from Windows logs
                user = get_user_from_event_log(exe)

                message = f"Path: {exe}, Parent Process Path: {parent_path}, Command Line: {cmdline}"

                # Print to the console
                print("New Process Detected:", message)

                messages.append(message)

            # Send notification
            if messages:
                console_output = "\n".join(messages)
                send_notification("New Process Detected", console_output)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()


Yardımın için teşekkür ederim ama sorunu çözdüm pythonla, inanmıyorsan bakabilirsin. Ben inanmıyorum nasıl becerdiğime. Hala şoktayım. Bugün olan ikinci şokum.

Cachy OS geliştiricis jomo'ya teşekkür ederim. Log alma fikrini o söylemişti aylar önce ama ben pratiğe geçirmemiştim.

Python:
import os
import psutil
import time
import json
from notifypy import Notify
import win32evtlog
import concurrent.futures

CONFIG_FOLDER = "config"
NEW_PROCESSES_FILE = os.path.join(CONFIG_FOLDER, "new_processes.json")

# Ensure the config folder exists
if not os.path.exists(CONFIG_FOLDER):
    os.makedirs(CONFIG_FOLDER)

def load_new_processes():
    try:
        with open(NEW_PROCESSES_FILE, "r") as file:
            return json.load(file)
    except (FileNotFoundError, json.JSONDecodeError):
        return []

def save_new_processes(new_processes):
    with open(NEW_PROCESSES_FILE, "w") as file:
        json.dump(new_processes, file)

def get_running_processes():
    processes = set()
    for p in psutil.process_iter(['name', 'exe', 'cmdline', 'pid', 'ppid']):
        try:
            if p.info is not None and 'name' in p.info and 'exe' in p.info:
                name = p.info['name']
                exe = p.info['exe']
                cmdline = tuple(p.info.get('cmdline', []))
                pid = p.pid
                ppid = p.ppid()
                processes.add((name, exe, cmdline, pid, ppid))
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass  # Skip processes that are inaccessible or no longer exist
        except Exception as e:
            print(f"Error getting process info: {e}")
    return processes

def get_parent_process_info(pid):
    try:
        parent_pid = psutil.Process(pid).ppid()
        parent_process = psutil.Process(parent_pid)
        return {
            'name': parent_process.name(),
            'exe': parent_process.exe(),
            'cmdline': parent_process.cmdline(),
            'pid': parent_process.pid,
        }
    except (psutil.NoSuchProcess, psutil.AccessDenied) as e:
        pass
    except Exception as e:
        print(f"An unexpected error occurred while getting parent process info: {e}")
        return None

def get_user_from_event_log(process_name):
    try:
        # Open the Security event log
        handle = win32evtlog.OpenEventLog(None, "Security")

        # Set the starting record to the end of the log
        flags = win32evtlog.EVENTLOG_BACKWARDS_READ | win32evtlog.EVENTLOG_SEQUENTIAL_READ
        total_records = win32evtlog.GetNumberOfEventLogRecords(handle)
        starting_record = total_records

        while True:
            # Read a batch of records
            events = win32evtlog.ReadEventLog(handle, flags, starting_record)

            if not events:
                break

            for event in events:
                # Check if the event is a process creation event (Event ID 4688)
                if event.EventID == 4688:
                    data = event.StringInserts

                    # Check if the process name matches the target process
                    if process_name.lower() in data[5].lower():
                        return "Unknown"

            # Update the starting record for the next batch
            starting_record -= len(events)

        # Close the event log handle
        win32evtlog.CloseEventLog(handle)
    except Exception as e:
        print(f"Error retrieving username from event log: {e}")
        return "Unknown"

def send_notification(title, message):
    notification = Notify()
    notification.title = title
    notification.message = message
    notification.send()

def process_checker(process_info, printed_processes):
    name, exe, cmdline, pid, parent_pid = process_info

    if exe not in printed_processes:
        # Print the running file only once
        print(f"Running File: {exe}")
        printed_processes.add(exe)

    parent_process_info = get_parent_process_info(pid)
    if parent_process_info is None or parent_process_info.get('exe') is None:
        return  # Skip processing if parent process info is None or has no executable information

    parent_path = parent_process_info['exe']

    # Check if parent and child have the same location
    if parent_path != "Unknown" and exe.startswith(parent_path):
        return  # Skip processing if they have the same location

    # Check if parent and child have the same full path
    if os.path.abspath(exe) == os.path.abspath(parent_path):
        return  # Skip processing if they have the same full path

    # Retrieve the username from Windows logs
    user = get_user_from_event_log(exe)

    message = f"Path: {exe}, Parent Process Path: {parent_path}, Command Line: {cmdline}"

    # Print to the console
    print("New Process Detected:", message)

    # Send notification
    send_notification("New Process Detected", message)

def main_program():
    previous_list = set()
    new_processes = load_new_processes()
    printed_processes = set()

    while True:
        # Get current running processes
        current_list = get_running_processes()

        # Compare with the previous list and find new processes
        newly_started_processes = current_list - previous_list
        new_processes.extend(newly_started_processes)

        if newly_started_processes:
            with concurrent.futures.ThreadPoolExecutor() as executor:
                executor.map(lambda info: process_checker(info, printed_processes), newly_started_processes)

        # Update the previous list
        previous_list = current_list

        # Save the updated new processes list to the file
        save_new_processes(new_processes)

        # Wait for a short period before checking again
        time.sleep(0.1)

if __name__ == "__main__":
    # Print the initially running processes
    print("Initially running processes:")
    print(get_running_processes())

    # Run the main program
    main_program()
Çok fazla bildirim geliyor birde sanki yeni işlemler yerine eskiden yürütülmüş yeni işlemleri bakıyor yani loga göre bakıyor gibi. Onu düzeltmek zaman alır neyse benden bu kadar yeter daha uzatmayacağım. Bundan daha iyi kod arıyorsanız kodun son halini atabilirim. Şu anlık elimde olan son kod bu ama ileride değişecektir illa.

Pardon yokmuş öyle bir şey meğerse prank.vbs null hatası vermiş ondan böyle bir ekran çıkmış. Neyse kodda sorun yok gibi.
Tüm bu yazdıkların iyi hoş da, adam dediklerinde hala daha haksız değil.

Python gerçekten bir antivirüs yazmak için yeterli değil.
Python yorumlanan bir dil, Python adamın da dediği gibi saniyede milyonlarca fonksiyon çağrısını işleyemez. Sen şu an eğleniyorsun sadece. Hani bu antivirüs'ü gerçekten iyi bir yere getirmek gibi bi amacın varsa C dillerinden birinde rewrite atmanı öneririm ve pek tabii bu fanboyluğu bırakmanı.

Ha yazdıklarından C dillerinde yetkin olmadığını görüyorum muhtemelen yapamayacaksın(yaparsın ama biraz sancılı olur senin adına) da neyse.
 
Son düzenleyen: Moderatör:

Technopat Haberler

Geri
Yukarı