Номера системных вызовов windows

Системные вызовы Windows

Последнее обновление: 09.10.2023

Для взаимодействия с ресурсами системы на Windows, также как и на Linux, теоретически можно использовать системные вызовы или syscalls. Однако в Windows обращение к
системным вызовам имеет свои особенности. Прежде всего, надо установить номер вызываемой системной функции в регистре RAX. И как и в общем случае для выполнения системного вызова применяется инструкция syscall:

movq НОМЕР_СИСТЕМНОГО_ВЫЗОВА, %rax
syscall

Если системный вызов принимает параметры, то их можно передать, как и в общую функцию C/C++: для передачи в функцию первых четырех параметров используются регистры,
но первый параметр передается через регистр R10, а не через RCX, как в случае с функциями C/C++. То есть первые четыре параметра передаются через R10, RDX, R8 и R9 соответственно. Результат вызова возвращается через регистр RAX.

Минусом ОС Windows является то, что она не ориентирована на использование системных вызовов. Так, официальной документации по этому поводу нет, более
того о некоторых системных функциях нет вообще никакого упоминания в документации а сами номера системных вызовах
могут меняться в зависимости от номера билда ОС. Хотя в целом они стабильны для большинства выпусков. Более менее полную таблицу системных вызовов
для Windows можно найти на страницу https://hfiref0x.github.io/NT10_syscalls.html.

Возьмем простейший системный вызов — завершение процесса, который представлен функцией NtTerminateProcess. Если мы обратимся к вышеуказанной таблице,
то увидим, что эта функция имеет номер 44. Мы можем найти в документации определение этой функции:

NTSYSAPI NTSTATUS ZwTerminateProcess(
  [in, optional] HANDLE   ProcessHandle,
  [in]           NTSTATUS ExitStatus
);

Хотя здесь указана функция ZwTerminateProcess, а не NtTerminateProcess, но в целом
Zw-версии функций и Nt-версии аналогичны.

И из определения функции мы видим, что она принимает два параметра:

  • ProcessHandle: дескриптор процесса, который надо закрыть. Это необязательный параметр. Если он равен 0, то закрываем текущий процесс.

  • ExitStatus: статус завершения процесса, в качестве которого выступает числовой код и который обычно возвращается данной функцией.

Применим данную функцию в программе:

.globl main
 
.text
main: 
    movq $0, %r10       # первый параметр - ProcessHandle не указываем
    movq $17, %rdx      # второй параметр - код статуса - произвольное число
    movq $44, %rax      # в rax номер вызываемой системной функции -  44 - NtTerminateProcess
    syscall             # вызываем системную функцию
    ret

Поскольку первый параметр необязательный, и мы хотим завершить текущую программу, то первому параметру через регистр R10 передаем значение 0.
Второму параметру через регистр RDХ передается произвольный числовой код статуса, в нашем случае число 17.

Для вызова системной функции инструкции в регистр %rax передается числовой код функции — 44, и выполняется инструкция syscall.
Результат компиляции и вызова программы (допустим, код программы расположен в файле hello.s и компилируется в файл hello.exe):

c:\asm>as hello.s -o hello.o

c:\asm>ld hello.o -o hello.exe

c:\asm>hello.exe

c:\asm>echo %ERRORLEVEL%
17

c:\asm>

Таким образом, функция NtTerminateProcess возвратила число 17, которое передавалось через второй параметр функции.

NtWriteFile

Рассмотрим другой пример — запись данных в файл, и как частный случай, вывод строки на консоль. За это отвечает системная функция
NtWriteFile, которая для последних версий Windows имеет номер 8 и которая имеет следующий заголовок:

__kernel_entry NTSYSCALLAPI NTSTATUS NtWriteFile(
  [in]           HANDLE           FileHandle,
  [in, optional] HANDLE           Event,
  [in, optional] PIO_APC_ROUTINE  ApcRoutine,
  [in, optional] PVOID            ApcContext,
  [out]          PIO_STATUS_BLOCK IoStatusBlock,
  [in]           PVOID            Buffer,
  [in]           ULONG            Length,
  [in, optional] PLARGE_INTEGER   ByteOffset,
  [in, optional] PULONG           Key
);

Функция принимает аж 9 параметров, из которых отметим наболее важные.

  • 1-й параметр — FileHandle представляет дескриптор файла (в нашем случае дискриптор консольного вывода).

  • 5-й пареметр IoStatusBlock представляет блок байтов, в который записывается статус операции.

  • 6-й параметр — Buffer — указатель на данные для записи (в нашем случае это будет адрес строки для вывода на экран)

  • 7-й параметр — Length хранит размер записываемых данных (размер строки для вывода)

Все остальные параметры необязательные, и вместо них будет использоваться значение по умолчанию — 0. Но при желении про эти параметры можно прочитать в
документации. Тепеь определим программу для вывода строки на консоль:

.globl main
 
.data
message: .asciz "Hello METANIT.COM\n"
.equ message_len, . - message
.balign 8
IoStatusBlock: .space 16  # буфер для получения статуса
.text
main: 
    subq $88, %rsp
  
    movq $-11, %rcx     # Аргумент для GetStdHandle - STD_OUTPUT
    call GetStdHandle     # вызываем функцию GetStdHandle

    movq %rax, %r10         # первый аргумент
    movq $0, %rdx            # Второй аргумент
    movq $0, %r8             # Третий аргумент
    movq $0, %r9             # Четвертый аргумент
    leaq IoStatusBlock(%rip), %rax  # Пятый аргумент
    movq %rax, 40(%rsp)    
    
    leaq message(%rip), %rax        
    movq %rax, 48(%rsp)    # Шестой аргумент - строка для вывода
    movq $message_len, 56(%rsp)    # # Седьмой аргумент - длина строки
    movq $0, 64(%rsp)            # Восьмой аргумент - для него выделяем память в стеке
    movq $0, 72(%rsp)      # Девятый аргумент - для него выделяем память в стеке
    movq $8, %rax          # вызов системной функции NtWriteFile
    syscall

    movq $0, %r10       # первый параметр - ProcessHandle не указываем
    movq $message_len, %rdx      # второй параметр - код статуса - произвольное число
    movq $44, %rax      # в rax номер вызываемой системной функции -  44 - NtTerminateProcess
    syscall             # вызываем системную функцию
    addq $88, %rsp     # очищаем стек 

    ret

Для упрощения для получения дескриптора консольного вывода используем функцию GetStdHandle. Эта функция возвращает через регистр
RAX дескриптор, который помещаем в регистр R10. Стоит отметить, что поскольку системный вызов NtWriteFile принимает 9 параметров, соответственно все параметры
не поместятся в 4 стандартных регистра, поэтому выделяем достаточное местов в стеке. Причем пятый параметр (он же первый параметр, который помещается в стек) должен начинаться в стеке со смещения
40(%rsp). Большинство параметров необязательные, и данном случае не имеют значения, поэтому передаем им значение 0.:

movq %rax, %r10         # первый аргумент
movq $0, %rdx            # Второй аргумент
movq $0, %r8             # Третий аргумент
movq $0, %r9             # Четвертый аргумент
leaq IoStatusBlock(%rip), %rax  # Пятый аргумент
movq %rax, 40(%rsp)    
    
leaq message(%rip), %rax        
movq %rax, 48(%rsp)    # Шестой аргумент - строка для вывода
movq $message_len, 56(%rsp)    # # Седьмой аргумент - длина строки
movq $0, 64(%rsp)            # Восьмой аргумент - для него выделяем память в стеке
movq $0, 72(%rsp)      # Девятый аргумент - для него выделяем память в стеке

После установки параметров вызываем системную функцию:

movq $8, %rax          # вызов системной функции NtWriteFile
syscall

Поскольку в программе используется функция GetStdHandle, то при компоновке программы необходимо передать компоновщику системную
библиотеку kernel32. Полный консольный вывод программы с компиляцией:

c:\asm>as hello.s -o hello.o

c:\asm>ld hello.o -o hello.exe -lkernel32

c:\asm>hello.exe
Hello METANIT.COM

c:\asm>echo %ERRORLEVEL%
19

c:\asm>

Windows System Call Tables

The repository contains system call tables collected from all modern and most older releases of Windows, starting with Windows NT.

Both 32-bit and 64-bit builds were analyzed, and the tables were extracted from both the core kernel image (ntoskrnl.exe) and the graphical subsystem (win32k.sys).

Formats

The data is formatted in the CSV and JSON formats for programmatic use, and as an HTML table for manual inspection.

The HTML files are also hosted on my blog under the following links:

  • ntoskrnl.exe, x86: https://j00ru.vexillium.org/syscalls/nt/32/
  • ntoskrnl.exe, x64: https://j00ru.vexillium.org/syscalls/nt/64/
  • win32k.sys, x86: https://j00ru.vexillium.org/syscalls/win32k/32/
  • win32k.sys, x64: https://j00ru.vexillium.org/syscalls/win32k/64/

Operating systems

The following major versions of Windows are included in the tables:

System x86 versions x64 versions
Windows NT 3.x 3.1, 3.5, 3.51
Windows NT 4.0 SP0, SP1, SP2, SP3, SP3 Terminal Server Edition, SP4, SP5, SP6
Windows 2000 SP0, SP1, SP2, SP3, SP4
Windows XP SP0, SP1, SP2, SP3 SP1, SP2
Windows Server 2003 SP0, SP1, SP2, R2, R2 SP2 SP0, SP2, R2, R2 SP2
Windows Vista SP0, SP1, SP2 SP0, SP1, SP2
Windows 7 SP0, SP1 SP0, SP1
Windows 8 8.0, 8.1 8.0, 8.1
Windows 10 1507, 1511, 1607, 1703, 1709, 1803, 1809, 1903, 1909, 2004, 20H2, 21H1, 21H2, 22H2 1507, 1511, 1607, 1703, 1709, 1803, 1809, 1903, 1909, 2004, 20H2, 21H1, 21H2, 22H2
Windows 11 21H2, 22H2, 23H2, 24H2
Windows Server 2022, 23H2, 2025

Some older versions of Windows Server are not included, as their syscall tables are equivalent to these of desktop Windows editions:

Windows Server version Windows Desktop version
2008 SP0/SP2 Vista SP1/SP2
2008 R2 SP0/SP1 7 SP0/SP1
2012 SP0 8.0
2012 R2 8.1
2016 LTSC (1607) 10 1607
1709 10 1709
1803 10 1803
2019 LTSC (1809) 10 1809
1903 10 1903
1909 10 1909
2004 10 2004
20H2 10 20H2

Historical system call counts

Below is a line chart showing the progression of Windows system call development over time. It covers all major desktop versions of Windows starting with Windows NT 3.1 released in July 1993, up to the most recent versions of Windows 11. Server editions are not included for brevity. The analysis was performed on x86 builds for consistency, with the exception of Windows 11 where x64 is the only supported platform. There might be very small differences on x64 builds of the kernel or the less popular editions (e.g. Windows NT 4.0 Terminal Server Edition), but they are insignificant for the purpose of this overview chart.

Historical system call counts

Thanks

We would like to thank the following contributors to the project: Woodmann, Deus, Gynvael Coldwind, MeMek, Alex, Omega Red, Wandering Glitch.

