Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нём некорректно. Вам необходимо обновить браузер или попробовать использовать другой.
Есть. Можешь на гитхабе ознакомиться, например, с EfiGuard. Написан весьма качественно, с точки зрения подхода к архитектуре. Можешь также посмотреть условный xigmapper, он написан весьма просто и понятно для "новичков".
Но я бы рекомендовал ознакомиться с процессом загрузки не из исходников буткитов, а из собственных наблюдений, ревёрса (загрузчиков и ядра) и статей на тему буткитов, ну и со спецификацией EFI тоже. Так будет проще понимать, что вообще происходит.
Я распишу в кратком изложении ниже, что из себя эти штуки представляют и что используют.
Буткиты, по сути, это просто драйвера времени исполнения EFI, которые поддерживают спецификацией конверсию физической памяти в виртуальную, тем самым перенося сами себя в "виртуальную память" (ну, не сами себя конечно, но да ладно).
С моей "субъективной" точки зрения, подходов к написанию буткита есть два:
Полностью "строить" буткит на "паттернах", то есть использовать только их, не вмешиваясь в сервисные таблицы;
Использовать "систему паттернов" и при необходимости вмешиваться в сервисные таблицы. Эдак система 50/50.
Оба хороши, просто за первым необходимо более тщательно следить (в конце концов паттернов будет больше). Подход к атаке на цепочку загрузки, в принципе, одинаковый - ты атакуешь бутменеджер (bootmgfw.efi) и бутлоадер (winload.efi). Все прототипы функций, упоминающихся далее, я буду выносить под спойлер.
Если говорить о первом способе, то в первую очередь твоя цель - бутменеджер, это функция ImgArchStartBootApplication, она ответственна за передачу управления от бутменеджера к бутлоадеру. Через её хук ты сможешь узнать адрес бутлоадера (и его размер).
Func #1:
EFI_STATUS
EFIAPI
ImgArchStartBootApplication(
IN VOID *AppEntry,
IN VOID *ImageBase,
IN UINT32 ImageSize,
IN UINT8 BootOptions,
IN VOID *RetArgs
)
После того, как мы обнаружили базовый адрес бутлоадера - мы можем найти две функции: BlImgAllocateImageBuffer и OslFwpSetupKernelPhase1
Начнём с первой - она необходима для аллокации памяти под ядро ОС и его модули. Единственное, в неё нужно передавать специфичные флаги: 0xE0000012 и 0x424000. Первый флаг указывает на то, что загружается модуль ядра, второй - флаг для выделения RWX-страниц. Адрес выделенного буфера желательно сохранить.
Если тебе интересно, то можешь поглазеть на функу OslpLoadAllModules в winload.efi, как минимум на OslLoadImage (в ней позже вызовется BlImgAllocateImageBuffer):
Func #2:
EFI_STATUS
EFIAPI
BlImgAllocateImageBuffer(
IN VOID **ImageBuffer,
IN UINTN ImageSize,
IN UINTN MemoryType,
IN UINTN Attributes,
IN VOID *Reserved,
IN UINTN Flags
)
OslFwpSetupKernelPhase1 глобально нужен нам для получения базового адреса ядра, так как в функцию передаётся "главная"
- LOADER_PARAMETER_BLOCK, в ней содержится вся информация, нужная для первых фаз инициализации ядра. В структуре нам нужно поле LoadOrderListHead, с помощью списка можно найти нужный модуль и информацию о нём (эт ядро в нашем случае).
В этот же момент ты наконец-то можешь мапнуть свою полезную нагрузку.
Func #3:
EFI_STATUS
EFIAPI
OslFwpSetupKernelPhase1(
IN PLOADER_PARAMETER_BLOCK LoaderParameterBlock
)
Полезную нагрузку необходимо запустить, так что тебе нужно будет придумать, где и как её запустить. Можно, например, хукнуть что-то в ядре. Делать это надо в рантайме (то есть, когда управление передано в ядру). Нужно будет
ExitBootServices, ты гарантировано пропустишь половину из того, что я описывал выше, ибо этот сервис вызывается единожды в OslFwpSetupKernelPhase1 (в бутлоадере). Останется только придумать, как выделить память и найти структуру LOADER_PARAMETER_BLOCK.
Касательно первого, ты можешь хукать другие сервисы, и в каждом вызове хука смотреть, был ли вызван он из бутлоадера - получать адрес вызывающего через _ReturnAddress, искать базовый адрес и смотреть на артефакты, присуще только бутлоадеру. Либо забить хуй (если тебе это не важно) и использовать аллокаторы из
P.S. Касательно второго способа и поиска LOADER_PARAMETER_BLOCK - его можно и не искать, если ориентироваться в том, что происходит в первых 16 мегабайтах физической памяти.
Есть. Можешь на гитхабе ознакомиться, например, с EfiGuard. Написан весьма качественно, с точки зрения подхода к архитектуре. Можешь также посмотреть условный xigmapper, он написан весьма просто и понятно для "новичков".
Но я бы рекомендовал ознакомиться с процессом загрузки не из исходников буткитов, а из собственных наблюдений, ревёрса (загрузчиков и ядра) и статей на тему буткитов, ну и со спецификацией EFI тоже. Так будет проще понимать, что вообще происходит.
Я распишу в кратком изложении ниже, что из себя эти штуки представляют и что используют.
Буткиты, по сути, это просто драйвера времени исполнения EFI, которые поддерживают спецификацией конверсию физической памяти в виртуальную, тем самым перенося сами себя в "виртуальную память" (ну, не сами себя конечно, но да ладно).
С моей "субъективной" точки зрения, подходов к написанию буткита есть два:
Полностью "строить" буткит на "паттернах", то есть использовать только их, не вмешиваясь в сервисные таблицы;
Использовать "систему паттернов" и при необходимости вмешиваться в сервисные таблицы. Эдак система 50/50.
Оба хороши, просто за первым необходимо более тщательно следить (в конце концов паттернов будет больше). Подход к атаке на цепочку загрузки, в принципе, одинаковый - ты атакуешь бутменеджер (bootmgfw.efi) и бутлоадер (winload.efi). Все прототипы функций, упоминающихся далее, я буду выносить под спойлер.
Если говорить о первом способе, то в первую очередь твоя цель - бутменеджер, это функция ImgArchStartBootApplication, она ответственна за передачу управления от бутменеджера к бутлоадеру. Через её хук ты сможешь узнать адрес бутлоадера (и его размер).
Func #1:
EFI_STATUS
EFIAPI
ImgArchStartBootApplication(
IN VOID *AppEntry,
IN VOID *ImageBase,
IN UINT32 ImageSize,
IN UINT8 BootOptions,
IN VOID *RetArgs
)
После того, как мы обнаружили базовый адрес бутлоадера - мы можем найти две функции: BlImgAllocateImageBuffer и OslFwpSetupKernelPhase1
Начнём с первой - она необходима для аллокации памяти под ядро ОС и его модули. Единственное, в неё нужно передавать специфичные флаги: 0xE0000012 и 0x424000. Первый флаг указывает на то, что загружается модуль ядра, второй - флаг для выделения RWX-страниц. Адрес выделенного буфера желательно сохранить.
Если тебе интересно, то можешь поглазеть на функу OslpLoadAllModules в winload.efi, как минимум на OslLoadImage (в ней позже вызовется BlImgAllocateImageBuffer):
Func #2:
EFI_STATUS
EFIAPI
BlImgAllocateImageBuffer(
IN VOID **ImageBuffer,
IN UINTN ImageSize,
IN UINTN MemoryType,
IN UINTN Attributes,
IN VOID *Reserved,
IN UINTN Flags
)
OslFwpSetupKernelPhase1 глобально нужен нам для получения базового адреса ядра, так как в функцию передаётся "главная"
- LOADER_PARAMETER_BLOCK, в ней содержится вся информация, нужная для первых фаз инициализации ядра. В структуре нам нужно поле LoadOrderListHead, с помощью списка можно найти нужный модуль и информацию о нём (эт ядро в нашем случае).
В этот же момент ты наконец-то можешь мапнуть свою полезную нагрузку.
Func #3:
EFI_STATUS
EFIAPI
OslFwpSetupKernelPhase1(
IN PLOADER_PARAMETER_BLOCK LoaderParameterBlock
)
Полезную нагрузку необходимо запустить, так что тебе нужно будет придумать, где и как её запустить. Можно, например, хукнуть что-то в ядре. Делать это надо в рантайме (то есть, когда управление передано в ядру). Нужно будет
ExitBootServices, ты гарантировано пропустишь половину из того, что я описывал выше, ибо этот сервис вызывается единожды в OslFwpSetupKernelPhase1 (в бутлоадере). Останется только придумать, как выделить память и найти структуру LOADER_PARAMETER_BLOCK.
Касательно первого, ты можешь хукать другие сервисы, и в каждом вызове хука смотреть, был ли вызван он из бутлоадера - получать адрес вызывающего через _ReturnAddress, искать базовый адрес и смотреть на артефакты, присуще только бутлоадеру. Либо забить хуй (если тебе это не важно) и использовать аллокаторы из
P.S. Касательно второго способа и поиска LOADER_PARAMETER_BLOCK - его можно и не искать, если ориентироваться в том, что происходит в первых 16 мегабайтах физической памяти.