Доброго времени! Пытаюсь загрузить в свой процесс kernel32.dll, делаю так: Код (Text): HANDLE hFile = CreateFile("C:\\Windows\\SysWOW64\\kernel32.dll", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); GetFileSizeEx(hFile, &fsz); NtAllocateVirtualMemory(NtCurrentProcess(), &Buffer, 0, &sz, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); ReadFile(hFile, Buffer, fsz.LowPart, &ReturnLength, NULL); NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, 0, PAGE_READONLY, SEC_IMAGE, hFile); NtMapViewOfSection(hSection, NtCurrentProcess(), §ionBaseAddress, NULL, NULL, NULL, &viewSize, 1, NULL, PAGE_EXECUTE_READWRITE); В итоге функции отрабатывают, последняя падает с ошибкой 40000003. Я не понимаю, где ошибка. Может у кого то есть код, который может dll в процесс загрузить?
Для NtMapViewOfSection 0x40000003 это не ошибка в строгом значении этого слова, STATUS_IMAGE_NOT_AT_BASE - указывает лишь на то, что образ был размещён в VM процесса не по желаемому образом адресу и его (образа) ImageBase был изменён. Для наглядности посмотрите любым сканером VM прогцесса (тем же VMMap например) - грузится ли образ и по какому адресу.
Тогда я не понимаю, что происходит. Но в карте памяти не отображается dll в отладчике. В чем может быть беда?
sectionBaseAddress = 0, а также viewSize = 0 или актуальный размер образа перед вызовом NtMapViewOfSection. и NtAllocateVirtualMemory и ReadFile здесь лишние, NtCreateSection выделяет память и читает файл сама.
piligmindo, Во первых это не загрузка, а отображение. Ядро ничего не знает про загрузку - оно фиксирует образ в памяти согласно параметрам файловых секций. Во вторых ядерные апи не могут падать, если решил с ними работать, то должен знать формат статусного кода: Код (Text): // Values are 32 bit values layed out as follows: // // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 // +---+-+-+-----------------------+-------------------------------+ // |Sev|C|R| Facility | Code | // +---+-+-+-----------------------+-------------------------------+ // // where // // Sev - is the severity code // // 00 - Success // 01 - Informational // 10 - Warning // 11 - Error // // C - is the Customer code flag // // R - is a reserved bit // // Facility - is the facility code // // Code - is the facility's status code > Но в карте памяти не отображается dll в отладчике. Отладчик берёт инфу из юзер загрузчика, если модуль спроецирован, это не значит что он загружен. --- Сообщение объединено, 3 дек 2019 --- > Может у кого то есть код, который может dll в процесс загрузить? Изначально не верный подход к решению задачи. Сложность системы растёт, просто не реально повторить загрузчик. Либо загружай из файла через его апи, либо симулируй section-object, для загрузки из памяти. Примеры есть, но врядле пока ты там что либо поймёшь
Пофиксил, не работает... Точнее, все так же нет образа в памяти. Это 3-е кольцо, не ядро. Я не понимаю, как тогда его загрузить в свой процесс, что бы им воспользоваться? Или как его найти тогда? Может я ищу не там? Но в любом сканере памяти нет dll.
>>C:\\Windows\\SysWOW64\\kernel32.dll вы случайно не в 64битный процесс пытаетесь загрузить 32битную DLL?
Я думаю, что все как то проще. Вот здесь написано: https://www.first.org/resources/pap...e-Evasion-Trend-Bypassing-User-Mode-Hooks.pdf Section Remapping. [Nt]CreateFile() + NtCreateSection(..., SEC_IMAGE, ...) + ZwMapViewOfSection() --- Сообщение объединено, 3 дек 2019 --- Нет. ОС x64, файл, который загружает - x86.
>>Нет. ОС x64, файл, который загружает - x86. Ну так в этом случае kernel32 уже спроецирован загрузчиком и повторного проецирования не происходит. аналогично для ntdll
Тогда грузите не SEC_IMAGE, а SEC_COMMIT и разбирайте вручную секции, делайте релокацию, настраивайте импорты и т.д
piligmindo, > Evasion-Trend-Bypassing-User-Mode-Hooks.pdf Незачем читать всякую чушь. Там обход" заключается в копировании уже спроецированного образа, он вне загрузчика и может работать как копия(те перемещён в памяти, а оригинальный образ настроен - например загружен импорт(IAT)). Нет смысла что то скрывать в памяти, ты не сможешь это сделать. Есть способы, но они слишком сложны - подмена локальной выборки, для этого приложение должно исполняться под визором, тогда можно выполнить подмену/симуляцию. Это сложная тема, не нужно лезть в то, что не понимаешь
piligmindo, Там описано копирование, те можно переместить в памяти уже загруженный образ. Так как адресация всегда релатив(относительная) в пределах секций, то остаётся лишь пофиксить указатели(fixup's). Но эта копия будет вне загрузчика, ты не сможешь вызвать никакие апи для работы с ней.
И не забывайте про CFG на 8.1+ - его битовую карту копирование не исправит, соответственно вызов функций из копии вывалит прогу в unhandled exception.