Contact

Mateusz ‘j00ru’ Jurczyk (j00ru.vx@gmail.com)

Введение

Системные вызовы выступают в роли посредников между приложениями и ядром. Они создают уровень абстракции, который защищает важные компоненты системы, такие как ЦП и память, от случайных ошибок и целенаправленных атак.

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

Что такое системный вызов? 

Системный вызов – это интерфейс между программой, которая работает в пользовательском пространстве, и операционной системой (ОС). Прикладные программы используют системные вызовы для того, чтобы запрашивать действия и функции у ядра ОС. Этот механизм позволяет программе вызывать действия, например, чтение из файла, не обращаясь к системным ресурсам напрямую.

Когда программа обращается к системному вызову, контекст выполнения переключается с пользовательского режима в режим ядра, позволяя системе получить доступ к аппаратному обеспечению и безопасно выполнить необходимые операции. После того, как операции завершены, управление возвращает в пользовательский режим, а программа продолжает свое выполнение.

Такой многоуровневый подход, осуществляемый при помощи системных вызовов:

  • Гарантирует изоляцию аппаратных ресурсов от процессов пользовательского пространства
  • Не допускает прямого доступа к ядру или аппаратной памяти
  • Позволяет коду приложения работать на различных аппаратных архитектурах

Какова задача системного вызова?

Системные вызовы выполняют несколько довольно важных функций:

  • Граница между пользователем и ядром. При запросе действия у ядра системные вызовы выступают в качестве авторизованного шлюза для пользовательских программ. Они гарантируют, что последние не смогут получить доступ к функциям ядра или критически важным системным ресурсам без достаточных оснований.
  • Управление ресурсами. С помощью системных вызовов пользовательские программы могут запрашивать важными ресурсами и управлять ими, например, временем ЦП, памятью и хранилищем файлов. ОС контролирует этот процесс и гарантирует, что он выполняется по всем правилам.
  • Более простая разработка. Системные вызовы позволяют абстрагироваться от сложностей аппаратного обеспечения. Таким образом, разработчики могут выполнять такие операции, как чтение и запись в файл или управление данными сети, и не писать отдельный код для аппаратного обеспечения.
  • Безопасность и контроль доступа. Системные вызовы выполняют проверки для того, чтобы гарантировать, что запросы, отправленные пользовательскими программами, действительны и что программы имеют необходимые права доступа для выполнения запрашиваемых операций. 
  • Межпроцессное взаимодействие (IPC — Inter-Process Communication). Системные вызовы предоставляют механизмы, с помощью которых процессы могут взаимодействовать друг с другом. Они предлагают такие средства, как каналы, очереди сообщений и общую память, для упрощения межпроцессного взаимодействия.
  • Сетевые операции. Системные вызовы предоставляют фреймворк для того, чтобы программы могли взаимодействовать по сети. Разработчики могут полностью сконцентрироваться на построении логики своего приложения вместо того, чтобы уделять внимание низкоуровневому сетевому программированию.

Как работают системные вызовы?

Здесь кратко описано как работают системные вызовы:

1. Запрос системного вызова. Приложение запрашивает системный вызов, используя для этого соответствующую функцию. Например, для того, чтобы прочитать данные из файла, программа может использовать функцию read().

2. Переключение контекста в пространство ядра. Для инициирования переключения контекста и перехода из пользовательского режима в режим ядра используются программное прерывание и специальные инструкции.

3. Идентификация системного вызова. Для идентификации системного вызова и адреса соответствующей функции ядра система использует индекс.

4. Выполнение функции ядра. Выполняется функция ядра, соответствующая системному вызову, например, чтение данных из файла.

5. Подготовка возвращаемых значений. После того, как функция ядра завершает свою работу, все возвращаемые значения или результаты подготавливаются для отправки в пользовательское приложение.

6. Переключение контекста в пользовательское пространство. Контекст выполнения переключается обратно из режима ядра в пользовательский режим.

7. Возобновление работы приложения. Приложение возобновляет свою работу с момента своей остановки, но теперь уже с результатами системного вызова.

Примечание: точное количество шагов и принцип работы системных вызовов могут различаться в зависимости от операционной системы.

Каковы функции системных вызовов?

Ниже представлены функции, характеризующие системные вызовы:

  • Безопасность. Системные вызовы гарантируют, что приложения пользовательского пространства никак не смогут навредить системе или помешать другим процессам.
  • Абстракция. Программам, например, не нужно знать особенности конфигурации сетевого оборудования для того, чтобы отправлять данные через Интернет или выполнять операции с диском для чтения файлов, так как эти задачи выполняет операционная система.
  • Контроль доступа. Системные вызовы обеспечивают соблюдение всех необходимых мер безопасности, проверяя, имеет ли программа соответствующие права доступа для обращения к ресурсам. 
  • Согласованность. Взаимодействие между ОС и программой остается согласованным, независимо от базовой конфигурации аппаратного обеспечения. Одна и та же программа может работать на разном оборудовании, главное, чтобы ее поддерживала операционная система.
  • Синхронное выполнение. Многие системные вызовы выполняются синхронно, блокируя вызывающий процесс до завершения операции. Однако существуют и асинхронные системные вызовы, которые позволяют процессам продолжать выполнение, не ожидая завершения операции.
  • Управление процессами. Системные вызовы упрощают управление процессами и выполнение нескольких задач одновременно за счет механизмов создания, завершения, планирования и синхронизации процессов.
  • Управление файлами. Системные вызовы поддерживают операции с файлами, такие как такие как чтение, запись, открытие и закрытие файлов.

File operations via system calls.

  • Управление устройствами. С помощью системных вызовов процессы могут запрашивать доступ к устройствам, выполнять операции чтения/записи на этих устройствах и освобождать их. 
  • Управление ресурсами. Системные вызовы помогают выделять и освобождать ресурсы, такие как память, время ЦП и устройства ввода-вывода.
  • Текущее обслуживание. Системные вызовы можно использовать для получения или настройки системной информации, такой как дата и время или состояние процесса.
  • Взаимодействие. Системные вызовы позволяют процессам взаимодействовать друг с другом и синхронизировать свои действия.
  • Обработка ошибок. Если системный вызов не может быть завершен, он возвращает код ошибки, который может обработать вызывающая программа.

Типы системных вызовов

Следующий перечень представляет собой классификацию системных вызовов на основании их функций:

1. Управление процессами

Системные вызовы играют важную роль в управлении системными процессами. С их помощью можно: 

  • Создавать новые процессы и завершать текущие
  • Загружать и выполнять программы в пространстве процесса
  • Планировать процессы и устанавливать параметры выполнения, например, приоритет
  • Дожидаться завершения процесса или подавать сигнал о его завершении

2. Управление файлами

Системные вызовы могут выполнять различные операции с файлами, например,

  • Чтение файлов и запись в файлы
  • Открытие и закрытие файлов
  • Удаление и изменение файловых атрибутов
  • Перемещение или переименование файлов

3. Управление устройствами

Системные вызовы можно использовать для помощи в управлении устройствами, а именно для:

  • Запроса доступа к устройству и его освобождения после использования
  • Установка атрибутов и параметров устройства
  • Чтение с устройств или запись на устройства
  • Сопоставление имен логических устройств с физическими

4. Информационное обеспечение

Эти системные вызовы позволяют процессам:

  • Получать и изменять различные системные атрибуты
  • Устанавливать системную дату и время
  • Запрашивать показатели производительности системы

5. Взаимодействие 

Эти системные вызовы упрощают:

  • Отправку и получение сообщение между процессами
  • Синхронизацию действий между пользовательскими процессами
  • Организации областей разделяемой памяти для межпроцессного взаимодействия
  • Работу в сети через сокеты

6. Безопасность и управление доступом

Системные вызовы вносят свой вклад в обеспечение безопасности и управление доступом за счет:

  • Определения того, какие процессы или пользователи получают доступ к тем или иным ресурсам, и кто может читать, записывать и выполнять ресурсы
  • Упрощения процедур аутентификации пользователей

Примеры системных вызовов

Ниже в таблице перечислены самые распространенные системные вызовы Unix и Windows и их описания.

Примечание: поведение системного вызова, его параметры и возвращаемые значения могут отличаться в зависимости от операционной системы и ее версии. Более подробную информацию можно найти в документации к операционной системе.

СИСТЕМНЫЙ ВЫЗОВЫ UNIX

ОПИСАНИЕ

СИСТЕМНЫЕ ВЫЗОВЫ WINDOWS

ОПИСАНИЕ

Управление процессами

fork()

Создает новый процесс

CreateProcess()

Создает новый процесс

exit()

Завершает текущий процесс

ExitProcess()

Завершает текущий процесс

wait()

Переводит процесс в режим ожидания до тех пор, пока не завершатся его дочерние процессы

WaitForSingleObject()

Ждет, пока процесс или поток завершит свою работу

exec()

Выполняет новую программу в процессе

CreateProcess() или 
ShellExecute()

Выполняет новую программу в процессе

getpid()

Получает уникальный идентификатор процесса

GetCurrentProcessId()

Получает уникальный идентификатор процесса

Управление файлами

open()

Открывает файл (или устройство)

open()

Открывает или создает файл или устройство

close()

Закрывает открытый файл (или устройство)

close()

Закрывает дескриптор открытого объекта

read()

Выполняет чтение из файла (или устройства)

read()

Выполняет чтение данных из файла или устройство ввода

write()

Выполняет запись в файл (или устройство)

write()

Выполняет запись данных в файл или устройство вывода

lseek()

Изменяет место выполнения чтения/записи в файле

lseek()

Устанавливает положение указателя позиции в файле

unlink()

Удаляет файл

unlink()

Удаляет существующий файл

rename()

Переименовывает файл

rename()

Перемещает или переименовывает файл

Управление каталогами

mkdir()

Создает новый каталог

CreateDirectory()

Создает новый каталог

rmdir()

Удаляет каталог

RemoveDirectory()

Удаляет существующий каталог

chdir()

Изменяет текущий каталог

SetCurrentDirectory()

Изменяет текущий каталог

stat()

Получает статус файла

GetFileAttributesEx()

Получает расширенные атрибуты файла

fstat()

Получает статус открытого файла

GetFileInformationByHandle()

Получает информацию о файле, используя его дескриптор

link()

Создает ссылку на файл

CreateHardLink()

Создает жесткую ссылку на существующий файл

symlink()

Получает статус открытого файла

CreateSymbolicLink()

Создает символическую ссылку

Управление устройствами

brk()или sbrk()

Увеличивает/уменьшает пространство данных программы 

VirtualAlloc()или
VirtualFree()

Резервирует, фиксирует изменения или освобождает область памяти

mmap()

Проецируют файлы или устройства в память

MapViewOfFile()

Проецирует файл в адресное пространство приложения

Информационное обеспечение

time()

Получает текущее время

GetSystemTime()

Получает текущее системное время

alarm()

Получает статус открытого файла

SetWaitableTimer()

Устанавливает таймер

getuid()

Устанавливает будильник для подачи сигнала

GetUserName()или
LookupAccountName()

Получает имя пользователям или его ID

getgid()

Получает идентификатор группы

GetTokenInformation()

Получает информацию о маркере доступа

Взаимодействие

socket()

