Дополни код user mode приложения, которое общается с драйвером. Нужно изменить вторую найденную сигнатуру с названием turn_back_signature:"00 00 00 73 00 74 00 61 00 74 00 20 00 66 00 70 00 73 00 00 00 00 00 54 00 75 00 72 00 6E 00 42 00 61 00 63 00 6B 00 00 00 00 00" на turn_back_patch: "00 00 00 73 00 74 00 61 00 74 00 20 00 66 00 70 00 73 00 00 00 00 00 72 00 6D 00 6F 00 64 00 65 00 20 00 35 00 00 00 00 00 00 00".  И используя GetAsyncKeyState меняй по нажатию средней кнопки мыши байт "35" из сигнатуры turn_back_patch на "31" и наоборот. 
#include <iostream>
#include <vector>

#include <Windows.h>
#include<TlHelp32.h>

static DWORD get_process_id(const wchar_t* process_name) {
	DWORD process_id = 0;

	HANDLE snap_shot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
	if (snap_shot == INVALID_HANDLE_VALUE)
		return process_id;

	PROCESSENTRY32W entry = {};
	entry.dwSize = sizeof(decltype(entry));

	if (Process32FirstW(snap_shot, &entry) == TRUE) {
		// Check if the first handle is the one we want.
		if (_wcsicmp(process_name, entry.szExeFile) == 0)
			process_id = entry.th32ProcessID;
		else {
			while (Process32NextW(snap_shot, &entry) == TRUE) {
				if (_wcsicmp(process_name, entry.szExeFile) == 0) {
					process_id = entry.th32ProcessID;
					break;
				}
			}
		}
	}

	CloseHandle(snap_shot);

	return process_id;
}

static std::uintptr_t get_module_base(const DWORD pid, const wchar_t* module_name) {
	std::uintptr_t module_base = 0;

	// Snap-shot of process' modules (dlls).
	HANDLE snap_shot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
	if (snap_shot == INVALID_HANDLE_VALUE)
		return module_base;

	MODULEENTRY32W entry = {};
	entry.dwSize = sizeof(decltype(entry));

	if (Module32FirstW(snap_shot, &entry) == TRUE) {
		if (wcsstr(module_name, entry.szModule) != nullptr)
			module_base = reinterpret_cast<std::uintptr_t>(entry.modBaseAddr);
		else {
			while (Module32NextW(snap_shot, &entry) == TRUE) {
				if (wcsstr(module_name, entry.szModule) != nullptr) {
					module_base = reinterpret_cast<std::uintptr_t>(entry.modBaseAddr);
					break;
				}
			}
		}
	}

	CloseHandle(snap_shot);

	return module_base;
}

struct Request {
	HANDLE process_id;
	PVOID target;
	PVOID buffer;
	SIZE_T size;
	SIZE_T return_size;
};

#define CTL_CODE(DeviceType, Function, Method, Access) (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))

constexpr auto method_buffered = 0;
constexpr auto file_device_unknown = 0x22;
constexpr auto file_any_access = 0;
constexpr auto custom_ioctl_read = CTL_CODE(file_device_unknown, 0x697, method_buffered, file_any_access);
constexpr auto custom_ioctl_write = CTL_CODE(file_device_unknown, 0x698, method_buffered, file_any_access);

bool ReadMemory(HANDLE hDriver, ULONG_PTR ProcessId, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size) {
	Request request{};
	request.process_id = reinterpret_cast<HANDLE>(ProcessId);
	request.target = SourceAddress;
	request.buffer = TargetAddress;
	request.size = Size;

	DWORD returned;
	return DeviceIoControl(hDriver, custom_ioctl_read, &request, sizeof(request), &request, sizeof(request), &returned, nullptr);
}

bool WriteMemory(HANDLE hDriver, ULONG_PTR ProcessId, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size) {
	Request request{};
	request.process_id = reinterpret_cast<HANDLE>(ProcessId);
	request.target = TargetAddress;
	request.buffer = SourceAddress;
	request.size = Size;

	DWORD returned;
	return DeviceIoControl(hDriver, custom_ioctl_write, &request, sizeof(request), &request, sizeof(request), &returned, nullptr);
}

bool FindAndReplaceSignature(HANDLE hDriver, DWORD pid, const std::vector<BYTE>& signature, const std::vector<BYTE>& patch) {
	bool found = false;
	SIZE_T stepSize = 0x1000; // Размер шага чтения в байтах
	BYTE buffer[0x1000]; // Буфер для временного хранения считываемой памяти

	for (ULONG_PTR address = 0x00000000; address < 0x7FFFFFFF; address += stepSize - signature.size()) {
		memset(buffer, 0, sizeof(buffer));
		if (ReadMemory(hDriver, pid, (PVOID)address, buffer, sizeof(buffer))) {
			for (size_t i = 0; i < stepSize - signature.size(); ++i) {
				if (memcmp(buffer + i, signature.data(), signature.size()) == 0) {
					ULONG_PTR patchAddress = address + i;
					if (WriteMemory(hDriver, pid, (PVOID)patch.data(), (PVOID)patchAddress, patch.size())) {
						std::cout << "Signature found and patched at: 0x" << std::hex << patchAddress << std::endl;
						found = true;
						break;
					}
				}
			}
		}
		if (found) break;
	}
	return found;
}

int main() {
	DWORD pid = get_process_id(L"l2.bin");

	if (pid == 0) {
		std::cout << "Failed to find l2.bin\n";
		std::cin.get();
		return 1;
	}

	std::vector<BYTE> user_ini_signature = { 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> user_ini_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 };

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

	if (driver::attach_to_process(driver, pid) == true) {
		std::cout << "Attachment successful.\n";
	}

	if (FindAndReplaceSignature(driver, pid, user_ini_signature, user_ini_patch)) {
		std::cout << "User.ini patch applied successfully.\n" << std::endl;
	}
	else {
		std::cout << "User.ini signature not found.\n" << std::endl;
	}

	CloseHandle(driver);

	std::cin.get();

	return 0;
}