Системные вызовы в Windows & Native API? - PullRequest
23 голосов
/ 22 марта 2010

В последнее время я много использую ассемблер в операционных системах * NIX. Мне было интересно, о домене Windows.


Соглашение о вызовах в Linux:

mov $SYS_Call_NUM, %eax
mov $param1 , %ebx
mov $param2 , %ecx
int $0x80

Вот и все. Вот как мы должны сделать системный вызов в Linux.

Ссылка на все системные вызовы в Linux:

Относительно того, какие $ SYS_Call_NUM и какие параметры мы можем использовать, эта ссылка: http://docs.cs.up.ac.za/programming/asm/derick_tut/syscalls.html

ОФИЦИАЛЬНЫЙ Ссылка: http://kernel.org/doc/man-pages/online/dir_section_2.html


Соглашение о вызовах в Windows:

???

Ссылка на все системные вызовы в Windows:

* * ??? тысяча тридцать один

Неофициально: http://www.metasploit.com/users/opcode/syscalls.html, но как мне использовать их в сборке, если я не знаю соглашение о вызовах.

ОФИЦИАЛЬНО: ???

  • Если вы говорите, они не задокументировали это. Тогда как можно написать libc для Windows, не зная системных вызовов? Как можно заниматься программированием на Windows Assembly? По крайней мере, в программировании драйвера нужно знать это. право?

Теперь, что случилось с так называемым Native API? Являются ли Native API & System calls for windows оба разными терминами, относящимися к одной и той же вещи? Для подтверждения я сравнил их из двух неофициальных источников

Системные вызовы: http://www.metasploit.com/users/opcode/syscalls.html

Собственный API: http://undocumented.ntinternals.net/aindex.html

Мои наблюдения:

  1. Все системные вызовы начинаются с букв Nt, где Native API состоит из множества функций, которые не начинаются с букв Nt.
  2. System Call of windows являются подмножеством Native API. Системные вызовы являются лишь частью Native API.

Может ли кто-нибудь подтвердить это и объяснить.

EDIT:

Был другой ответ. Это был второй ответ. Мне действительно понравилось это, но я не знаю, почему ответчик удалил это. Я прошу его опубликовать свой ответ.

Ответы [ 5 ]

24 голосов
/ 22 марта 2010

Если вы занимаетесь программированием на ассемблере под Windows, вы не выполняете системные вызовы вручную. Для этого вы используете NTDLL и собственный API.

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

Вам НИКОГДА не нужно вручную выполнять системный вызов, чтобы весь ваш вопрос был излишним.

Коды системных вызовов Linux не меняются, как и в Windows, поэтому вам нужно работать через дополнительный уровень абстракции (он же NTDLL).

EDIT:

Кроме того, даже если вы работаете на уровне сборки, у вас все еще есть полный доступ к Win32 API, нет никаких оснований использовать NT API для начала! Импорт, экспорт и т. Д. Все отлично работают в программах сборки.

EDIT2:

Если вы ДЕЙСТВИТЕЛЬНО хотите выполнять системные вызовы вручную, вам нужно будет отменить NTDLL для каждой соответствующей версии Windows, добавить определение версии (через PEB) и выполнить поиск по системному вызову для каждого вызова.

Однако это было бы глупо. NTDLL существует по причине.

8 голосов
/ 30 апреля 2010

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

Даже механизм, используемый для выполнения системных вызовов (который int или sysenter) не зафиксирован в камне и изменился в прошлом, и я думаю, что когда-то одна и та же версия окон использовала разные DLL, которые использовали разные механизмы ввода в зависимости от процессора в машине.

1 голос
/ 23 июля 2018

Мне было интересно сделать вызов Windows API в сборке без импорта (как учебное упражнение), поэтому я написал следующую сборку FASM, чтобы сделать то, что делает NtDll! NtCreateFile. Это грубая демонстрация на моей 64-битной версии Windows (Win10 1803 Версия 10.0.17134), и она вылетает после вызова, но возвращаемое значение системного вызова равно нулю, поэтому оно успешно. Все настраивается в соответствии с соглашением о вызовах Windows x64, затем номер системного вызова загружается в RAX, а затем выполняется инструкция сборки syscall для запуска вызова. В моем примере создается файл c: \ HelloWorldFile_FASM, поэтому его нужно запускать «как администратор».

format PE64 GUI 4.0


entry start