Создает новый сокет

socket()

Создает новый сокет

bind()

Привязывает сокет к сетевому адресу

bind()

Привязывает сокет к сетевому адресу

listen()

Привязывает сокет к сетевому адресу

listen()

Отслеживает соединения в сокете 

accept()

Принимает новое соединение в сокете

accept()

Принимает новое соединение в сокете

connect()

Инициализирует соединение в сокете

connect()

Инициализирует соединение в сокете

send()или recv()

Отправляет и получает данные через сокет

send()или recv()

Отправляет и получает данные через сокет

Безопасность и управление доступом

chmod()или umask()

Изменяет права доступа/режим файла

SetFileAttributes()или SetSecurityInfo()

Изменяет атрибуты файла или сведения о защите

chown()

Изменяет владельца или группу файла

SetSecurityInfo()

Устанавливает сведения о защите

Как передавать параметры системным вызовам?

Когда пользовательская программа обращается к системному вызову, ей, как правило, для того, чтобы указать запрос, нужно передать ему дополнительные параметры. То, насколько грамотно передаются эти параметры между пользователем и ядром, влияет на производительность системы. 

Способ передачи параметров зависит от системной архитектуры, но есть некоторые общие правила:

  • Ограниченное количество параметров. Чаще всего системные вызовы принимают ограниченное количество параметров. Это правило нужно для того, чтобы упростить взаимодействие и принудить пользователей использовать структуры данных или блоки памяти.
  • Использование регистров ЦП. Регистры ЦП – это области памяти, к которым можно быстрее всего получить доступ. Количество регистров ЦП ограничено, а это значит, что количество передаваемых вызову параметров также ограничено. Если вы передаете небольшое количество параметров, используйте регистры ЦП.

  • Использование указателей для агрегирования данных. Вместо того, чтобы передавать огромное количество параметров или большие объемы данных, используйте переменные-указатели, чтобы указывать на блоки или структуры памяти (которые содержат все параметры). Ядро будет использовать этот указатель для того, чтобы получить доступ к этому блоку памяти и извлечь параметры.
  • Проверка целостности и безопасности данных. Ядро должно проверять любые указатели, которые передаются из пользовательского пространства. Оно должно проверить, что эти указатели относятся только к тем областям, к которым имеет доступ пользовательская программа. Кроме того, прежде чем использовать данные, которые поступают из пользовательских программ, оно их перепроверяет.
  • Обработка стековых параметров. Некоторые системы помещают параметры в стек, и для того, чтобы выполнить их обработку, ядру приходится их извлекать. Такой метод не так распространен, как использование регистров ЦП и указателей, поскольку он более сложен с точки зрения реализации и управления.
  • Изоляция данных путем их копирования. Ядро часто копирует данные из пространства пользователя в пространство ядра (и наоборот). Оно это делает для того, чтобы защитить систему от ошибочных или вредоносных данных. В связи с этим, данные, которые передаются между этими двумя пространствами, не должны передаваться напрямую. 
  • Возвращаемые значения и обработка ошибок. Системный вызов возвращает значение – как правило, это код успешного завершения или ошибки. В случае получения кода ошибки, всегда пытайтесь найти больше информации об этой ошибке. Сообщения об ошибках чаще всего хранятся в определенных местах, например, в переменной errno (Linux).

Примечание: правила и методы, приведенные выше, могут различаться в зависимости от архитектуры (x86, ARM, MIPS и т.д.) и особенностей операционной системы. Всегда обращайтесь к документации операционной системы или исходному коду, чтобы получить более точную информацию.

Заключение

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

Аннотация: В лекции описаны прерывания, системные вызовы и исключительные ситуации, которые являются фундаментальными механизмами операционных систем, и проанализированы особенности их реализации в ОС Windows. Обработка всех типов событий осуществляется единым образом и связана с сохранением/восстановлением состояния и эффективным поиском программы обработчика по системным таблицам. Важную роль для правильной организации имеет иерархия событий, реализованная в виде набора IRQL-приоритетов

Прерывания, исключения, системные вызовы

В любой операционной системе существует набор базовых концепций и базовых механизмов, ставших неотъемлемой частью теории и практики ОС. Например, в
«Создание ОС Windows. Структура ОС Windows»
были приведены краткие описания процессов и потоков. Ниже будет подробно рассмотрена реализация ряда других важных концепций современных ОС.

Из теории ОС известно
[
Карпов
]
,
[
Таненбаум
]
,
[
Столлингс
]
, что современные ОС реализуют поддержку системных вызовов, обработку прерываний и исключительных ситуаций, которые относят к основным механизмам ОС.

Системные вызовы (system calls) — механизм, позволяющий пользовательским программам обращаться к услугам ядра ОС, то есть это интерфейс между операционной системой и пользовательской программой. Концептуально системный вызов похож на обычный вызов подпрограммы. Основное отличие состоит в том, что при системном вызове выполнение программы осуществляется в привилегированном режиме или режиме ядра. Поэтому системные вызовы иногда еще называют программными прерываниями, в отличие от аппаратных прерываний, которые чаще называют просто прерываниями. В большинстве операционных систем системный вызов является результатом выполнения команды программного прерывания ( INT ). Таким образом, системный вызов — это синхронное событие.

Прерывание (hardware interrupt) — это событие, генерируемое внешним (по отношению к процессору) устройством. Посредством аппаратных прерываний аппаратура либо информирует центральный процессор о том, что произошло событие, требующее немедленной реакции (например, пользователь нажал клавишу), либо сообщает о завершении операции ввода вывода (например, закончено чтение данных с диска в основную память). Каждый тип аппаратных прерываний имеет собственный номер, однозначно определяющий источник прерывания. Аппаратное прерывание — это асинхронное событие, то есть оно возникает вне зависимости от того, какой код исполняется процессором в данный момент. Обработка аппаратного прерывания не должна учитывать, какой процесс или поток является текущим.

Исключительная ситуация (exception) — событие, возникающее в результате попытки выполнения программой команды, которая по каким-то причинам не может быть выполнена до конца. Примерами таких команд могут быть попытки доступа к ресурсу при отсутствии достаточных привилегий или обращение к отсутствующей странице памяти. Исключительные ситуации, как и системные вызовы, являются синхронными событиями, возникающими в контексте текущей задачи. Исключительные ситуации можно разделить на исправимые и неисправимые. К исправимым относятся такие исключительные ситуации, как отсутствие нужной информации в оперативной памяти. После устранения причины исправимой исключительной ситуации программа может выполняться дальше.
Возникновение в процессе работы операционной системы исправимых исключительных ситуаций считается нормальным явлением. Неисправимые исключительные ситуации чаще всего возникают в результате ошибок в программах (например, деление на ноль). Обычно в таких случаях операционная система реагирует завершением программы, вызвавшей исключительную ситуацию.

Применяя структурную обработку исключений, упомянутую в предыдущей лекции, можно попытаться «исправить» неисправимую исключительную ситуацию, вернув управление программе, которая сгенерировала эту ситуацию.

Прогон программы реализующей структурную обработку исключений

В качестве упражнения рекомендуется выполнить прогон программы, в которой произведена обработка деления на 0. Особенности применения операторов try и except описаны в MSDN.

#include <stdio.h>

void main() {

int i = 1, j = 0, k = 0;
__try {
   k = i / j;
   puts("in try");
   printf("k=%d\n",k);
}
__except (1) {
   puts("in except");
   printf("k=%d\n",k);
}
}

Реализация прерываний, системных вызовов и исключений в ОС Windows

Рассмотрим реализацию основных механизмов операционной системы в ОС Windows. Следует отметить, что терминология корпорации Microsoft несколько отличается от общепринятой. Например, системные вызовы называются системными сервисами, а под программным прерыванием (см. прерывания DPC и APC) понимается выполнение специфичных функций ядра, требующих прерывания работы текущего процесса.

Ловушки

Общим для реализации рассматриваемых основных механизмов является необходимость сохранения состояния текущего потока с его последующим восстановлением. Для этого в ОС Windows используется механизм ловушек (trap). В случае возникновения требующего обработки события (прерывания, исключения или вызова системного сервиса) процессор переходит в привилегированный режим и передает управление обработчику ловушек, входящему в состав ядра. Обработчик ловушек создает в стеке ядра (о стеке ядра см.
«Реализация процессов и потоков»
) прерываемого потока фрейм ловушки, содержащий часть контекста потока для последующего восстановления его состояния, и в свою очередь передает управление определенной части ОС, отвечающей за первичную обработку произошедшего события.

В типичном случае сохраняются и впоследствии восстанавливаются:

  • программный счетчик;
  • регистр состояния процессора;
  • содержимое остальных регистров процессора;
  • указатели на стек ядра и пользовательский стек;
  • указатели на адресное пространство, в котором выполняется поток (каталог таблиц страниц процесса).

Эта информация специфицирована в структуре CONTEXT (файл winnt.h), и может быть получена пользователем с помощью функции GetThreadContext.

Адрес части ядра ОС, ответственной за обработку данного конкретного события определяется из вектора прерываний, который номеру события ставит в соответствие адрес процедуры его первичной обработки. Это оказывается возможным, поскольку все события типизированы и их число ограничено. Для асинхронных событий их номер определяется контроллером прерываний, а для синхронных — ядром. В
[
Руссинович
]
описана процедура просмотра вектора прерываний, который в терминологии корпорации Microsoft называется таблицей диспетчеризации прерываний (interrupt dispatch table, IDT), при помощи отладчика kd. Например, для x86 процессора прерыванию от клавиатуры соответствует номер 0x52, системным сервисам — 0x2e, а исключительной ситуации, связанной со страничной ошибкой, — 0xE (см.
рис.
3.1рс. 3.1).

Вектор прерываний (IDT)

Рис.
3.1.
Вектор прерываний (IDT)

После прохождения первичной обработки для каждого события предусмотрена процедура его последующей обработки другими частями ОС. Например, обработка системного сервиса (системного вызова) предполагает передачу управления по адресу 0x2e, где располагается диспетчер системных сервисов, которому через регистры EAX и EBX передаются номер запрошенного сервиса и список параметров, передаваемых этому системному сервису.

То же самое происходит в случае возникновения исключений и прерываний. Простые исключения могут быть обработаны диспетчером ловушек, а более сложные обрабатываются диспетчером исключений, который может в случае возникновения исключения вернуть управление вызвавшему это исключение приложению. Это делается с помощью упомянутого выше аппарата структурной обработки исключений. Вторичная обработка прерывания обеспечивается драйверами соответствующих устройств.

В качестве примера рассмотрим процедуру обработки создания файла. Вызов Win32 функции CreateFile() генерирует передачу управления функции NtCreateFile исполнительной системы, ассемблерный код которой содержит следующие операции:

mov еах, Ox17   номер системного сервиса для NtCreateFile
mov ebx, esp    
int Ox2E        обработка системного сервиса
ret Ox2C        возврат управления

Рисунок 3.2 иллюстрирует дальнейшую обработку данного сервиса.

Пример обработки системного вызова (системного сервиса).

Рис.
3.2.
Пример обработки системного вызова (системного сервиса).

Приоритеты. IRQL

