• XSS.stack #1 – первый литературный журнал от юзеров форума

Assembler + WinAPI

codedivision

RAID-массив
Пользователь
Регистрация
14.12.2018
Сообщения
71
Реакции
16
Здравствуйте.
Нужно небольшое разъяснение по Assembler + WinAPI.

Как лучше использовать сторонние функции, через import и extern или только extern?

Пример:

1. import и extern - macro_import_function kernel32.dll, _ExitProcess
2. extern - extern _ExitProcess@4
И вызов функции - call _ExitProcess@4.

Сейчас я использую второй вариант и импортирую данные из dll при линковке, так как не хочу работать с макросами. Но я не понимаю, для чего нужен @4 (в данном случае) и откуда это взять? Без @4 линковка с ошибками, что нет defined.
Я думал, что это данные из dll, но об этом ничего не указано.

Пример кода.

extern _CreateWindowExA@48
extern _DefWindowProcA@16
extern _DispatchMessageA@4
extern _ExitProcess@4
extern _GetMessageA@16
extern _GetModuleHandleA@4
extern _IsDialogMessageA@8
extern _LoadImageA@24
extern _PostQuitMessage@4
extern _RegisterClassExA@4
extern _ShowWindow@8
extern _TranslateMessage@4
extern _UpdateWindow@4

Как работать с defined?

Нужно ли на Assembler дополнительно объявлять функции как это происходит у других языков программирования?

Пример для C++.

int WINAPI MessageBox(
_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
_In_ UINT uType
);
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
в папке example есть пример PEDEMO. где чистый код без инклудов


; Example of making 32-bit PE program as raw code and data

format PE GUI
entry start

section '.text' code readable executable

start:

push 0
push _caption
push _message
push 0
call [MessageBoxA]

push 0
call [ExitProcess]

section '.data' data readable writeable

_caption db 'Win32 assembly program',0
_message db 'Hello World!',0

section '.idata' import data readable writeable

dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0

kernel_table:
ExitProcess dd RVA _ExitProcess
dd 0
user_table:
MessageBoxA dd RVA _MessageBoxA
dd 0

kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0

_ExitProcess dw 0
db 'ExitProcess',0
_MessageBoxA dw 0
db 'MessageBoxA',0

section '.reloc' fixups data readable discardable ; needed for Win32s
 
kernel_name db 'KERNEL32.DLL',0
user_name db 'USER32.DLL',0
Отсюда берется информация.
А у меня при линковке, нужен define для функций или будет ошибка.
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
для чего нужен @4
В данном случае 1 параметр, речь идет же о 32 битах? т.е. это 1 dword.
 
речь идет же о 32 битах?
Да. На 64 могу работать без define. Почему так?

это 1 dword
Минимум 4 байта - @4 - 1 dword?
Выставляю одинаковые значения для теста (@4, @20), но все работает нормально. Можешь отправить материалы об этом?
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
На 64 другая конвенция вызова функций.

Надо указывать именно столько, сколько аргументов у функции, чтобы потом не искать трудноуловимые ошибки.
А вообще, не понимаю, зачем такой изврат, с этим _@ - . Я не знаю, что оно делает в фасм, но в масме это экономит 6 байт перехода + 1-2 лишних такта процессора. Это же не анти-отладка или эмуль.. Конечно, для обучения можно кодить как угодно, но все же.

Почитай для начала уроки Iczelion'a по фасм (если пишешь на нем). Будут вопросы, пиши в теме, но сначала матчасть.
 
что-то не пойму как это помогает отловить сколько параметров передано в функцию. параметры в стек можно класть каким угодно способом. даже ROPом сделать можно, как это проконтролируется ?
 
Пожалуйста, обратите внимание, что пользователь заблокирован
Да никак не проконтролируется. Функции пофигу , что там в стеке. Если она принимает, скажем, 2 парамета, то и берет их оттуда, а что там будет - уже на совести кодера.

что-то я не пойму, о чем у нас тема.
 
Да никак не проконтролируется. Функции пофигу , что там в стеке. Если она принимает, скажем, 2 парамета, то и берет их оттуда, а что там будет - уже на совести кодера.
Можно брать любое количество, только не меньше того, чем нужно?

что-то я не пойму, о чем у нас тема.
Тема о том, как нормально работать с асм + винапи.

Я не использую сторонние макросы и инклюды (из-за этого импорт функций напрямую можно сразу отбросить). Пишу на насм с использованием голинк. Последний при линковке берет инфу импорта из длл.
Вызов сторонней функции происходит с call _. Иначе насм и голинк не работают.
Если не указываю @ происходит ошибка. Скриншот ниже.

error.png


Новый вопрос. Как правильно работать с @? Примеров функций в теме достаточно.

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

Для Win32 API (например, kernel32, user32 и т.д.), каждая функция, сопровождается «@xx», где xx - количество 4-байтовых аргументов, необходимых такой функции в десятичном числе. Например, «ExitProcess» требует одного аргумента, таким образом, Вы называете его как _ExitProcess@4. Если 4 аргумента (4 толчка), то это «@16».
Почти все функции Win32 API - stdcall, таким образом, их имена украшены знаком, сопровождаемый числом байтов, поднятых их параметрами.

Обычно компилятор заботится об этих пунктах для Вас.
Подчеркивание (_) снабжено префиксом к имени. Имя сопровождается в знаке сопровождаемым числом байтов (в десятичном числе) в списке аргументов. Поэтому функция, объявленная как интервал func (интервал a, дважды b), украшена следующим образом: _func@12
 
Последнее редактирование:
Пожалуйста, обратите внимание, что пользователь заблокирован
codedivision
Объясните, зачем вам вообще эти извраты? У меня масм не собирает код вида extern _imp__MessageBoxA@20:dword , потому что линкер не находит в либ файле MessageBoxA@20 , там есть только с 16 (4 дворда).

как нормально работать с асм + винапи.
нормально - это подключить инклуды и вызывать функции через invoke ,ну максимум через call FuncName , а не через сомнительные техники.
 
нормально - это подключить инклуды и вызывать функции через invoke ,ну максимум через call FuncName , а не через сомнительные техники.
Я и использую второй вариант, только без левых инклюдов.

Объясните, зачем вам вообще эти извраты?
Выше объяснил.
Если указываю без @, то ругается голинк. Если указываю через импорт, то ругается насм.
И почему-то через импорт (просто функция, без @) будет ошибка, что такой функции нет в длл.

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


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх