Начинающий
Начинающий
- Статус
- Оффлайн
- Регистрация
- 10 Апр 2022
- Сообщения
- 21
- Реакции
- 4
всем привет
мне для одного проекта нужно было загружать .NET файл собранный с NativeAOT в память вручную, без сохранения файла на диск
пока искал информацию, увидел что до сих пор не существовало ни одной публичной реализации такого лоадера.
сами разработчики dotnet ещё в 2022 году
с тех пор никто эту задачу публично не решил, поэтому решил сам.
проблема в том что NativeAOT binary нельзя просто замапить в память и вызвать entry point. есть несколько проблем
которые нужно решить вместе:
1. GetModuleHandleExW не находит модуль - NativeAOT runtime при инициализации вызывает
GetModuleHandleExW(FROM_ADDRESS) чтобы найти себя. на Win10+ этот lookup идет через red-black tree
(BaseAddressIndex), а не через PEB linked lists. вручную замапленного модуля в этом дереве нет, lookup возвращает
NULL, runtime вызывает __fastfail. решение - найти LdrpModuleBaseAddressIndex и вставить наш модуль через
RtlRbInsertNodeEx.
2. TLS не инициализируется - NativeAOT использует static TLS (__declspec(thread)) для thread management и GC. при
ручном маппинге OS loader не регистрирует TLS для нашего модуля. решение - найти LdrpHandleTlsData. я это делал через
reference-based scan ntdll (ищем функцию которая вызывает RtlImageDirectoryEntryToData, RtlAcquireSRWLockExclusive,
RtlAllocateHeap и memcpy одновременно), это позволяет легче решить проблему с отличием сигнатур на разных версиях системы.
затем вызвать эту функцию с нашим LDR entry.
3. неполный LDR_DATA_TABLE_ENTRY - большинство реализаций заполняют 5-6 полей. ntdll обращается к DdagNode,
BaseAddressIndexNode, HashLinks, BaseNameHashValue и другим. пришлось создать полную структуру на 0x200 байт с ~30
полями.
4. ленивая инициализация runtime - для DLL вариантов: DllMain только регистрирует callback, реальная инициализация
происходит при первом вызове export через RhpReversePInvokeAttachOrTrapThread2. если к этому моменту предыдущие
проблемы не решены - __fastfail.
больше информации и исходники на
мне для одного проекта нужно было загружать .NET файл собранный с NativeAOT в память вручную, без сохранения файла на диск
пока искал информацию, увидел что до сих пор не существовало ни одной публичной реализации такого лоадера.
сами разработчики dotnet ещё в 2022 году
Пожалуйста, авторизуйтесь для просмотра ссылки.
.с тех пор никто эту задачу публично не решил, поэтому решил сам.
проблема в том что NativeAOT binary нельзя просто замапить в память и вызвать entry point. есть несколько проблем
которые нужно решить вместе:
1. GetModuleHandleExW не находит модуль - NativeAOT runtime при инициализации вызывает
GetModuleHandleExW(FROM_ADDRESS) чтобы найти себя. на Win10+ этот lookup идет через red-black tree
(BaseAddressIndex), а не через PEB linked lists. вручную замапленного модуля в этом дереве нет, lookup возвращает
NULL, runtime вызывает __fastfail. решение - найти LdrpModuleBaseAddressIndex и вставить наш модуль через
RtlRbInsertNodeEx.
2. TLS не инициализируется - NativeAOT использует static TLS (__declspec(thread)) для thread management и GC. при
ручном маппинге OS loader не регистрирует TLS для нашего модуля. решение - найти LdrpHandleTlsData. я это делал через
reference-based scan ntdll (ищем функцию которая вызывает RtlImageDirectoryEntryToData, RtlAcquireSRWLockExclusive,
RtlAllocateHeap и memcpy одновременно), это позволяет легче решить проблему с отличием сигнатур на разных версиях системы.
затем вызвать эту функцию с нашим LDR entry.
3. неполный LDR_DATA_TABLE_ENTRY - большинство реализаций заполняют 5-6 полей. ntdll обращается к DdagNode,
BaseAddressIndexNode, HashLinks, BaseNameHashValue и другим. пришлось создать полную структуру на 0x200 байт с ~30
полями.
4. ленивая инициализация runtime - для DLL вариантов: DllMain только регистрирует callback, реальная инициализация
происходит при первом вызове export через RhpReversePInvokeAttachOrTrapThread2. если к этому моменту предыдущие
проблемы не решены - __fastfail.
больше информации и исходники на
Пожалуйста, авторизуйтесь для просмотра ссылки.
.