В большинстве операционных систем аппаратные прерывания имеют приоритеты, которые определяются контроллерами прерываний. Однако ОС Windows имеет свою аппаратно-независимую шкалу приоритетов, которые называются уровни запросов прерываний (interrupt request levels, IRQL), и охватывает не только прерывания, а все события, требующие системной обработки. В таблице 3.1 приведены значения IRQL уровней для x86 систем.

Таблица
3.1.
Уровни запросов прерываний (IRQL) в x86 системах

Уровень Значение Номер
High Наивысший уровень 31
Power fail Отказ электропитания 30
Inter-process interrupt Межпроцессорный сигнал 29
Clock Системные часы 28
Profile Контроль производительности ядра 27
Device n Прерывание от устройства 26
Прерывания от устройств
Device 1 Прерывание от устройства 3
DPC/dispatch Отложенные операции и планирование 2
APC Асинхронные вызовы процедур 1
Passive Нормальное выполнение потоков 0

Обрабатываемые события обслуживаются в порядке их приоритета, и события с более высоким приоритетом вытесняют обработку событий с меньшим приоритетом. При возникновении события с высоким приоритетом IRQL процессора повышается до уровня данного события. После его обработки могут проявить себя замаскированные менее приоритетные события, которые, в свою очередь, могут быть обработаны по обычной схеме. Текущий уровень приоритета хранится в данных, описывающих состояние процессора, и может быть определен системным отладчиком kd или посредством вызова функции KeGetCurrentIrql.

Значения IRQL для аппаратных прерываний расставляются диспетчером Plug and Play с помощью уровня абстрагирования от оборудования HAL, а для остальных событий — ядром. Таким образом, уровень IRQL определяется источником события, что имеет иной смысл, нежели приоритеты в стратегии планирования потоков. Разбиение на IRQL уровни является основным механизмом упорядочивания по приоритетам действий операционной системы.

Можно сказать, что в ОС Windows действует двухуровневая схема планирования. Приоритеты высшего уровня (в данном случае IRQLs) определяются аппаратными или программными прерываниями, а приоритеты низшего уровня (в своем диапазоне от 0 до 31) устанавливаются для пользовательских потоков, выполняемых на нулевом уровне IRQL, и контролируются планировщиком.

На нулевом (PASSIVE LEVEL) уровне IRQL работают пользовательские процессы и часть кода операционной системы. Программа, работающая на этом уровне, может быть вытеснена почти любым событием, случившимся в системе. Большинство процедур режима ядра старается удерживать IRQL уровень процессора как можно более низким.

IRQL уровни 1 (APC LEVEL) и 2 (DISPATCH LEVEL) предназначены для так называемых программных (в терминологии Microsoft) прерываний соответственно: асинхронный вызов процедуры — APC (asynchronous procedure call) и отложенный вызов процедуры — DPC (deferred procedure call). Если ядро принимает решение выполнить некоторую системную процедуру, но нет необходимости делать это немедленно, оно ставит ее в очередь DPC и генерирует DPC прерывание. Когда IRQL процессора станет достаточно низким, эта процедура выполняется. Характерный пример — отложенная операция планирования. Из этого следует, что код, выполняемый на IRQL уровне, выше или равном 2, не подвержен операции планирования. Асинхронный вызов процедур — механизм, аналогичный механизму DPC, но более общего назначения, в частности, доступный пользовательским процессам.

IRQL уровни 3-26 относятся к обычным прерываниям от устройств. Более подробное описание IRQL уровней имеется в
[
Руссинович
]
.

Заключение

В настоящей лекции описаны прерывания, системные вызовы и исключительные ситуации, которые являются фундаментальными механизмами операционных систем, и проанализированы особенности их реализации в ОС Windows. Обработка всех типов событий осуществляется единым образом и связана с сохранением/восстановлением состояния и эффективным поиском программы обработчика по системным таблицам. Важную роль для правильной организации имеет иерархия событий, реализованная в виде набора IRQL приоритетов.

Everyone who’s familiar with operating systems theoretical structure, whether he attented a college course or he has just read a book on this subject, knows the concept of a system call i.e. how a user space application talks with the kernel asking it to perform various jobs such as opening a file, creating a memory mapped region, etc.

Those system calls are usually described as putting some value ( the syscall number ) in a CPU register and then call an OS dependant interrupt, for instance ( the syscall number here was totally invented, just showing you an example )

1
2
3
mov eax, 0x1234
lea edx, [esp+4]
int 0x2E

This piece of assembly code would invoke the 0x1234 syscall on a 32bit Windows 2000 system, but this mechanism had deeply changed starting from Windows XP and later versions.

XP, SYSENTER and KiFastSystemCall

Windows XP was the first version of the Microsoft OS which introduced the KiFastSystemCall mechanism, look at the following code which is basically the same as the previous one:

1
2
3
4
mov eax, 0x1234
mov edx, address of ntdll!KiFastSystemCall
call edx
retn 8

If we disassemble the KiFastSystemCall symbol exported by ntdll.dll we find the following code:

1
2
3
mov edx, esp
sysenter
retn

Notice the sysenter operator, as stated by the Intel instruction set reference manual ( vol. 2 p. 721 ) :

The SYSENTER instruction is part of the "Fast System Call" facility introduced on the
Pentium® II processor. The SYSENTER instruction is optimized to provide the maximum
performance for transitions to protection ring 0 (CPL = 0).

The SYSENTER and SYSEXIT instructions do not constitute a call/return pair; therefore, the
system call "stub" routines executed by user code (typically in shared libraries or DLLs) must
perform the required register state save to create a system call/return pair.
The SYSENTER instruction always transfers to a flat protected mode kernel at CPL = 0.
SYSENTER can be invoked from all modes except real mode.

So this is basically a new opcode introduced by Intel which makes swapping from Ring 3 to Ring 0 and back faster than it was with the old interrupt call.

64bit Systems

You will find that on 64bit systems things are slightly different ( I’ve just tested this on a Windows 7 SP1 64bit installation, please correct me if I’m wrong for other OS versions ), if we take a look at the code of NtCreateFile inside ntdll, the code is:

1
2
3
4
mov     r10, rcx
mov eax, 52h
syscall
retn

As you can see there’s no call to KiFastSystemCall, instead the eax register is filled with the syscall number ( 52h in this case ) and sysenter is called directly by the NT API, but what about 32bit applications running under a WOW64 environment ?

Just WOW64

Obviously there’s some trick behind it, how a 32bit application could ask a 64bit processor to perform a transition from Ring3 to Ring0? As you probably know, Windows has a subsystem called WOW64 which acts as an emulation layer for 32bit apps under 64bit architectures. Among other things WOW64 is composed by a full set of 32bit stub/proxy libraries who make the app run without problems while WOW manages the switch between 32bit and 64bit OS code. An example of the KiFastSystemCall mechanism under WOW64 would be ( always talking about NtCreateFile )

1
2
3
4
5
6
mov	eax,52h
xor ecx,ecx
lea edx,[esp+04h]
call fs:[C0h]
add esp,04h
retn 002Ch

Very similar to the 32bit counterpart, but this time the call is towards FS:C0h, a field in the TIB which contains a pointer to another call. So let’s try to see what’s in there with the following C application.

1
2
3
4
5
6
7
8
#include <windows.h>
#include <stdio.h>

int main(int argc, char* argv[])
{
printf( "FS:[C0h] : %08X\n", __readfsdword(0xc0) );
printf( "KiFastSystemCall : %08X\n", GetProcAddress( GetModuleHandle("ntdll"), "KiFastSystemCall" ) );
}

On my computer this program prints the following results:

FS:[C0h]         : 75452320
KiFastSystemCall : 77B101D0

It is clear that we’re not invoking KiFastSystemCall anymore, so what’s at address 75452320 and by whom is contained? Nothing OllyDbg can’t find out :)

OllyDbg WOW64 Syscall

Wait, what?! An anonymous memory region? Let’s go deeper …

OllyDbg WOW64 jmp

And this is where the transition from 32bit to 64bit code occurs, with a far jump to 7545271E with the code segment being set at 33h, i.e. a jmp to the symbol CpupReturnFromSimulatedCode of wow64cpu.dll, a 64bit library which is always loaded into a 32bit application address space but it’s hidden from the PEB by the OS itself ( that’s why Olly saw it as an anonymous memory region ).
Going deeper in its content we would see that the syscall is performed just as we saw before, setting the proper syscall number and then calling the real KiFastSystemCall from 64bit ntdll.dll.

Using raw system calls instead of normal high level API is obviously unusual and unnecessarily uncomfortable, except if you want to evade some monitoring/hooking software and obtain a basic code obfuscation … think about it, you won’t use any API but just set up some registers and then calling sysenter, isn’t it cool ? :)
The problem here is on every Windows version, and among each service pack too syscall numbers may vary and there’s no official way to obtain the correct values for the system your application is running on.
By “official ways” I mean there’s no API Microsoft implemented to have this information, but we can always extract those values from the ntdll library we can find during runtime.
We can load it with a simple LoadLibrary, obtain a pointer to the API we’re interested in ( let’s say NtCreateFile ) with GetProcAddress and examine the first opcodes in it … would’t it be cool if we could achieve the same result without loading the library but manually inspecting its content as a portable executable file? Of course it would, we can easily open ntdll.dll, inspect its export directory, obtain the RVA and raw offset of NtCreateFile and then check the first bytes of opcodes. We’ve to expect the first byte to be B8h which is a MOV EAX, IMM32 so we can take the four next bytes and have our syscall number.

The following is an example program I’ve made for this purpose, it parses ntdll export directory and prints a table with each syscall number, RVA and relative API name.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#include <stdio.h>
#include <Windows.h>

#define IS_ADDRESS_BETWEEN( left, right, address ) ( (address) >= (left) && (address) < (right) )

PIMAGE_SECTION_HEADER SectionByRVA( PIMAGE_SECTION_HEADER pSections, DWORD dwSections, DWORD rva )
{
PIMAGE_SECTION_HEADER pSectionHeader = pSections;
DWORD i;

for( i = 0; i < dwSections; i++, pSectionHeader++ )
{

if( IS_ADDRESS_BETWEEN( pSectionHeader->VirtualAddress, ( pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData ), rva ) )
return pSectionHeader;
}

return 0;
}

DWORD RawOffsetByRVA( PIMAGE_SECTION_HEADER pSections, DWORD dwSections, DWORD dwFileSize, DWORD rva )
{
PIMAGE_SECTION_HEADER pSectionHeader;
DWORD dwOffset, dwDelta;

pSectionHeader = SectionByRVA( pSections, dwSections, rva );
if ( !pSectionHeader )
{
return 0;
}

dwDelta = rva - pSectionHeader->VirtualAddress;
dwOffset = pSectionHeader->PointerToRawData + dwDelta;

if( dwOffset >= dwFileSize )
return 0;
else
{
return dwOffset;
}
}

#define GET_POINTER(RVA) ( pBuffer + RawOffsetByRVA( Sections, dwSections, dwFileSize, (RVA) ) )

