Подтвердить что ты не робот

Системные вызовы в windows & Native API?

Недавно я использовал много языков ассемблера в операционных системах * 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

Native API: http://undocumented.ntinternals.net/aindex.html

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

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

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

EDIT:

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

4b9b3361

Ответ 1

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

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

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

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

РЕДАКТИРОВАТЬ:

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

EDIT2:

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

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

Люди уже сделали часть обратного инжиниринга: см. Https://j00ru.vexillium.org/syscalls/nt/64/ для таблицы номеров системных вызовов для каждого ядра Windows. (Обратите внимание, что более поздние строки меняются даже между версиями Windows 10.) Опять же, это плохая идея, кроме экспериментов только для личного использования на вашей собственной машине, чтобы узнать больше об asm и/или внутренностях Windows. Не вставляйте системные вызовы в код, который вы распространяете среди других.

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

Я был заинтересован в выполнении вызова Windows API в сборке без импорта (как учебное упражнение), поэтому я написал следующую сборку FASM, чтобы сделать то, что делает NtDll! NtCreateFile. Это грубая демонстрация на моей 64-битной версии Windows (Win10 1803 Version 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
);

Ответ 5

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

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

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