- Статус
- Оффлайн
- Регистрация
- 13 Фев 2026
- Сообщения
- 429
- Реакции
- 10
Народ, кто плотно ковыряет UEFI буткиты, нужна помощь по логике проброса хуков в ядро. Ситуация следующая: пытаюсь захукать MmCopyMemory через цепочку перехватов в winload.
Что уже сделано:
Код хука выглядит примерно так:
Суть проблемы:
Винда грузится нормально, но как только доходит до вызова MmCopyMemory, вылетает SYSTEM_SERVICE_EXCEPTION bugcheck.
Подозрение на то, что шеллкод делает прыжок по физическому адресу, который в контексте ядра уже невалиден. Пробовал делать ConvertPointer для адреса хука, но на выходе получаю честный 0x0. Если вместо прыжка вставлять просто xor rax, rax; ret, то патч отрабатывает и система не падает, но мне нужен полноценный трамплин.
Явно где-то косячу с маппингом адресов при переходе из окружения EFI в ядро. Кто уже сталкивался с таким поведением при попытке захукать ntoskrnl на этапе загрузки?
Отпишитесь, кто фиксил подобные краши.
Что уже сделано:
- Хукаю ExitBootServices.
- Выцепляю базу winload.efi.
- Ставлю хук на OslArchTransferToKernel.
- Внутри этого хука пытаюсь патчить ntoskrnl.exe.
Код хука выглядит примерно так:
Код:
EFI_STATUS osl_arch_transfer_to_kernel_hook(uint64_t loader_block, uint64_t entry)
{
uint64_t cr0 = AsmReadCr0();
AsmWriteCr0(cr0 & ~0x10000ull);
copy_memory((uint8_t*)g_osl_arch_transfer_to_kernel, g_osl_arch_transfer_to_kernel_bytes, 12);
AsmWriteCr0(cr0);
switch_ctx(0);
KLDR_DATA_TABLE_ENTRY ntoskrnl = get_module_base(&lpb->LoadOrderListHead, L"ntoskrnl.exe");
g_mm_copy_memory = (uint64_t)ntoskrnl.DllBase + 0x030C030;
copy_memory(g_mm_copy_memory_bytes, (uint8_t*)g_mm_copy_memory, 12);
uint64_t hook_address = (uint64_t)mm_copy_memory_hook;
uint8_t shellcode[12] = {0x48, 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xE0};
copy_memory(shellcode + 2, (uint8_t*)&hook_address, 8);
cr0 = AsmReadCr0();
AsmWriteCr0(cr0 & ~0x10000ull);
copy_memory((uint8_t*)g_mm_copy_memory, shellcode, 12);
AsmWriteCr0(cr0);
return ((osl_arch_transfer_to_kernel_t)g_osl_arch_transfer_to_kernel)(loader_block, entry);
}
Суть проблемы:
Винда грузится нормально, но как только доходит до вызова MmCopyMemory, вылетает SYSTEM_SERVICE_EXCEPTION bugcheck.
Подозрение на то, что шеллкод делает прыжок по физическому адресу, который в контексте ядра уже невалиден. Пробовал делать ConvertPointer для адреса хука, но на выходе получаю честный 0x0. Если вместо прыжка вставлять просто xor rax, rax; ret, то патч отрабатывает и система не падает, но мне нужен полноценный трамплин.
Код:
#include <stdint.h>
#include "tools.h"
typedef void(__stdcall* blp_arch_switch_context_t)(int);
EFI_SYSTEM_TABLE* g_system_table;
static EFI_EXIT_BOOT_SERVICES original_exit_boot_services = NULL;
static uint64_t g_osl_arch_transfer_to_kernel = 0;
static uint8_t g_osl_arch_transfer_to_kernel_bytes[12] = {0};
blp_arch_switch_context_t switch_ctx = 0;
typedef EFI_STATUS (*osl_arch_transfer_to_kernel_t)(uint64_t loader_block, uint64_t entry);
LOADER_PARAMETER_BLOCK* lpb = 0;
// ... helper functions ...
EFI_STATUS EFIAPI exit_boot_services_hook(EFI_HANDLE image_handle, uint64_t ebs_map_key)
{
uint64_t return_address = (uint64_t)_ReturnAddress();
gBS->ExitBootServices = original_exit_boot_services;
uint64_t winload_efi = get_module_base_from_address(return_address);
// Pattern matching winload for OslExecuteTransition and BlpArchSwitchContext
// Setting up the hook for OslArchTransferToKernel
return original_exit_boot_services(image_handle, ebs_map_key);
}
Явно где-то косячу с маппингом адресов при переходе из окружения EFI в ядро. Кто уже сталкивался с таким поведением при попытке захукать ntoskrnl на этапе загрузки?
Отпишитесь, кто фиксил подобные краши.