int main(int argc, char* argv[])
{
HANDLE hFile = INVALID_HANDLE_VALUE,
hMap = NULL;
PBYTE pBuffer = NULL, pOps = NULL;
DWORD dwFileSize = 0,
dwSizeOfHeaders = 0,
dwSections = 0,
dwBaseAddress = 0,
dwImageSize = 0,
dwExportRVA = 0,
dwExportSize = 0,
dwExportRaw = 0,
dwExports = 0;
PDWORD pdwFunctions, pszFunctionNames;
PWORD pwOrdinals;
PIMAGE_NT_HEADERS NTHeader;
PIMAGE_DOS_HEADER DOSHeader;
PIMAGE_SECTION_HEADER Sections;
PIMAGE_EXPORT_DIRECTORY pExportDirectory;

hFile = CreateFile
(
"c:\\windows\\system32\\ntdll.dll",
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if( hFile == INVALID_HANDLE_VALUE )
{
fprintf( stderr, "Could not open file: %08X\n", GetLastError() );
goto done;
}

dwFileSize = GetFileSize( hFile, NULL );

hMap = CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
if( hMap == NULL )
{
fprintf( stderr, "Could not create memory map: %08X\n", GetLastError() );
goto done;
}

pBuffer = (PBYTE)MapViewOfFile( hMap, FILE_MAP_READ, 0, 0, 0 );
if( hMap == NULL )
{
fprintf( stderr, "Could not obtain memory map view: %08X\n", GetLastError() );
goto done;
}

if( pBuffer[0] != 'M' || pBuffer[1] != 'Z' )
{
fprintf( stderr, "Unexpected file header.\n" );
goto done;
}


DOSHeader = (PIMAGE_DOS_HEADER)pBuffer;
NTHeader = (PIMAGE_NT_HEADERS)( pBuffer + DOSHeader->e_lfanew );

dwSizeOfHeaders = NTHeader->OptionalHeader.SizeOfHeaders;
dwBaseAddress = NTHeader->OptionalHeader.ImageBase;
dwImageSize = NTHeader->OptionalHeader.SizeOfImage;
dwSections = NTHeader->FileHeader.NumberOfSections;


Sections = (PIMAGE_SECTION_HEADER)
(
pBuffer +
DOSHeader->e_lfanew +
sizeof(IMAGE_NT_HEADERS)
);


dwExportRVA = NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
dwExportSize = NTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
dwExportRaw = RawOffsetByRVA( Sections, dwSections, dwFileSize, dwExportRVA );

if( !dwExportRVA || !dwExportSize || !dwExportRaw )
{
fprintf( stderr, "Unexpected export directory structure.\n" );
goto done;
}

pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)( pBuffer + dwExportRaw );
pdwFunctions = (PDWORD)GET_POINTER( pExportDirectory->AddressOfFunctions );
pwOrdinals = (PWORD)GET_POINTER( pExportDirectory->AddressOfNameOrdinals );
pszFunctionNames = (PDWORD)GET_POINTER( pExportDirectory->AddressOfNames );
dwExports = pExportDirectory->NumberOfNames;

printf( "SYSCALL RVA NAME\n" );
printf( "-----------------------------------------------\n" );


for( DWORD i = 0; i < pExportDirectory->NumberOfNames; ++i )
{
DWORD dwNameRVA = pszFunctionNames[ i ],
dwApiRVA = pdwFunctions[ pwOrdinals[ i ] ],
dwSyscall = 0,
dwApiRaw = RawOffsetByRVA( Sections, dwSections, dwFileSize, dwApiRVA ),
dwNameRaw = RawOffsetByRVA( Sections, dwSections, dwFileSize, dwNameRVA );

pOps = pBuffer + dwApiRaw;
















if( pOps[0] == 0xB8 &&
(
(
pOps[5] == 0x33 && pOps[6] == 0xC9 &&
!memcmp( &pOps[7], "\x8D\x54\x24\x04", 4 ) &&
!memcmp( &pOps[11], "\x64\xFF\x15\xC0\x00\x00\x00", 7 )
)
||
(
pOps[5] == 0xB9 &&
!memcmp( &pOps[10], "\x8D\x54\x24\x04", 4 ) &&
!memcmp( &pOps[13], "\x64\xFF\x15\xC0\x00\x00\x00", 7 )
)
)
)
{



dwSyscall = *(DWORD *)( pOps + 1 );

printf( "%08X %08X %s\n", dwSyscall, dwBaseAddress + dwApiRVA, pBuffer + dwNameRaw );
}
}

done:

if( hFile != INVALID_HANDLE_VALUE )
{
CloseHandle( hFile );
}

if( pBuffer != NULL )
{
UnmapViewOfFile( pBuffer );
}

if( hMap != NULL )
{
CloseHandle( hMap );
}

return 0;
}

On my Windows 7 computer the output is:

