Форум программистов, компьютерный форум, киберфорум
_lunar_
Войти
Регистрация
Восстановить пароль

Стек вызовов Windows API

Запись от _lunar_ размещена 11.04.2022 в 14:59
Показов 2809 Комментарии 0
Метки c, c++, winapi

В этой записи я постараюсь простым понятным языком объяснить что такое API в целом, а также его разновидности в зависимости от того, где это API исполняется.

Сперва, предлагаю внимательно посмотреть на скриншот и запомнить последовательность вызовов
(не стал рисовать свои скриншоты, т.к. этот в полной мере описывает весь процесс)
Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 571
Размер:	57.6 Кб
ID:	7441

Итак, после того, как исходный код был скомпилирован, появляется пользовательское приложение (файл с расширением *.exe).
EXE файл это исполняемый файл со строго типизированной структурой заголовка Portable Executable (PE).
Формат PE достаточно объемный, и поэтому кажется сложным. Но Microsoft любезно предоставляет спецификацию этого формата PE Format, так что с освоением проблем не должно возникнуть.
Такая структурированность требуется для того, чтобы загрузчик Windows смог проецировать таблицы с кодом, заложенные в EXE файле, в виртуальное адресное пространство, для дальнейшего его исполнения на процессоре (инструкция за инструкцией).

Я сейчас не буду подробно останавливаться на каждой таблице, но нужно запомнить вот что:
у EXE файлов всегда есть таблица импорта адресов - Import Address Table (IAT) (за исключением случаев, когда код написан без среды выполнения C Runtime (CRT)).

Вернёмся на шаг назад - к исходному коду.
Когда программист пишет код будущего пользовательского приложения, он использует заготовленные файлы хидеров (Header), в которых определены различные константы, прототипы функций и многое другое.
Хидер это просто текст и не более.
Ещё программист использует библиотеки (*.lib), чтобы связать (слинковать) прототип функции из хидера с реальной функций в одной из системных библиотек DLL.
Именно эта связь формирует таблицу импорта адресов (IAT) в заголовке PE будущего EXE файла.

Снова вернёмся к скриншоту, на котором для примера выбрана функция WriteFile и весь её стек вызовов.
И вот тут уже можно начинать задать вопрос - что же такое Application Programming Interface (API)?

Начнем с пользовательского окружения - то, что доступно непосредственно пользователю: Windows API (WinAPI).
WinAPI это документированное API, т.е. к прототипам его функций есть описание и спецификации.
WinAPI представляет собой массивный набор функций, распределенный по нескольким системным библиотекам DLL.
Основные системные библиотеки пользовательского окружения: kernelbase.dll (до Windows 8 это была kernel32.dll и теперь она служит лишь стабом для совместимости), user32.dll, gdi32.dll, advapi32.dll, ntmarta.dll, shell32.dll и др.
В них собрано огромное количество функций, которые и формируют WinAPI.

Когда программист в коде использует функцию WriteFile, он вызывает её API из соответствующей системной библиотеки (в данном случае kernel32.dll).
По сути API это ничто иное как исполняемый код в самой библиотеки DLL.
Там выполняются различные internal функции (не экспортируемые функции), вычисления, заполнение переменных, переданных программистом через аргументы функции WriteFile.
Формируется так называемый пользовательский контекст - массив данных, который передаётся ядру ОС через ссылку на стек (шлюз)
Assembler
1
2
3
4
5
proc near
    mov edx, esp
    syscall ; mov edx, 7FFE0300 // SharedUserData!SystemCallStub (в 7FFE0300 находится адрес KiFastSystemCall)
    retn
endp
Конечным результатом внутреннего исполнения функции WriteFile в библиотеке kernel32.dll будет вызов функции NtWriteFile с тем самым пользовательским контекстом.

Есть ещё несколько библиотек пользовательского окружения, таких как ntdll.dll и win32u.dll, функции которых доступны из UserMode.
Набор их функций формирует так называемое NativeAPI.
NativeAPI это недокументированное API, и разбор прототипов его функций осуществляется энтузиастами в ручном режиме с помощью отладчиков и дизассемблеров.
Главная задача этих функций - передать пользовательский контекст в ядро ОС.
Делается это переключением (или точнее системным прерыванием) процессора в защищенный режим (ProtectedMode).
В современных ОС и процессорах для этого используются инструкции SYSCALL или SYSENTER (внутри KiFastSystemCall) (в старых ОС это системное прерывание называлось int 2e (внутри KiIntSystemCall))
Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 487
Размер:	64.8 Кб
ID:	7442
Возврат контекста из ядра ОС в пользовательский режим осуществляется инструкциями SYSRET или SYSEXIT (внутри KiFastSystemCallRet).

После того, как процессор перешёл в защищенный режим (ProtectedMode), переданный пользовательский контекст начинает обрабатываться в ядре ОС - ntoskrnl.exe
Для этого используется процедура ZwWriteFile (не путайте с функций NtWriteFile из библиотеки ntdll.dll).
Код API, который исполняется в ядре ОС называется KernelAPI.
KernelAPI это недокументированное API (небольшая часть функций всё же описана в WDK, но не все).
В кругах низкоуровневых программистов функции KernelAPI ещё называют сервисами (или подпрограммами системных служб).

Дальше опускаться уже не будем - там только слой аппаратных абстракций (HAL) и само железо.
В двух словах: HAL транслирует код в оперативной памяти таким образом, чтобы другие микроконтроллеры смогли обработать запросы от центрального процессора и предоставить ответы.
Вот одна из Hal-функций, которые начиная с поздних версий Windows 10, переехали из hal.dll в ядро ОС ntoskrnl.exe
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
NTHALAPI
BOOLEAN
HalTranslateBusAddress(
    _In_ INTERFACE_TYPE InterfaceType,
    _In_ ULONG BusNumber,
    _In_ PHYSICAL_ADDRESS BusAddress,
    _Inout_ PULONG AddressSpace,
    _Out_ PPHYSICAL_ADDRESS TranslatedAddress
    );
 
//
// Values for AddressSpace parameter of HalTranslateBusAddress
//
//      0x0         - Memory space
//      0x1         - Port space
//      0x2 - 0x1F  - Address spaces specific for Alpha
//                      0x2 - UserMode view of memory space
//                      0x3 - UserMode view of port space
//                      0x4 - Dense memory space
//                      0x5 - reserved
//                      0x6 - UserMode view of dense memory space
//                      0x7 - 0x1F - reserved
//
Итак, подведём итоги:
1. операционная система Windows предоставляет API интерфейсы, расположенные в библиотеках DLL.
2. пользовательское приложение вызывает API, реализованное в библиотеках DLL.
3. большинство функций API в конечном итоге вызывают подпрограммы системных служб (сервисы) в ntoskrnl.exe

Все менеджеры, утилиты, программы и т.д. используют API.
API не может использовать менеджеры и утилиты в качестве запуска службы и прочего.
API это программный интерфейс, выполняющий определенные команды, которыми пользуются программисты при разработке приложений.
Метки c, c++, winapi
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru