Начинающий
- Статус
- Оффлайн
- Регистрация
- 2 Фев 2020
- Сообщения
- 248
- Реакции
- 21
Спасибо огромное этому Человеку.
Первый код (НЕ РАБОТАЕТ на 24H2+):
Почему не работает:
Прямая загрузка через ctypes.WinDLL блокируется системой на Windows 11 24H2+
Отсутствует задержка между загрузкой и инициализацией
Нет обработки специфических флагов загрузки
Второй код (РАБОТАЕТ на 24H2+):
Почему работает:
Использование низкоуровневого kernel32.LoadLibraryA вместо прямого ctypes.WinDLL
Получение адресов функций через GetProcAddress
Обход системной блокировки через системный API
Ключевые отличия (почему второй код работает):
Метод загрузки DLL
Первый код (проблемный):
Второй код (рабочий):
Получение функций
Первый код:
Второй код:
Обработка ошибок
Первый код:
Второй код:
Полное исправление для первого кода:
Основные выводы:
1. Первый код использует высокоуровневый ctypes.WinDLL, который на Windows 11 24H2+ блокируется системой безопасности
2. Второй код использует низкоуровневый kernel32.LoadLibraryA через ctypes.WinDLL("kernel32"), что позволяет обойти блокировку
3. Ключевое исправление - загрузка DLL через системный API kernel32, а не напрямую через ctypes
Спасибо за внимание!