section '.text' code readable executable


 start: 
 ;puting the first four parameters into the right registers

                            mov rcx, _Handle
                            mov rdx, [_access_mask]
                            mov r8, objectAttributes
                            mov r9, ioStatusBlock

 ;I think we need 1 stack word of padding:

                            push 0x0DF0AD8B


 ;pushing the other params in reverse order:

                            push [_eaLength]
                            push [_eaBuffer]
                            push [_createOptions]
                            push [_createDisposition]
                            push [_shareAcceses]
                            push [_fileAttributes]
                            push [_pLargeInterger]

 ;adding the shadow space (4x8)

 ;                               push 0x0
 ;                               push 0x0
 ;                               push 0x0
 ;                               push 0x0

 ;pushing the 4 register params into the shadow space for ease of debugging

                            push r9
                            push r8
                            push rdx
                            push rcx

 ;now pushing the return address to the stack:

                            push endOfProgram

                            mov r10, rcx ;copied from ntdll!NtCreateFile, not sure of the reason for this
                            mov eax, 0x55
                            syscall

 endOfProgram:
                            retn




 section '.data' data readable writeable

 ;parameters------------------------------------------------------------------------------------------------

 _Handle                         dq      0x0
 _access_mask                    dq      0x00000000c0100080
 _pObjectAttributes              dq      objectAttributes        ; at 00402058
 _pIoStatusBlock                 dq           ioStatusBlock
 _pLargeInterger                 dq      0x0
 _fileAttributes                 dq      0x0000000000000080
 _shareAcceses                   dq      0x0000000000000002
 _createDisposition              dq      0x0000000000000005
 _createOptions                  dq      0x0000000000000060
 _eaBuffer                       dq      0x0000000000000000       ; "optional" param
 _eaLength                       dq      0x0000000000000000

 ;----------------------------------------------------------------------------------------------------------


                            align   16
 objectAttributes:
 _oalength                       dq      0x30
 _rootDirectory                  dq      0x0
 _objectName                     dq           unicodeString
 _attributes                     dq      0x40
 _pSecurityDescriptor            dq      0x0
 _pSecurityQualityOfService      dq      securityQualityOfService


 unicodeString:
 _unicodeStringLength            dw      0x34
 _unicodeStringMaxumiumLength    dw      0x34, 0x0, 0x0
 _pUnicodeStringBuffer           dq      _unicodeStringBuffer


 _unicodeStringBuffer            du      '\??\c:\HelloWorldFile_FASM'       ; may need to "run as adinistrator" for the file create to work.



 ioStatusBlock:
 _status_pointer                 dq      0x0
 _information                    dq      0x0


 securityQualityOfService:
 _sqlength                       dd      0xC
 _impersonationLevel             dd      0x2
 _contextTrackingMode            db      0x1
 _effectiveOnly                  db      0x1, 0x0, 0x0

Я использовал документацию для Ntdll! NtCreateFile, а также отладчик ядра для просмотра и копирования большого количества параметров.

__kernel_entry NTSTATUS NtCreateFile(
  OUT PHANDLE                      FileHandle,
  IN ACCESS_MASK                   DesiredAccess,
  IN POBJECT_ATTRIBUTES            ObjectAttributes,
  OUT PIO_STATUS_BLOCK             IoStatusBlock,
  IN PLARGE_INTEGER AllocationSize OPTIONAL,
  IN ULONG                         FileAttributes,
  IN ULONG                         ShareAccess,
  IN ULONG                         CreateDisposition,
  IN ULONG                         CreateOptions,
  IN PVOID EaBuffer                OPTIONAL,
  IN ULONG                         EaLength
);
1 голос
/ 22 марта 2010

Системные вызовы Windows выполняются путем вызова системных системных библиотек, таких как kernel32.dll или gdi32.dll, что выполняется обычными вызовами подпрограмм. Механизмы захвата в привилегированный уровень ОС недокументированы, но это нормально, потому что такие библиотеки как kernel32.dll делают это за вас.

И под системными вызовами я имею в виду документированные точки входа Windows API, такие как CreateProcess() или GetWindowText(). Драйверы устройств обычно используют API, отличный от Windows DDK.

0 голосов
/ 23 марта 2010

ОФИЦИАЛЬНЫЙ Соглашение о вызовах в Windows: http://msdn.microsoft.com/en-us/library/7kcdt6fy.aspx

(надеюсь, что эта ссылка сохранится в будущем; если нет, просто поищите "x64 Software Conventions" в MSDN).

Соглашение о вызове функции отличается в Linux и Windows x86_64. В обоих ABI параметры предпочтительно передаются через регистры, но используемые регистры различаются. Более подробную информацию о Linux ABI можно найти по адресу http://www.x86 -64.org / Documentation / abi.pdf

...