У меня есть приложение, которое общается с драйвером и меняет байты. Из минусов - оно работает, если запущен один экземпляр l2.bin, а я могу запустить максимум 2 экземпляра. Нужно, чтобы программа отслеживала новые pid процессов l2.bin. Если появляется новый процесс - производится его патчинг. Помни, что я могу запустить максимум 2 процесса. Следовательно, если 2 процесса запущено, то отслеживать новые не нужно, если один процесс закроется, нужно следить за процессами и быть готовым, что запустится второй
 #include <iostream>
#include <iomanip>
#include <future>
#include <algorithm>
#include <string>
#include <memory>
#include <mutex>
#include <vector>
#include <Windows.h>
#include <TlHelp32.h>
#include "driver_code.h"

class MemoryPatcher {
    HANDLE driver_handle;
    DWORD pid;
    std::mutex print_mutex;
    std::uintptr_t turnback_patch_address = 0;
    bool is_patched_to_31 = false;

public:
    MemoryPatcher(HANDLE driverHandle, DWORD processId) : driver_handle(driverHandle), pid(processId) {}

    bool apply_patch(const std::string& patch_name, const std::vector<BYTE>& sequence, const std::vector<BYTE>& patch, std::uintptr_t start_address, std::uintptr_t end_address, int target_occurrence = 1) {
        std::lock_guard<std::mutex> guard(print_mutex);
        std::cout << "[+] Attempting to apply " << patch_name << " patch\n";
        int occurrence_count = 0;
        auto current_address = start_address;

        while (current_address < end_address) {
            auto found_address = driver::find_memory_sequence(driver_handle, pid, sequence, current_address, end_address);
            if (found_address != 0) {
                occurrence_count++;
                if (occurrence_count == target_occurrence) {
                    std::cout << "[+] " << patch_name << " sequence found at: 0x" << std::uppercase << std::hex << found_address << std::dec << "\n";
                    if (driver::replace_memory_sequence(driver_handle, found_address, patch)) {
                        std::cout << "[+] " << patch_name << " sequence has been successfully replaced!\n";
                        if (patch_name == "turnback" && occurrence_count == target_occurrence) {
                            turnback_patch_address = found_address;
                            std::cout << "[+] vision address set to: 0x" << std::hex << turnback_patch_address << std::dec << "\n";
                        }
                        return true;
                    }
                    else {
                        std::cout << "[-] Failed to apply " << patch_name << ".\n";
                            return false;
                    }
                }
                current_address = found_address + sequence.size();
            }
            else {
                break;
            }
        }
        std::cout << "[-] " << patch_name << " sequence not found.\n";
        return false;
    }