Первый код (НЕ РАБОТАЕТ на 24H2+):
Код:
class DDXoft:
def __init__(self):
self.dll = None
self.available = False
def load(self, dll_path):
try:
# ПРОБЛЕМА: Прямая загрузка через WinDLL
self.dll = ctypes.WinDLL(dll_path)
# Настройка функций
self.DD_btn = self.dll.DD_btn
self.DD_btn.argtypes = [ctypes.c_int]
self.DD_btn.restype = ctypes.c_int
self.DD_key = self.dll.DD_key
self.DD_key.argtypes = [ctypes.c_int, ctypes.c_int]
self.DD_key.restype = ctypes.c_int
# ПРОБЛЕМА: Инициализация сразу после загрузки
result = self.DD_btn(0)
if result == 1:
self.available = True
return 1
return -1
except Exception as e:
return -2
Почему не работает:
Прямая загрузка через ctypes.WinDLL блокируется системой на Windows 11 24H2+
Отсутствует задержка между загрузкой и инициализацией
Нет обработки специфических флагов загрузки
Второй код (РАБОТАЕТ на 24H2+):
Код:
def load_ddx():
global DD_movR, DD_btn
try:
dll_path = os.path.abspath(DLL_NAME).encode("utf-8")
# ИСПРАВЛЕНИЕ 1: Использование kernel32.LoadLibraryA
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
load_library = kernel32.LoadLibraryA
load_library.argtypes = [ctypes.c_char_p]
load_library.restype = ctypes.c_void_p
# ИСПРАВЛЕНИЕ 2: Загрузка через низкоуровневый API
dll_handle = load_library(dll_path)
if not dll_handle:
raise RuntimeError("Не удалось загрузить ddxoft.dll")
# ИСПРАВЛЕНИЕ 3: Получение адресов функций через GetProcAddress
get_proc_address = kernel32.GetProcAddress
get_proc_address.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
get_proc_address.restype = ctypes.c_void_p
def bind_function(name, restype, argtypes):
addr = get_proc_address(dll_handle, name.encode("ascii"))
if not addr:
raise RuntimeError(f"Функция {name} не найдена в DLL")
return ctypes.CFUNCTYPE(restype, *argtypes)(addr)
DD_movR = bind_function("DD_movR", ctypes.c_int, [ctypes.c_int, ctypes.c_int])
DD_btn = bind_function("DD_btn", ctypes.c_int, [ctypes.c_int])
# ИСПРАВЛЕНИЕ 4: Проверка инициализации
if DD_btn(0) != 1:
raise RuntimeError("Драйвер ddxoft не активен или неподдерживаемая версия")
print("[INFO] DLL успешно загружена и инициализирована")
return True
except Exception as e:
print(f"[ERROR] Ошибка инициализации DLL: {e}")
return False
Почему работает:
Использование низкоуровневого kernel32.LoadLibraryA вместо прямого ctypes.WinDLL
Получение адресов функций через GetProcAddress
Обход системной блокировки через системный API
Ключевые отличия (почему второй код работает):
Метод загрузки DLL
Первый код (проблемный):
Код:
self.dll = ctypes.WinDLL(dll_path) # Высокоуровневый метод
Второй код (рабочий):
Код:
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
load_library = kernel32.LoadLibraryA # Низкоуровневый API
dll_handle = load_library(dll_path)
Получение функций
Первый код:
Код:
self.DD_btn = self.dll.DD_btn # Автоматическое связывание
Второй код:
Код:
def bind_function(name, restype, argtypes):
addr = get_proc_address(dll_handle, name.encode("ascii"))
return ctypes.CFUNCTYPE(restype, *argtypes)(addr)
Обработка ошибок
Первый код:
Код:
result = self.DD_btn(0) # Нет повторных попыток
Второй код:
Код:
if DD_btn(0) != 1: # Единоразовая проверка с clear error message
raise RuntimeError("Драйвер ddxoft не активен или неподдерживаемая версия")
Полное исправление для первого кода:
Код:
class DDXoftFixed:
def __init__(self):
self.dll_handle = None
self.dll = None
self.available = False
self.key_map = {
'q': 301, 'w': 302, 'e': 303, 'r': 304, 'd': 403, 'f': 404,
'z': 501, 'x': 502, 'c': 503
}
def load(self, dll_path):
try:
# ИСПРАВЛЕНИЕ: Используем kernel32.LoadLibraryA вместо прямого WinDLL
kernel32 = ctypes.WinDLL("kernel32", use_last_error=True)
load_library = kernel32.LoadLibraryA
load_library.argtypes = [ctypes.c_char_p]
load_library.restype = ctypes.c_void_p
get_proc_address = kernel32.GetProcAddress
get_proc_address.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
get_proc_address.restype = ctypes.c_void_p
# Загружаем DLL
path_encoded = os.path.abspath(dll_path).encode("utf-8")
self.dll_handle = load_library(path_encoded)
if not self.dll_handle:
raise RuntimeError("Не удалось загрузить ddxoft.dll")
# ИСПРАВЛЕНИЕ: Функция для привязки методов
def bind_function(name, restype, argtypes):
addr = get_proc_address(self.dll_handle, name.encode("ascii"))
if not addr:
raise RuntimeError(f"Функция {name} не найдена")
return ctypes.CFUNCTYPE(restype, *argtypes)(addr)
# Привязываем функции
self.DD_btn = bind_function("DD_btn", ctypes.c_int, [ctypes.c_int])
self.DD_key = bind_function("DD_key", ctypes.c_int, [ctypes.c_int, ctypes.c_int])
# ИСПРАВЛЕНИЕ: Небольшая задержка перед инициализацией
time.sleep(0.1)
# Инициализация
result = self.DD_btn(0)
if result == 1:
self.available = True
return 1
return -1
except Exception as e:
print(f"Error loading DDXoft: {e}")
return -2
def tap_key(self, key):
if not self.available or key not in self.key_map:
return False
code = self.key_map[key]
self.DD_key(code, 1)
time.sleep(0.01)
self.DD_key(code, 2)
return True
# Функция инициализации для первого кода
def init_ddxoft_fixed():
try:
if not ctypes.windll.shell32.IsUserAnAdmin():
messagebox.showerror("Ошибка", "Запустите от имени администратора")
return False
if not os.path.exists(DLL_NAME):
if not download_ddx():
messagebox.showerror("Ошибка", "Не удалось загрузить ddxoft.dll")
return False
# ИСПРАВЛЕНИЕ: Используем исправленный класс
ddxoft_instance = DDXoftFixed()
result = ddxoft_instance.load(os.path.abspath(DLL_NAME))
if result != 1:
messagebox.showerror("Ошибка", "Не удалось загрузить драйвер ddxoft")
return False
return True
except Exception as e:
messagebox.showerror("Ошибка", str(e))
return False
Основные выводы:
1. Первый код использует высокоуровневый ctypes.WinDLL, который на Windows 11 24H2+ блокируется системой безопасности
2. Второй код использует низкоуровневый kernel32.LoadLibraryA через ctypes.WinDLL("kernel32"), что позволяет обойти блокировку
3. Ключевое исправление - загрузка DLL через системный API kernel32, а не напрямую через ctypes
Спасибо за внимание!