SYSCALL   RVA       NAME
-----------------------------------------------
00000060  7DE90210  NtAcceptConnectPort
00000061  7DE90228  NtAccessCheck
00000026  7DE8FC68  NtAccessCheckAndAuditAlarm
00000062  7DE90240  NtAccessCheckByType
00000056  7DE90114  NtAccessCheckByTypeAndAuditAlarm
00000063  7DE90258  NtAccessCheckByTypeResultList
00000064  7DE90270  NtAccessCheckByTypeResultListAndAuditAlarm
00000065  7DE90288  NtAccessCheckByTypeResultListAndAuditAlarmByHandle
00000066  7DE902A0  NtAddBootEntry
00000067  7DE902B8  NtAddDriverEntry
00000068  7DE902D0  NtAdjustGroupsToken
0000003E  7DE8FEC0  NtAdjustPrivilegesToken
0000006C  7DE9033C  NtAllocateReserveObject
0000006D  7DE90354  NtAllocateUserPhysicalPages
00000015  7DE8FAC0  NtAllocateVirtualMemory
0000006F  7DE90388  NtAlpcAcceptConnectPort
00000070  7DE903A0  NtAlpcCancelMessage
00000071  7DE903B8  NtAlpcConnectPort
00000072  7DE903D0  NtAlpcCreatePort
00000073  7DE903E8  NtAlpcCreatePortSection
00000074  7DE90400  NtAlpcCreateResourceReserve
00000075  7DE90418  NtAlpcCreateSectionView
00000076  7DE90430  NtAlpcCreateSecurityContext
00000077  7DE90448  NtAlpcDeletePortSection
00000078  7DE90460  NtAlpcDeleteResourceReserve
00000079  7DE90478  NtAlpcDeleteSectionView
0000007A  7DE90490  NtAlpcDeleteSecurityContext
0000007B  7DE904A8  NtAlpcDisconnectPort
0000007C  7DE904C0  NtAlpcImpersonateClientOfPort
0000007D  7DE904D8  NtAlpcOpenSenderProcess
0000007E  7DE904F0  NtAlpcOpenSenderThread
0000007F  7DE90508  NtAlpcQueryInformation
00000080  7DE90520  NtAlpcQueryInformationMessage
00000081  7DE90538  NtAlpcRevokeSecurityContext
00000082  7DE90550  NtAlpcSendWaitReceivePort
00000083  7DE90568  NtAlpcSetInformation
00000049  7DE8FFD4  NtApphelpCacheControl
00000002  7DE8F8D8  NtCallbackReturn
0000005A  7DE9017C  NtCancelIoFile
00000086  7DE905B8  NtCancelIoFileEx
00000087  7DE905D0  NtCancelSynchronousIoFile
0000000C  7DE8F9E0  NtClose
00000038  7DE8FE2C  NtCloseObjectAuditAlarm
00000088  7DE905E8  NtCommitComplete
00000089  7DE90600  NtCommitEnlistment
0000008A  7DE90618  NtCommitTransaction
0000008B  7DE90630  NtCompactKeys
0000008C  7DE90648  NtCompareTokens
0000008D  7DE90660  NtCompleteConnectPort
0000008F  7DE90694  NtConnectPort
00000040  7DE8FEF0  NtContinue
00000090  7DE906AC  NtCreateDebugObject
00000091  7DE906C4  NtCreateDirectoryObject
00000092  7DE906DC  NtCreateEnlistment
00000045  7DE8FF74  NtCreateEvent
00000093  7DE906F4  NtCreateEventPair
00000052  7DE900B4  NtCreateFile
00000094  7DE9070C  NtCreateIoCompletion
00000095  7DE90724  NtCreateJobObject
00000096  7DE9073C  NtCreateJobSet
0000001A  7DE8FB40  NtCreateKey
00000097  7DE90754  NtCreateKeyTransacted
00000098  7DE9076C  NtCreateKeyedEvent
00000099  7DE90784  NtCreateMailslotFile
0000009A  7DE9079C  NtCreateMutant
0000009B  7DE907B4  NtCreateNamedPipeFile
0000009C  7DE907CC  NtCreatePagingFile
0000009D  7DE907E4  NtCreatePort
0000009E  7DE907FC  NtCreatePrivateNamespace
0000009F  7DE90814  NtCreateProcess
0000004A  7DE8FFEC  NtCreateProcessEx
000000A0  7DE9082C  NtCreateProfile
000000A1  7DE90844  NtCreateProfileEx
000000A2  7DE9085C  NtCreateResourceManager
00000047  7DE8FFA4  NtCreateSection
000000A3  7DE90874  NtCreateSemaphore
000000A4  7DE9088C  NtCreateSymbolicLinkObject
0000004B  7DE90004  NtCreateThread
000000A5  7DE908A4  NtCreateThreadEx
000000A6  7DE908BC  NtCreateTimer
000000A7  7DE908D4  NtCreateToken
000000A8  7DE908EC  NtCreateTransaction
000000A9  7DE90904  NtCreateTransactionManager
000000AA  7DE9091C  NtCreateUserProcess
000000AB  7DE90934  NtCreateWaitablePort
000000AC  7DE9094C  NtCreateWorkerFactory
000000AE  7DE90980  NtDebugContinue
000000B0  7DE909B4  NtDeleteBootEntry
000000B1  7DE909CC  NtDeleteDriverEntry
000000B2  7DE909E4  NtDeleteFile
000000B3  7DE909FC  NtDeleteKey
000000B4  7DE90A14  NtDeleteObjectAuditAlarm
000000B5  7DE90A2C  NtDeletePrivateNamespace
000000B6  7DE90A44  NtDeleteValueKey
000000B7  7DE90A5C  NtDisableLastKnownGood
000000B8  7DE90A74  NtDisplayString
000000B9  7DE90A8C  NtDrawText
00000039  7DE8FE44  NtDuplicateObject
0000003F  7DE8FED8  NtDuplicateToken
000000BA  7DE90AA4  NtEnableLastKnownGood
000000BB  7DE90ABC  NtEnumerateBootEntries
000000BC  7DE90AD4  NtEnumerateDriverEntries
0000002F  7DE8FD4C  NtEnumerateKey
000000BD  7DE90AEC  NtEnumerateSystemEnvironmentValuesEx
000000BE  7DE90B04  NtEnumerateTransactionObject
00000010  7DE8FA40  NtEnumerateValueKey
000000BF  7DE90B1C  NtExtendSection
000000C0  7DE90B34  NtFilterToken
00000048  7DE8FFBC  NtFlushBuffersFile
000000C1  7DE90B4C  NtFlushInstallUILanguage
000000C4  7DE90B9C  NtFlushProcessWriteBuffers
000000C5  7DE90BB4  NtFlushVirtualMemory
000000C7  7DE90BE8  NtFreeUserPhysicalPages
0000001B  7DE8FB58  NtFreeVirtualMemory
000000C8  7DE90C00  NtFreezeRegistry
000000C9  7DE90C18  NtFreezeTransactions
000000CA  7DE90C30  NtGetContextThread
000000CD  7DE90C80  NtGetMUIRegistryInfo
000000CE  7DE90C98  NtGetNextProcess
000000CF  7DE90CB0  NtGetNextThread
000000D0  7DE90CC8  NtGetNlsSectionPtr
000000D1  7DE90CE0  NtGetNotificationResourceManager
000000D2  7DE90CF8  NtGetPlugPlayEvent
000000D3  7DE90D10  NtGetWriteWatch
000000D5  7DE90D44  NtImpersonateThread
000000D6  7DE90D5C  NtInitializeNlsFiles
000000D7  7DE90D74  NtInitializeRegistry
000000DA  7DE90DC4  NtIsUILanguageComitted
000000DB  7DE90DDC  NtListenPort
000000DC  7DE90DF4  NtLoadDriver
000000DD  7DE90E0C  NtLoadKey
000000DE  7DE90E24  NtLoadKey2
000000DF  7DE90E3C  NtLoadKeyEx
000000E0  7DE90E54  NtLockFile
000000E3  7DE90EA4  NtLockVirtualMemory
000000E6  7DE90EF4  NtMapCMFModule
00000025  7DE8FC50  NtMapViewOfSection
000000E8  7DE90F28  NtModifyBootEntry
000000E9  7DE90F40  NtModifyDriverEntry
000000EA  7DE90F58  NtNotifyChangeDirectoryFile
000000EB  7DE90F70  NtNotifyChangeKey
000000EC  7DE90F88  NtNotifyChangeMultipleKeys
000000ED  7DE90FA0  NtNotifyChangeSession
00000055  7DE900FC  NtOpenDirectoryObject
000000EE  7DE90FB8  NtOpenEnlistment
0000003D  7DE8FEA8  NtOpenEvent
000000EF  7DE90FD0  NtOpenEventPair
00000030  7DE8FD64  NtOpenFile
000000F0  7DE90FE8  NtOpenIoCompletion
000000F1  7DE91000  NtOpenJobObject
0000000F  7DE8FA28  NtOpenKey
000000F2  7DE91018  NtOpenKeyEx
000000F3  7DE91030  NtOpenKeyTransacted
000000F4  7DE91048  NtOpenKeyTransactedEx
000000F5  7DE91060  NtOpenKeyedEvent
000000F6  7DE91078  NtOpenMutant
000000F7  7DE91090  NtOpenObjectAuditAlarm
000000F8  7DE910A8  NtOpenPrivateNamespace
00000023  7DE8FC20  NtOpenProcess
000000F9  7DE910C0  NtOpenProcessToken
0000002D  7DE8FD18  NtOpenProcessTokenEx
000000FA  7DE910D8  NtOpenResourceManager
00000034  7DE8FDC8  NtOpenSection
000000FB  7DE910F0  NtOpenSemaphore
000000FC  7DE91108  NtOpenSession
000000FD  7DE91120  NtOpenSymbolicLinkObject
000000FE  7DE91138  NtOpenThread
00000021  7DE8FBF0  NtOpenThreadToken
0000002C  7DE8FD00  NtOpenThreadTokenEx
000000FF  7DE91150  NtOpenTimer
00000100  7DE91168  NtOpenTransaction
00000101  7DE91180  NtOpenTransactionManager
00000102  7DE91198  NtPlugPlayControl
0000005C  7DE901AC  NtPowerInformation
00000103  7DE911B0  NtPrePrepareComplete
00000104  7DE911C8  NtPrePrepareEnlistment
00000105  7DE911E0  NtPrepareComplete
00000106  7DE911F8  NtPrepareEnlistment
00000108  7DE9122C  NtPrivilegeObjectAuditAlarm
00000109  7DE91244  NtPrivilegedServiceAuditAlarm
0000010A  7DE9125C  NtPropagationComplete
0000010B  7DE91274  NtPropagationFailed
0000004D  7DE90038  NtProtectVirtualMemory
0000003A  7DE8FE5C  NtQueryAttributesFile
0000010D  7DE912A8  NtQueryBootEntryOrder
0000010E  7DE912C0  NtQueryBootOptions
00000032  7DE8FD98  NtQueryDirectoryFile
00000110  7DE912F4  NtQueryDirectoryObject
00000111  7DE9130C  NtQueryDriverEntryOrder
00000112  7DE91324  NtQueryEaFile
00000053  7DE900CC  NtQueryEvent
00000113  7DE9133C  NtQueryFullAttributesFile
00000114  7DE91354  NtQueryInformationAtom
00000115  7DE9136C  NtQueryInformationEnlistment
0000000E  7DE8FA10  NtQueryInformationFile
00000116  7DE91384  NtQueryInformationJobObject
00000117  7DE9139C  NtQueryInformationPort
00000016  7DE8FAD8  NtQueryInformationProcess
00000118  7DE913B4  NtQueryInformationResourceManager
00000022  7DE8FC08  NtQueryInformationThread
0000001E  7DE8FBA8  NtQueryInformationToken
00000119  7DE913CC  NtQueryInformationTransaction
0000011A  7DE913E4  NtQueryInformationTransactionManager
0000011B  7DE913FC  NtQueryInformationWorkerFactory
0000011E  7DE9144C  NtQueryIoCompletion
00000013  7DE8FA90  NtQueryKey
0000011F  7DE91464  NtQueryLicenseValue
00000120  7DE9147C  NtQueryMultipleValueKey
00000121  7DE91494  NtQueryMutant
0000000D  7DE8F9F8  NtQueryObject
00000122  7DE914AC  NtQueryOpenSubKeys
00000123  7DE914C4  NtQueryOpenSubKeysEx
00000125  7DE914F8  NtQueryQuotaInformationFile
0000004E  7DE90050  NtQuerySection
00000126  7DE91510  NtQuerySecurityAttributesToken
00000127  7DE91528  NtQuerySecurityObject
00000128  7DE91540  NtQuerySemaphore
00000129  7DE91558  NtQuerySymbolicLinkObject
0000012A  7DE91570  NtQuerySystemEnvironmentValue
0000012B  7DE91588  NtQuerySystemEnvironmentValueEx
00000033  7DE8FDB0  NtQuerySystemInformation
0000012C  7DE915A0  NtQuerySystemInformationEx
00000035  7DE8FDE0  NtQueryTimer
00000014  7DE8FAA8  NtQueryValueKey
00000020  7DE8FBD8  NtQueryVirtualMemory
00000046  7DE8FF8C  NtQueryVolumeInformationFile
00000042  7DE8FF24  NtQueueApcThread
0000012E  7DE915D4  NtQueueApcThreadEx
0000012F  7DE915EC  NtRaiseException
00000130  7DE91604  NtRaiseHardError
00000131  7DE9161C  NtReadOnlyEnlistment
00000051  7DE9009C  NtReadRequestData
0000003C  7DE8FE90  NtReadVirtualMemory
00000132  7DE91634  NtRecoverEnlistment
00000133  7DE9164C  NtRecoverResourceManager
00000134  7DE91664  NtRecoverTransactionManager
00000135  7DE9167C  NtRegisterProtocolAddressInformation
00000138  7DE916CC  NtReleaseWorkerFactoryWorker
00000139  7DE916E4  NtRemoveIoCompletionEx
0000013B  7DE91718  NtRenameKey
0000013C  7DE91730  NtRenameTransactionManager
0000013D  7DE91748  NtReplaceKey
0000013E  7DE91760  NtReplacePartitionUnit
00000009  7DE8F994  NtReplyPort
00000008  7DE8F97C  NtReplyWaitReceivePort
00000028  7DE8FC98  NtReplyWaitReceivePortEx
0000013F  7DE91778  NtReplyWaitReplyPort
00000140  7DE91790  NtRequestPort
0000001F  7DE8FBC0  NtRequestWaitReplyPort
00000143  7DE917E0  NtRestoreKey
00000145  7DE91814  NtRollbackComplete
00000146  7DE9182C  NtRollbackEnlistment
00000147  7DE91844  NtRollbackTransaction
00000148  7DE9185C  NtRollforwardTransactionManager
00000149  7DE91874  NtSaveKey
0000014A  7DE9188C  NtSaveKeyEx
0000014C  7DE918C0  NtSecureConnectPort
0000014D  7DE918D8  NtSerializeBoot
0000014E  7DE918F0  NtSetBootEntryOrder
0000014F  7DE91908  NtSetBootOptions
00000150  7DE91920  NtSetContextThread
00000155  7DE919A8  NtSetDriverEntryOrder
00000156  7DE919C0  NtSetEaFile
00000159  7DE91A10  NtSetInformationDebugObject
0000015A  7DE91A28  NtSetInformationEnlistment
00000024  7DE8FC38  NtSetInformationFile
0000015B  7DE91A40  NtSetInformationJobObject
0000015C  7DE91A58  NtSetInformationKey
00000059  7DE90164  NtSetInformationObject
00000019  7DE8FB28  NtSetInformationProcess
0000015D  7DE91A70  NtSetInformationResourceManager
0000000A  7DE8F9AC  NtSetInformationThread
0000015E  7DE91A88  NtSetInformationToken
0000015F  7DE91AA0  NtSetInformationTransaction
00000160  7DE91AB8  NtSetInformationTransactionManager
00000161  7DE91AD0  NtSetInformationWorkerFactory
00000163  7DE91B04  NtSetIoCompletion
00000164  7DE91B1C  NtSetIoCompletionEx
00000165  7DE91B34  NtSetLdtEntries
00000168  7DE91B84  NtSetQuotaInformationFile
00000169  7DE91B9C  NtSetSecurityObject
0000016A  7DE91BB4  NtSetSystemEnvironmentValue
0000016B  7DE91BCC  NtSetSystemEnvironmentValueEx
0000016C  7DE91BE4  NtSetSystemInformation
0000016D  7DE91BFC  NtSetSystemPowerState
0000005F  7DE901F8  NtSetTimer
00000170  7DE91C4C  NtSetTimerEx
0000005D  7DE901C4  NtSetValueKey
00000173  7DE91C9C  NtSetVolumeInformationFile
00000175  7DE91CD0  NtShutdownWorkerFactory
00000177  7DE91D04  NtSinglePhaseReject
0000017C  7DE91D8C  NtSystemDebugControl
00000029  7DE8FCB0  NtTerminateProcess
00000050  7DE90084  NtTerminateThread
0000017F  7DE91DDC  NtThawRegistry
00000180  7DE91DF4  NtThawTransactions
00000181  7DE91E0C  NtTraceControl
0000005B  7DE90194  NtTraceEvent
00000183  7DE91E40  NtUmsThreadYield
00000184  7DE91E58  NtUnloadDriver
00000185  7DE91E70  NtUnloadKey
00000186  7DE91E88  NtUnloadKey2
00000187  7DE91EA0  NtUnloadKeyEx
00000188  7DE91EB8  NtUnlockFile
00000189  7DE91ED0  NtUnlockVirtualMemory
00000027  7DE8FC80  NtUnmapViewOfSection
0000018A  7DE91EE8  NtVdmControl
0000018B  7DE91F00  NtWaitForDebugEvent
0000018D  7DE91F34  NtWaitForWorkViaWorkerFactory
00000190  7DE91F84  NtWorkerFactoryWorkerReady
000001A3  7DE9214C  NtWow64CallFunction64
00000194  7DE91FE4  NtWow64CsrAllocateCaptureBuffer
00000196  7DE92014  NtWow64CsrAllocateMessagePointer
00000197  7DE9202C  NtWow64CsrCaptureMessageBuffer
00000198  7DE92044  NtWow64CsrCaptureMessageString
00000193  7DE91FCC  NtWow64CsrClientCallServer
00000191  7DE91F9C  NtWow64CsrClientConnectToServer
00000195  7DE91FFC  NtWow64CsrFreeCaptureBuffer
00000199  7DE9205C  NtWow64CsrGetProcessId
00000192  7DE91FB4  NtWow64CsrIdentifyAlertableThread
0000019A  7DE92074  NtWow64CsrVerifyRegion
0000019B  7DE9208C  NtWow64DebuggerCall
0000019C  7DE920A4  NtWow64GetCurrentProcessorNumberEx
0000019D  7DE920BC  NtWow64GetNativeSystemInformation
0000019E  7DE920D4  NtWow64InterlockedPopEntrySList
0000019F  7DE920EC  NtWow64QueryInformationProcess64
000001A2  7DE92134  NtWow64QueryVirtualMemory64
000001A0  7DE92104  NtWow64ReadVirtualMemory64
000001A1  7DE9211C  NtWow64WriteVirtualMemory64
00000054  7DE900E4  NtWriteRequestData
00000037  7DE8FE14  NtWriteVirtualMemory
0000019D  7DE920BC  RtlGetNativeSystemInformation
00000060  7DE90210  ZwAcceptConnectPort
00000061  7DE90228  ZwAccessCheck
00000026  7DE8FC68  ZwAccessCheckAndAuditAlarm
00000062  7DE90240  ZwAccessCheckByType
00000056  7DE90114  ZwAccessCheckByTypeAndAuditAlarm
00000063  7DE90258  ZwAccessCheckByTypeResultList
00000064  7DE90270  ZwAccessCheckByTypeResultListAndAuditAlarm
00000065  7DE90288  ZwAccessCheckByTypeResultListAndAuditAlarmByHandle
00000066  7DE902A0  ZwAddBootEntry
00000067  7DE902B8  ZwAddDriverEntry
00000068  7DE902D0  ZwAdjustGroupsToken
0000003E  7DE8FEC0  ZwAdjustPrivilegesToken
0000006C  7DE9033C  ZwAllocateReserveObject
0000006D  7DE90354  ZwAllocateUserPhysicalPages
00000015  7DE8FAC0  ZwAllocateVirtualMemory
0000006F  7DE90388  ZwAlpcAcceptConnectPort
00000070  7DE903A0  ZwAlpcCancelMessage
00000071  7DE903B8  ZwAlpcConnectPort
00000072  7DE903D0  ZwAlpcCreatePort
00000073  7DE903E8  ZwAlpcCreatePortSection
00000074  7DE90400  ZwAlpcCreateResourceReserve
00000075  7DE90418  ZwAlpcCreateSectionView
00000076  7DE90430  ZwAlpcCreateSecurityContext
00000077  7DE90448  ZwAlpcDeletePortSection
00000078  7DE90460  ZwAlpcDeleteResourceReserve
00000079  7DE90478  ZwAlpcDeleteSectionView
0000007A  7DE90490  ZwAlpcDeleteSecurityContext
0000007B  7DE904A8  ZwAlpcDisconnectPort
0000007C  7DE904C0  ZwAlpcImpersonateClientOfPort
0000007D  7DE904D8  ZwAlpcOpenSenderProcess
0000007E  7DE904F0  ZwAlpcOpenSenderThread
0000007F  7DE90508  ZwAlpcQueryInformation
00000080  7DE90520  ZwAlpcQueryInformationMessage
00000081  7DE90538  ZwAlpcRevokeSecurityContext
00000082  7DE90550  ZwAlpcSendWaitReceivePort
00000083  7DE90568  ZwAlpcSetInformation
00000049  7DE8FFD4  ZwApphelpCacheControl
00000002  7DE8F8D8  ZwCallbackReturn
0000005A  7DE9017C  ZwCancelIoFile
00000086  7DE905B8  ZwCancelIoFileEx
00000087  7DE905D0  ZwCancelSynchronousIoFile
0000000C  7DE8F9E0  ZwClose
00000038  7DE8FE2C  ZwCloseObjectAuditAlarm
00000088  7DE905E8  ZwCommitComplete
00000089  7DE90600  ZwCommitEnlistment
0000008A  7DE90618  ZwCommitTransaction
0000008B  7DE90630  ZwCompactKeys
0000008C  7DE90648  ZwCompareTokens
0000008D  7DE90660  ZwCompleteConnectPort
0000008F  7DE90694  ZwConnectPort
00000040  7DE8FEF0  ZwContinue
00000090  7DE906AC  ZwCreateDebugObject
00000091  7DE906C4  ZwCreateDirectoryObject
00000092  7DE906DC  ZwCreateEnlistment
00000045  7DE8FF74  ZwCreateEvent
00000093  7DE906F4  ZwCreateEventPair
00000052  7DE900B4  ZwCreateFile
00000094  7DE9070C  ZwCreateIoCompletion
00000095  7DE90724  ZwCreateJobObject
00000096  7DE9073C  ZwCreateJobSet
0000001A  7DE8FB40  ZwCreateKey
00000097  7DE90754  ZwCreateKeyTransacted
00000098  7DE9076C  ZwCreateKeyedEvent
00000099  7DE90784  ZwCreateMailslotFile
0000009A  7DE9079C  ZwCreateMutant
0000009B  7DE907B4  ZwCreateNamedPipeFile
0000009C  7DE907CC  ZwCreatePagingFile
0000009D  7DE907E4  ZwCreatePort
0000009E  7DE907FC  ZwCreatePrivateNamespace
0000009F  7DE90814  ZwCreateProcess
0000004A  7DE8FFEC  ZwCreateProcessEx
000000A0  7DE9082C  ZwCreateProfile
000000A1  7DE90844  ZwCreateProfileEx
000000A2  7DE9085C  ZwCreateResourceManager
00000047  7DE8FFA4  ZwCreateSection
000000A3  7DE90874  ZwCreateSemaphore
000000A4  7DE9088C  ZwCreateSymbolicLinkObject
0000004B  7DE90004  ZwCreateThread
000000A5  7DE908A4  ZwCreateThreadEx
000000A6  7DE908BC  ZwCreateTimer
000000A7  7DE908D4  ZwCreateToken
000000A8  7DE908EC  ZwCreateTransaction
000000A9  7DE90904  ZwCreateTransactionManager
000000AA  7DE9091C  ZwCreateUserProcess
000000AB  7DE90934  ZwCreateWaitablePort
000000AC  7DE9094C  ZwCreateWorkerFactory
000000AE  7DE90980  ZwDebugContinue
000000B0  7DE909B4  ZwDeleteBootEntry
000000B1  7DE909CC  ZwDeleteDriverEntry
000000B2  7DE909E4  ZwDeleteFile
000000B3  7DE909FC  ZwDeleteKey
000000B4  7DE90A14  ZwDeleteObjectAuditAlarm
000000B5  7DE90A2C  ZwDeletePrivateNamespace
000000B6  7DE90A44  ZwDeleteValueKey
000000B7  7DE90A5C  ZwDisableLastKnownGood
000000B8  7DE90A74  ZwDisplayString
000000B9  7DE90A8C  ZwDrawText
00000039  7DE8FE44  ZwDuplicateObject
0000003F  7DE8FED8  ZwDuplicateToken
000000BA  7DE90AA4  ZwEnableLastKnownGood
000000BB  7DE90ABC  ZwEnumerateBootEntries
000000BC  7DE90AD4  ZwEnumerateDriverEntries
0000002F  7DE8FD4C  ZwEnumerateKey
000000BD  7DE90AEC  ZwEnumerateSystemEnvironmentValuesEx
000000BE  7DE90B04  ZwEnumerateTransactionObject
00000010  7DE8FA40  ZwEnumerateValueKey
000000BF  7DE90B1C  ZwExtendSection
000000C0  7DE90B34  ZwFilterToken
00000048  7DE8FFBC  ZwFlushBuffersFile
000000C1  7DE90B4C  ZwFlushInstallUILanguage
000000C4  7DE90B9C  ZwFlushProcessWriteBuffers
000000C5  7DE90BB4  ZwFlushVirtualMemory
000000C7  7DE90BE8  ZwFreeUserPhysicalPages
0000001B  7DE8FB58  ZwFreeVirtualMemory
000000C8  7DE90C00  ZwFreezeRegistry
000000C9  7DE90C18  ZwFreezeTransactions
000000CA  7DE90C30  ZwGetContextThread
000000CD  7DE90C80  ZwGetMUIRegistryInfo
000000CE  7DE90C98  ZwGetNextProcess
000000CF  7DE90CB0  ZwGetNextThread
000000D0  7DE90CC8  ZwGetNlsSectionPtr
000000D1  7DE90CE0  ZwGetNotificationResourceManager
000000D2  7DE90CF8  ZwGetPlugPlayEvent
000000D3  7DE90D10  ZwGetWriteWatch
000000D5  7DE90D44  ZwImpersonateThread
000000D6  7DE90D5C  ZwInitializeNlsFiles
000000D7  7DE90D74  ZwInitializeRegistry
000000DA  7DE90DC4  ZwIsUILanguageComitted
000000DB  7DE90DDC  ZwListenPort
000000DC  7DE90DF4  ZwLoadDriver
000000DD  7DE90E0C  ZwLoadKey
000000DE  7DE90E24  ZwLoadKey2
000000DF  7DE90E3C  ZwLoadKeyEx
000000E0  7DE90E54  ZwLockFile
000000E3  7DE90EA4  ZwLockVirtualMemory
000000E6  7DE90EF4  ZwMapCMFModule
00000025  7DE8FC50  ZwMapViewOfSection
000000E8  7DE90F28  ZwModifyBootEntry
000000E9  7DE90F40  ZwModifyDriverEntry
000000EA  7DE90F58  ZwNotifyChangeDirectoryFile
000000EB  7DE90F70  ZwNotifyChangeKey
000000EC  7DE90F88  ZwNotifyChangeMultipleKeys
000000ED  7DE90FA0  ZwNotifyChangeSession
00000055  7DE900FC  ZwOpenDirectoryObject
000000EE  7DE90FB8  ZwOpenEnlistment
0000003D  7DE8FEA8  ZwOpenEvent
000000EF  7DE90FD0  ZwOpenEventPair
00000030  7DE8FD64  ZwOpenFile
000000F0  7DE90FE8  ZwOpenIoCompletion
000000F1  7DE91000  ZwOpenJobObject
0000000F  7DE8FA28  ZwOpenKey
000000F2  7DE91018  ZwOpenKeyEx
000000F3  7DE91030  ZwOpenKeyTransacted
000000F4  7DE91048  ZwOpenKeyTransactedEx
000000F5  7DE91060  ZwOpenKeyedEvent
000000F6  7DE91078  ZwOpenMutant
000000F7  7DE91090  ZwOpenObjectAuditAlarm
000000F8  7DE910A8  ZwOpenPrivateNamespace
00000023  7DE8FC20  ZwOpenProcess
000000F9  7DE910C0  ZwOpenProcessToken
0000002D  7DE8FD18  ZwOpenProcessTokenEx
000000FA  7DE910D8  ZwOpenResourceManager
00000034  7DE8FDC8  ZwOpenSection
000000FB  7DE910F0  ZwOpenSemaphore
000000FC  7DE91108  ZwOpenSession
000000FD  7DE91120  ZwOpenSymbolicLinkObject
000000FE  7DE91138  ZwOpenThread
00000021  7DE8FBF0  ZwOpenThreadToken
0000002C  7DE8FD00  ZwOpenThreadTokenEx
000000FF  7DE91150  ZwOpenTimer
00000100  7DE91168  ZwOpenTransaction
00000101  7DE91180  ZwOpenTransactionManager
00000102  7DE91198  ZwPlugPlayControl
0000005C  7DE901AC  ZwPowerInformation
00000103  7DE911B0  ZwPrePrepareComplete
00000104  7DE911C8  ZwPrePrepareEnlistment
00000105  7DE911E0  ZwPrepareComplete
00000106  7DE911F8  ZwPrepareEnlistment
00000108  7DE9122C  ZwPrivilegeObjectAuditAlarm
00000109  7DE91244  ZwPrivilegedServiceAuditAlarm
0000010A  7DE9125C  ZwPropagationComplete
0000010B  7DE91274  ZwPropagationFailed
0000004D  7DE90038  ZwProtectVirtualMemory
0000003A  7DE8FE5C  ZwQueryAttributesFile
0000010D  7DE912A8  ZwQueryBootEntryOrder
0000010E  7DE912C0  ZwQueryBootOptions
00000032  7DE8FD98  ZwQueryDirectoryFile
00000110  7DE912F4  ZwQueryDirectoryObject
00000111  7DE9130C  ZwQueryDriverEntryOrder
00000112  7DE91324  ZwQueryEaFile
00000053  7DE900CC  ZwQueryEvent
00000113  7DE9133C  ZwQueryFullAttributesFile
00000114  7DE91354  ZwQueryInformationAtom
00000115  7DE9136C  ZwQueryInformationEnlistment
0000000E  7DE8FA10  ZwQueryInformationFile
00000116  7DE91384  ZwQueryInformationJobObject
00000117  7DE9139C  ZwQueryInformationPort
00000016  7DE8FAD8  ZwQueryInformationProcess
00000118  7DE913B4  ZwQueryInformationResourceManager
00000022  7DE8FC08  ZwQueryInformationThread
0000001E  7DE8FBA8  ZwQueryInformationToken
00000119  7DE913CC  ZwQueryInformationTransaction
0000011A  7DE913E4  ZwQueryInformationTransactionManager
0000011B  7DE913FC  ZwQueryInformationWorkerFactory
0000011E  7DE9144C  ZwQueryIoCompletion
00000013  7DE8FA90  ZwQueryKey
0000011F  7DE91464  ZwQueryLicenseValue
00000120  7DE9147C  ZwQueryMultipleValueKey
00000121  7DE91494  ZwQueryMutant
0000000D  7DE8F9F8  ZwQueryObject
00000122  7DE914AC  ZwQueryOpenSubKeys
00000123  7DE914C4  ZwQueryOpenSubKeysEx
00000125  7DE914F8  ZwQueryQuotaInformationFile
0000004E  7DE90050  ZwQuerySection
00000126  7DE91510  ZwQuerySecurityAttributesToken
00000127  7DE91528  ZwQuerySecurityObject
00000128  7DE91540  ZwQuerySemaphore
00000129  7DE91558  ZwQuerySymbolicLinkObject
0000012A  7DE91570  ZwQuerySystemEnvironmentValue
0000012B  7DE91588  ZwQuerySystemEnvironmentValueEx
00000033  7DE8FDB0  ZwQuerySystemInformation
0000012C  7DE915A0  ZwQuerySystemInformationEx
00000035  7DE8FDE0  ZwQueryTimer
00000014  7DE8FAA8  ZwQueryValueKey
00000020  7DE8FBD8  ZwQueryVirtualMemory
00000046  7DE8FF8C  ZwQueryVolumeInformationFile
00000042  7DE8FF24  ZwQueueApcThread
0000012E  7DE915D4  ZwQueueApcThreadEx
0000012F  7DE915EC  ZwRaiseException
00000130  7DE91604  ZwRaiseHardError
00000131  7DE9161C  ZwReadOnlyEnlistment
00000051  7DE9009C  ZwReadRequestData
0000003C  7DE8FE90  ZwReadVirtualMemory
00000132  7DE91634  ZwRecoverEnlistment
00000133  7DE9164C  ZwRecoverResourceManager
00000134  7DE91664  ZwRecoverTransactionManager
00000135  7DE9167C  ZwRegisterProtocolAddressInformation
00000138  7DE916CC  ZwReleaseWorkerFactoryWorker
00000139  7DE916E4  ZwRemoveIoCompletionEx
0000013B  7DE91718  ZwRenameKey
0000013C  7DE91730  ZwRenameTransactionManager
0000013D  7DE91748  ZwReplaceKey
0000013E  7DE91760  ZwReplacePartitionUnit
00000009  7DE8F994  ZwReplyPort
00000008  7DE8F97C  ZwReplyWaitReceivePort
00000028  7DE8FC98  ZwReplyWaitReceivePortEx
0000013F  7DE91778  ZwReplyWaitReplyPort
00000140  7DE91790  ZwRequestPort
0000001F  7DE8FBC0  ZwRequestWaitReplyPort
00000143  7DE917E0  ZwRestoreKey
00000145  7DE91814  ZwRollbackComplete
00000146  7DE9182C  ZwRollbackEnlistment
00000147  7DE91844  ZwRollbackTransaction
00000148  7DE9185C  ZwRollforwardTransactionManager
00000149  7DE91874  ZwSaveKey
0000014A  7DE9188C  ZwSaveKeyEx
0000014C  7DE918C0  ZwSecureConnectPort
0000014D  7DE918D8  ZwSerializeBoot
0000014E  7DE918F0  ZwSetBootEntryOrder
0000014F  7DE91908  ZwSetBootOptions
00000150  7DE91920  ZwSetContextThread
00000155  7DE919A8  ZwSetDriverEntryOrder
00000156  7DE919C0  ZwSetEaFile
00000159  7DE91A10  ZwSetInformationDebugObject
0000015A  7DE91A28  ZwSetInformationEnlistment
00000024  7DE8FC38  ZwSetInformationFile
0000015B  7DE91A40  ZwSetInformationJobObject
0000015C  7DE91A58  ZwSetInformationKey
00000059  7DE90164  ZwSetInformationObject
00000019  7DE8FB28  ZwSetInformationProcess
0000015D  7DE91A70  ZwSetInformationResourceManager
0000000A  7DE8F9AC  ZwSetInformationThread
0000015E  7DE91A88  ZwSetInformationToken
0000015F  7DE91AA0  ZwSetInformationTransaction
00000160  7DE91AB8  ZwSetInformationTransactionManager
00000161  7DE91AD0  ZwSetInformationWorkerFactory
00000163  7DE91B04  ZwSetIoCompletion
00000164  7DE91B1C  ZwSetIoCompletionEx
00000165  7DE91B34  ZwSetLdtEntries
00000168  7DE91B84  ZwSetQuotaInformationFile
00000169  7DE91B9C  ZwSetSecurityObject
0000016A  7DE91BB4  ZwSetSystemEnvironmentValue
0000016B  7DE91BCC  ZwSetSystemEnvironmentValueEx
0000016C  7DE91BE4  ZwSetSystemInformation
0000016D  7DE91BFC  ZwSetSystemPowerState
0000005F  7DE901F8  ZwSetTimer
00000170  7DE91C4C  ZwSetTimerEx
0000005D  7DE901C4  ZwSetValueKey
00000173  7DE91C9C  ZwSetVolumeInformationFile
00000175  7DE91CD0  ZwShutdownWorkerFactory
00000177  7DE91D04  ZwSinglePhaseReject
0000017C  7DE91D8C  ZwSystemDebugControl
00000029  7DE8FCB0  ZwTerminateProcess
00000050  7DE90084  ZwTerminateThread
0000017F  7DE91DDC  ZwThawRegistry
00000180  7DE91DF4  ZwThawTransactions
00000181  7DE91E0C  ZwTraceControl
0000005B  7DE90194  ZwTraceEvent
00000183  7DE91E40  ZwUmsThreadYield
00000184  7DE91E58  ZwUnloadDriver
00000185  7DE91E70  ZwUnloadKey
00000186  7DE91E88  ZwUnloadKey2
00000187  7DE91EA0  ZwUnloadKeyEx
00000188  7DE91EB8  ZwUnlockFile
00000189  7DE91ED0  ZwUnlockVirtualMemory
00000027  7DE8FC80  ZwUnmapViewOfSection
0000018A  7DE91EE8  ZwVdmControl
0000018B  7DE91F00  ZwWaitForDebugEvent
0000018D  7DE91F34  ZwWaitForWorkViaWorkerFactory
00000190  7DE91F84  ZwWorkerFactoryWorkerReady
000001A3  7DE9214C  ZwWow64CallFunction64
00000194  7DE91FE4  ZwWow64CsrAllocateCaptureBuffer
00000196  7DE92014  ZwWow64CsrAllocateMessagePointer
00000197  7DE9202C  ZwWow64CsrCaptureMessageBuffer
00000198  7DE92044  ZwWow64CsrCaptureMessageString
00000193  7DE91FCC  ZwWow64CsrClientCallServer
00000191  7DE91F9C  ZwWow64CsrClientConnectToServer
00000195  7DE91FFC  ZwWow64CsrFreeCaptureBuffer
00000199  7DE9205C  ZwWow64CsrGetProcessId
00000192  7DE91FB4  ZwWow64CsrIdentifyAlertableThread
0000019A  7DE92074  ZwWow64CsrVerifyRegion
0000019B  7DE9208C  ZwWow64DebuggerCall
0000019C  7DE920A4  ZwWow64GetCurrentProcessorNumberEx
0000019D  7DE920BC  ZwWow64GetNativeSystemInformation
0000019E  7DE920D4  ZwWow64InterlockedPopEntrySList
0000019F  7DE920EC  ZwWow64QueryInformationProcess64
000001A2  7DE92134  ZwWow64QueryVirtualMemory64
000001A0  7DE92104  ZwWow64ReadVirtualMemory64
000001A1  7DE9211C  ZwWow64WriteVirtualMemory64
00000054  7DE900E4  ZwWriteRequestData
00000037  7DE8FE14  ZwWriteVirtualMemory

Enjoy :)

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Ssd отказано в доступе windows 10
  • Исчез блютуз на ноутбуке windows 11
  • Аренда сервера windows server 2003
  • Базовый пакет для сертифицированной версии ос microsoft windows server standard 2016
  • Какой windows больше подходит для игр