    void toggle_vision() {
        std::lock_guard<std::mutex> guard(print_mutex);
        if (turnback_patch_address == 0) {
            std::cout << "[-] vision address is not set.\n";
            return;
        }

        std::vector<BYTE> new_patch;
        std::string vision_state_before_toggle = is_patched_to_31 ? "OFF -" : "ON +";

        if (is_patched_to_31) {
            new_patch = { 0x00, 0x00, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00, 0x70, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x00, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

        } else {
            new_patch = { 0x00, 0x00, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00, 0x70, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
        }

        if (driver::replace_memory_sequence(driver_handle, turnback_patch_address, new_patch)) {
            is_patched_to_31 = !is_patched_to_31;
            std::string vision_state_after_toggle = is_patched_to_31 ? "OFF -" : "ON +";
            std::cout << "[+] vision " << vision_state_after_toggle << "\n";
        }
        else {
            std::cout << "[-] failed to toggle Vision.\n";
        }
    }
};

int main() {
    setlocale(LC_ALL, "Russian");
    std::cout << "\n"
"  /\\ o o o\\ \n"
" /o \\ o o o\\_______\n"
"<    >------>   o /|     Zonner сосать\n"
" \\ o/  o   /_____/o|          , ,__\n"
"  \\/______/     |oo|         c''   \)? \n"
"        |   o   |o/            ''''\n"
"        |_______|/\n" << std::endl;

    auto pid = ProcessHelper::getProcessId(L"l2.bin");
    if (pid == 0) {
        std::cout << "[-] Failed to find l2.bin.\n";
        std::cin.get();
        return 1;
    }

    HANDLE driver_handle = CreateFile(L"\\\\.\\MotorolaDriver", GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
    if (driver_handle == INVALID_HANDLE_VALUE) {
        std::cout << "[-] Failed to create our driver handle.\n";
        std::cin.get();
        return 1;
    }

    if (driver::attach_to_process(driver_handle, pid)) {
        std::cout << "[+] Attachment successful.\n";
    }
    else {
        std::cout << "[-] Failed to attach to process.\n";
        std::cin.get();
        return 1;
    }

    MemoryPatcher patcher(driver_handle, pid);

    std::vector<BYTE> page_up_down_bytes = { 0x44, 0x00, 0x65, 0x00, 0x62, 0x00, 0x75, 0x00, 0x67, 0x00, 0x4D, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x75, 0x00, 0x2E, 0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, 0x00, 0x78, 0x00, 0x65, 0x00, 0x64, 0x00, 0x44, 0x00, 0x65, 0x00, 0x66, 0x00, 0x61, 0x00, 0x75, 0x00, 0x6C, 0x00, 0x74, 0x00, 0x43, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x46, 0x00, 0x69, 0x00, 0x78, 0x00, 0x65, 0x00, 0x64, 0x00, 0x44, 0x00, 0x65, 0x00, 0x66, 0x00, 0x61, 0x00, 0x75, 0x00, 0x6C, 0x00, 0x74, 0x00, 0x43, 0x00, 0x61, 0x00, 0x6D, 0x00, 0x65, 0x00, 0x72, 0x00, 0x61, 0x00, 0x20, 0x00, 0x55, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x65, 0x00, 0x79, 0x00, 0x62, 0x00, 0x6F, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x50, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x4D, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    std::vector<BYTE> page_up_down_patch = { 0x44, 0x00, 0x65, 0x00, 0x62, 0x00, 0x75, 0x00, 0x67, 0x00, 0x4D, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x75, 0x00, 0x2E, 0x00, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C, 0x00, 0x32, 0x00, 0x52, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x68, 0x00, 0x6F, 0x00, 0x77, 0x00, 0x20, 0x00, 0x70, 0x00, 0x61, 0x00, 0x72, 0x00, 0x74, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6C, 0x00, 0x65, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4B, 0x00, 0x65, 0x00, 0x79, 0x00, 0x62, 0x00, 0x6F, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x50, 0x00, 0x65, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x61, 0x00, 0x6E, 0x00, 0x65, 0x00, 0x6E, 0x00, 0x74, 0x00, 0x4D, 0x00, 0x6F, 0x00, 0x76, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    std::vector<BYTE> turnback_bytes = { 0x00, 0x00, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00, 0x70, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x75, 0x00, 0x72, 0x00, 0x6E, 0x00, 0x42, 0x00, 0x61, 0x00, 0x63, 0x00, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x00 };
    std::vector<BYTE> turnback_patch = { 0x00, 0x00, 0x00, 0x73, 0x00, 0x74, 0x00, 0x61, 0x00, 0x74, 0x00, 0x20, 0x00, 0x66, 0x00, 0x70, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x6D, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

    // Асинхронно применяем патчи
    auto pageUpDownPatchFuture = std::async(std::launch::async, &MemoryPatcher::apply_patch, &patcher, "page up - page down", page_up_down_bytes, page_up_down_patch, 0x00000000, 0x7FFFFFFF, 1);
    auto turnBackPatchFuture = std::async(std::launch::async, &MemoryPatcher::apply_patch, &patcher, "turnback", turnback_bytes, turnback_patch, 0x0000000, 0x7FFFFFFF, 2);

    // Ожидаем завершения
    pageUpDownPatchFuture.wait();
    turnBackPatchFuture.wait();

    std::cout << "\n[+] Waiting for vision action...\n";

    // Цикл для отслеживания нажатия кнопки колесика мыши
    while (true) {
        Sleep(100); // задержка для снижения загрузки CPU
        if ((GetAsyncKeyState(VK_MBUTTON) & 0x8000) != 0) {
            patcher.toggle_vision();
            Sleep(340); // чтобы избежать ложных нажатий
        }
    }
    CloseHandle(driver_handle);
    std::cin.get();
    return 0;
}