Где я могу найти, какие данные передавать функциям Windows API

Насколько я понимаю, лучший способ сделать что-то на ассемблере x86-64 - это не программировать что-то самостоятельно. Вместо этого попросите Windows сделать это за вас. Например, открыть новую консоль или напечатать текст в окне консоли. Но вы не можете вызывать системные вызовы Windows напрямую, так как они могут быть изменены по щелчку пальцев Microsoft. Итак, вы вызываете Windows API через call-команды.

Итак, я хочу иметь возможность программировать полные приложения в сборке x86-64 в Windows 10, но мне трудно найти информацию о Windows API. В частности, какую информацию/данные/числа передавать в RCX, RDX, R8 и R9 перед вызовом функции Windows API? Например, программа Hello World, которую я нашел где-то в Интернете, использует как «GetStdHandle», так и «WriteConsoleA». Я понимаю, что они делают, но я не знаю, что означают все числа и манипулирование регистрами или как это влияет на Windows API. Вот код:

extern GetStdHandle
extern WriteConsoleA

section .data
    msg: db "HelloWorld"
    msglen: equ $-msg

section .bss

section .text
start:

    mov ECX, -11
    call GetStdHandle

    mov RCX, RAX
    mov RDX, msg
    mov R8, msglen
    lea R9, [RSP-16]
    call WriteConsoleA

    mov EAX, 0

    ret

Это было скомпилировано с помощью NASM и связано с Golink. Вот make-файл:

{NasmPath} -f win64 HelloWorld.asm
{GoLinkPath} HelloWorld.obj /console kernel32.dll

Для пояснения: я не запускал {NasmPath} или {GoLinkPath} через консоль, я просто отредактировал его, потому что в фактическом пути есть мое имя.

TLDR: где я могу найти информацию о том, какие данные следует передавать через регистры RCX, RDX, R8 и R9 в функции Windows API?

Первое, что вам нужно понять, это соглашение о вызовах Win64. Это говорит о том, какие регистры (или стек) используются для каких параметров. Вы можете найти информацию о соглашении о вызовах Win64 здесь: learn.microsoft.com/en-us/cpp/build/… здесь: en.wikipedia.org/wiki/… . База не заключается в том, что вы просто находите, что API нужно передать для каждого параметра, и кодируете это в соответствии с соглашением о вызовах.

Michael Petch 25.10.2022 05:58

Каждый API, описанный для C, можно найти здесь. Например GetStdHandle: learn.microsoft.com/en-us/windows/console/console-functions . Вы можете искать многие другие вызовы API там.

Michael Petch 25.10.2022 05:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Соглашения о вызовах Windows x64 задокументированы в Microsoft Docs.

Вызов GetStdHandle очень прост: он передает STD_OUTPUT_HANDLE (-11) в качестве первого параметра, который использует ECX; возвращаемое значение находится в RAX.

Вызов WriteConsoleA немного сложнее. Технически функция принимает 5 параметров, последний из которых зарезервирован, но код передает только четыре.

Имейте в виду, что написать полностью «правильную» сборку Windows x64 довольно сложно из-за необходимой информации для раскручивания исключений. Есть некоторые макросы MASM, но не знаю о NASM.

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

vitsoft 25.10.2022 09:53

Я ожидаю, что вызовы перезапишут адрес возврата, поэтому он вылетит на ret внизу, поскольку эта программа не может зарезервировать 32 байта теневого пространства перед вызовами. Это важная часть соглашения о вызовах, которому этот код не следует. Он также передает указатель на [RSP-16], который находится внутри кадра стека вызываемого объекта.

Peter Cordes 25.10.2022 15:18

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