Сейчас на форуме: igorcauret, Rio (+6 невидимых) |
![]() |
eXeL@B —› Вопросы новичков —› Как работают прослойки для системных библиотек |
Посл.ответ | Сообщение |
|
Создано: 16 июня 2015 16:39 · Личное сообщение · #1 Приветствую. Поясните, пожалуйста, один момент. Я отлаживаю приложение в OllyDbg на Windows 8. Предположим, мне захотелось поставить бряк на WinAPI-функциях HeapAlloc и HeapFree, которые, согласно документации на MSDN, лежат в kernel32.dll. Я переключаюсь на этот модуль в OllyDbg, нажимаю Ctrl-N, пишу HeapFree и вижу: Names in KERNEL32, item 1188 Address=75FF502E Section=.text Type=Export (Known) Name=HeapFree Names in KERNEL32, item 1189 Address=76050484 Section=.rdata Type=Import Name=api-ms-win-core-heap-l1-2-0.HeapFree Функция импортируется из "api-ms-win-core-heap-l1-2-0" и разрешает экспортировать себя, ссылаясь на адрес 0x75FF502E. Насколько я понял из статьи на MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/dn505783(v=vs.85).aspx), kernel32.dll и другие системные библиотеки на современных версиях Windows -- это всего лишь прослойка, которая только импортирует необходимые функции из "реальной" DLL и позволяет экспортировать их, верно? Если это действительно так, то у меня возникают сразу несколько вопросов: - Почему некоторые WinAPI-функции (например, HeapAlloc в моём случае), если верить тому, что показывает OllyDbg, импортируются из "реальной" DLL ("api-ms-win-core-heap-l1-2-0"), но не позволяют себя экспортировать, т.е. строчки с экспортом этой функции в kernel32.dll просто нет: Names in KERNEL32, item 1181 Address=76050480 Section=.rdata Type=Import Name=api-ms-win-core-heap-l1-2-0.HeapAlloc - Почему эти "реальные" DLL не загружаются в адресное пространство исследуемого процесса? Об этом я сужу из-за отсутствия в списке Executable Modules (Alt-E) той же "api-ms-win-core-heap-l1-2-0" - Для чего вообще это всё было сделано? На MSDN сказано, что "The decoupling between implementation and interface contracts provided by API Sets offers many engineering advantages, but can also potentially reduce the number of DLLs loaded in a process", но я, честно говоря, не понимаю, как это может уменьшить кол-во DLL, загружаемых в процесс, ведь некоторые функции, реализации которых раньше находилась в одной и той же DLL, теперь находятся в совершенно разных библиотеках (например, Beep и HeapAlloc, обе из которых раньше находились в kernel32.dll, теперь находятся в api-ms-win-core-util-l1-1-0.dll и api-ms-win-core-heap-l1-2-0.dll соответственно). Или, может, имелся ввиду меньший объём загружаемых DLL, если нужна лишь часть функционала какой-то из них? Но ведь это же системные библиотеки, так что говорить об этом как-то глупо, по-моему. В общем, зачем это было сделано? Как это работает и какую проблему это решает? Почему та же HeapAlloc не экспортируется из kernel32.dll в моём случае и как мне в итоге поставить бряк на эту функцию? Заранее благодарю за возможные ответы. Добавлено спустя 22 минуты По поводу того, почему эти библиотеки не отображаются в списке Executable Modules в OllyDbg, сказано вот тут -- http://www.nirsoft.net/articles/windows_7_kernel_architecture_changes.html By looking in dependency walker utility, we can see that advapi32.dll, kernel32.dll, and other system dll files, are now statically linked to these empty api-ms-win-core files А вот в связи с этой фразой из той же статьи, я окончательно запутался, зачем это нужно: So here's our RegDeleteValueW example again: when loading a program into WinDbg, we can see that the jmp call now points to kernel32!RegDeleteValueW function. That's because during the loading of advapi32.dll, Windows automatically replace the import entry of API-MS-Win-Core-LocalRegistry-L1-1-0.RegDeleteValueW to the function address of RegDeleteValueW in kernel32 Получается, что вызов HeapFree из kernel32.dll, который был JMP'ом на функцию HeapFree, импортируемую из api-ms-win-core-heap-l1-2-0.dll, заменится в итоге вызовом той же самой функции из той же kernel32.dll? Что-то я не понял. ![]() |
|
Создано: 17 июня 2015 18:59 · Личное сообщение · #2 |
|
Создано: 17 июня 2015 19:05 · Личное сообщение · #3 |
|
Создано: 17 июня 2015 22:42 · Личное сообщение · #4 b0r3d0m подумайте об обратной совместимости... винда уже разбухла в попытке усидеть на даже не на 2ух.. на всех стульях. либы становятся прослойками для совместимости раз.. и от части, что в мелкософте уже нет людей которые знают как работает сама их ось, поэтому крайне осторожно трогают кернельные либы ----- Наша работа во тьме, Мы делаем, что умеем. Мы отдаем, что имеем, Наша работа во тьме.... ![]() |
|
Создано: 17 июня 2015 22:56 · Личное сообщение · #5 VodoleY пишет: подумайте об обратной совместимости Обратной совместимости чего и с чем? Функций из kernel32.dll с другими версиями ОС? Если да, то что мешает, как и раньше, просто редактировать их код, не создавая никаких дополнительных прослоек? VodoleY пишет: и от части, что в мелкософте уже нет людей которые знают как работает сама их ось, поэтому крайне осторожно трогают кернельные либы Они лишь увеличили кол-во абстракций, но в случае необходимости изменить поведение той или иной функции они всё равно будут вынуждены залезть в недра той или иной библиотеки, а там уже какая разница, что именно это будет -- kernel32.dll, kernelbase.dll или какая-то api-ms-win-core-* библиотека? И да, сможете ответить на остальные вопросы, пожалуйста? ![]() |
|
Создано: 17 июня 2015 23:06 · Личное сообщение · #6 |
|
Создано: 17 июня 2015 23:06 · Поправил: dosprog · Личное сообщение · #7 |
|
Создано: 17 июня 2015 23:10 · Личное сообщение · #8 |
|
Создано: 18 июня 2015 05:50 · Личное сообщение · #9 b0r3d0m ну вот смотрите.. допустим.. есть вин2к с отлтаженным кернел32.. отладка и выкусывание глюков длилось лет 5... обьем кода в нем немалый.. вы выпускаете новую версию ОС.. и вам нужны новые фишки. у вас есть 2 варианта либо добавить в старый кернел новые функи (тогда есть шанс добавить глюков, а изза все увеличивающегося обьема тестить ее все сложнее и сложнее.. типа.. убираем старые глюки добавляем новые) или вариант 2. сделать враперную либу, которая будет иметь только новые функи, а остальные вызывать из уже стабильной либы. ----- Наша работа во тьме, Мы делаем, что умеем. Мы отдаем, что имеем, Наша работа во тьме.... ![]() |
|
Создано: 18 июня 2015 09:18 · Поправил: b0r3d0m · Личное сообщение · #10 VodoleY пишет: а изза все увеличивающегося обьема тестить ее все сложнее и сложнее Почему? Тестируются же конкретные функции, которые доступны через отдельные точки входа. Какая разница, какой суммарный объём у DLL? VodoleY пишет: сделать враперную либу, которая будет иметь только новые функи, а остальные вызывать из уже стабильной либы Тут вообще всё очень не просто как-то. Та же CreateFileA изначально экспортируется наружу их kernel32.dll, однако если посмотреть на её реализацию, то мы увидим JMP на api-ms-win-core-*, который ОС автоматически заменила на прыжок в kernelbase.dll. Зачем такие сложности? Почему, допустим, не прыгать сразу в kernelbase.dll? К чему вот это всё: > So here's our RegDeleteValueW example again: when loading a program into WinDbg, we can see that the jmp call now points to kernel32!RegDeleteValueW function. That's because during the loading of advapi32.dll, Windows automatically replace the import entry of API-MS-Win-Core-LocalRegistry-L1-1-0.RegDeleteValueW to the function address of RegDeleteValueW in kernel32 ![]() |
|
Создано: 18 июня 2015 10:43 · Личное сообщение · #11 Старые либы оставили для совместимости. А новую прослойку ввели для унификации работы на других платформах, в той же 10 они через пень-колоду пришли к максимальному использованию общего кода на разных платформах. ![]() |
|
Создано: 18 июня 2015 11:15 · Личное сообщение · #12 Archer пишет: Старые либы оставили для совместимости. А новую прослойку ввели для унификации работы на других платформах, в той же 10 они через пень-колоду пришли к максимальному использованию общего кода на разных платформах. Хорошо, спасибо. А что по поводу вот этого вопроса: > Почему некоторые WinAPI-функции (например, HeapAlloc в моём случае), если верить тому, что показывает OllyDbg, импортируются из "реальной" DLL ("api-ms-win-core-heap-l1-2-0"), но не позволяют себя экспортировать, т.е. строчки с экспортом этой функции в kernel32.dll просто нет: Names in KERNEL32, item 1181 Address=76050480 Section=.rdata Type=Import Name=api-ms-win-core-heap-l1-2-0.HeapAlloc ![]() |
|
Создано: 18 июня 2015 12:05 · Личное сообщение · #13 |
|
Создано: 18 июня 2015 12:12 · Личное сообщение · #14 |
|
Создано: 18 июня 2015 12:29 · Поправил: ClockMan · Личное сообщение · #15 |
|
Создано: 18 июня 2015 16:18 · Поправил: b0r3d0m · Личное сообщение · #16 ClockMan пишет: Во первых разберитесь что такое таблица экспорта и как она работает, и что такое форвардинг,зайдите в таблицу экспорта kernel32.dll и по поиску найдите NTDLL.RtlAllocateHeap...... Таблица экспорта -- это раздел PE-файла, который содержит информацию о функциях, которые экспортируются из данного модуля. Форвардинг -- это перенаправление экспорта в другую DLL. Выполнил dumpbin /exports kernel32.dll и увидел, помимо всего прочего, следующее: 847 34D HeapAlloc (forwarded to NTDLL.RtlAllocateHeap) Но как я мог это увидеть в OllyDbg? И что в итоге делать с бряком? Просто поставить его на RtlAllocateHeap? ![]() |
|
Создано: 18 июня 2015 16:38 · Личное сообщение · #17 |
|
Создано: 18 июня 2015 17:01 · Личное сообщение · #18 |
|
Создано: 18 июня 2015 17:10 · Поправил: kid · Личное сообщение · #19 |
|
Создано: 18 июня 2015 17:18 · Поправил: ClockMan · Личное сообщение · #20 b0r3d0m пишет: Но как я мог это увидеть в OllyDbg? Ни как, только ида покажет это Code:
b0r3d0m пишет: И что в итоге делать с бряком? Просто поставить его на RtlAllocateHeap да ----- Чтобы правильно задать вопрос, нужно знать большую часть ответа. Р.Шекли. ![]() |
|
Создано: 18 июня 2015 17:34 · Личное сообщение · #21 kid пишет: Ctrl+G -> HeapAlloc В kernel32.dll? "Unknown identifier". kid пишет: Это попытка отладить kernel32.dll ? Нет, я пытался поставить бряки на вызовах HeapAlloc в исследуемом приложении, однако в процессе обнаружил, что данной функции нет в списке "Intermodular calls". В связи с этим я решил поставить бряк на саму реализацию функции HeapAlloc и не обнаружил экспорта в kernel32.dll, из-за чего и возник данный вопрос. ClockMan пишет: да Хорошо, спасибо. ![]() |
![]() |
eXeL@B —› Вопросы новичков —› Как работают прослойки для системных библиотек |