Вопрос

В последнее время я использую много языка ассемблера в операционных системах * 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?По крайней мере, при программировании драйвера нужно это знать.верно?

Итак, что происходит с так называемым 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 где as Native API состоит из множества функций, которые не начинаются с букв Nt.
  2. System Call of windows являются подмножеством Native API.Системные вызовы - это всего лишь часть собственного API.

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

Редактировать:

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

Это было полезно?

Решение

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

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

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

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

Редактировать:

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

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

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

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

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

Другие советы

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

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

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

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

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

ОФИЦИАЛЬНОЕ соглашение о вызовах в 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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top