Русский / Russian English / Английский

Сейчас на форуме: strannyi, artyavmu, user99 (+4 невидимых)
 · Начало · Статистика · Регистрация · Поиск · ПРАВИЛА ФОРУМА · Язык · RSS ·

 eXeL@B —› Программирование —› Вопрос по х64 асму
Посл.ответ Сообщение


Ранг: 150.7 (ветеран)
Статус: Участник

Создано: 16 августа 2018 12:30 · Поправил: -=AkaBOSS=- New!
Цитата · Личное сообщение · #1

Приветствую собратьев ассемблерщиков!
Недавно решил поиграться 64 битным асмом, и засыпался на банальнейшем хелловорлде
Code:
  1.   frame
  2.   invoke MessageBoxW, 0, addr txt1, addr txt2, 0
  3.   invoke ExitProcess, 0
  4.   endf


Вроде ж ничего криминального, но программа упорно падает где-то в системных недрах:
Code:
  1. movaps xmmword [rsp+150],  xmm8   ; lpk.dll+1775 exception!


Эксепшен генерится ммх командой, которая ожидает, что записываемый адрес будет кратен 0х10
Таким образом, добавив в начало своей программы выравнивание стэка "and rsp, -16", я от проблемы избавился.

А теперь, собственно, вопрос: как правильно оформлять стек в х64?
Допустим, я вызываю апи функцию, которой нужно передать больше 4ёх аргументов - они пойдут через стэк.
Выравнивать нужно до стековых аргументов, или так, чтобы в итоге только 0x20 фрейм был выравнен?
Какие еще есть грабли, о которых нужно знать, чтобы писать на х64 асме?

[имхо]стандартное соглашение о вызовах - просто жесть дичайшая.
Вместо того, чтобы просто толкать первые четыре аргумента в стэк, они пишутся в регистры,
но вызывающая сторона всё равно должна выделить 0х20 байт в стэке, куда вызванная
функция сохраняет свои аргументы. О чём они, бл***, думали?
[/имхо]



{ Атач доступен только для участников форума } - buggy.exe

Ранг: 404.7 (мудрец)
Статус: Участник
"Тибериумный реверсинг"

Создано: 16 августа 2018 12:58 · Поправил: ELF_7719116 New!
Цитата · Личное сообщение · #2

Что студийный компиль нагенерил:
Code:
  1. ::MessageBoxW(NULL, L"TEXT", L"HEAD", MB_OK);
  2. 0000000140007940  mov         eax,0  
  3. 0000000140007945  lea         rdx,[string L"\x5400\x4500\x5800\x5400" (014031933Ch)]  
  4. 000000014000794C  lea         rcx,[string L"\x4800\x4500\x4100\x4400" (0140319348h)]  
  5. 0000000140007953  mov         ebx,0  
  6. 0000000140007958  mov         rsi,qword ptr [__imp_MessageBoxW (0140314FD0h)]  
  7. 000000014000795F  mov         qword ptr [rbp+298h],rcx  
  8. 0000000140007966  mov         rcx,rax 
  9. 0000000140007969  mov         rax,qword ptr [rbp+298h]  
  10. 0000000140007970  mov         r8,rax  
  11. 0000000140007973  mov         r9d,ebx  
  12. 0000000140007976  call        rsi  
  13. 0000000140007978  mov         dword ptr [rbp+22Ch],eax

как-бэ fastcall

Ранг: 370.2 (мудрец)
Статус: Участник

Создано: 16 августа 2018 15:09 · Поправил: ntldr New!
Цитата · Личное сообщение · #3

ELF_7719116 пишет:
как-бэ fastcall

Обычный для x64 calling convention

-=AkaBOSS=- пишет:
Вместо того, чтобы просто толкать первые четыре аргумента в стэк, они пишутся в регистры,
но вызывающая сторона всё равно должна выделить 0х20 байт в стэке, куда вызванная
функция сохраняет свои аргументы. О чём они, бл***, думали?

Вообще-то это очень мудрое решение с точки зрения глобальной оптимизации кода. Стековые фреймы могут быть выделены один раз, функции можно вызывать много раз и разные.
Просто это всё не предназначено чтобы вручную писать на ассемблере. Юзайте си.


Ранг: 244.0 (наставник)
Статус: Участник

Создано: 16 августа 2018 15:14 · Поправил: f13nd New!
Цитата · Личное сообщение · #4

Code:
  1.         sub rsp,0x400
  2.         and rsp,not 31
  3.         invoke MessageBoxW, 0, addr txt1, addr txt2, MB_OK
  4.         invoke ExitProcess, 0
  5.         ret

Идея понятна?
С такой мишурой можно столкнуться и в х32, с Zw* и Nt* функциями.


Ранг: 2008.7 (!!!!)
Статус: Модератор
retired

Создано: 16 августа 2018 15:25 New!
Цитата · Личное сообщение · #5

Есть отличная статья про переход на x64 https://www.codeproject.com/Articles/17263/Moving-to-Windows-Vista-x64
Это стандартная (и единственная) конвенция вызовов в x64. Всяко полезно ознакомиться.

| Сообщение посчитали полезным: ajax, -=AkaBOSS=-, plutos



Ранг: 63.2 (постоянный)
Статус: Участник

Создано: 16 августа 2018 20:02 · Поправил: BlackCode New!
Цитата · Личное сообщение · #6

-=AkaBOSS=-
В х64 необходимо выравнивать стек на 16 байт, в противном случае будут проблемы описанные тобой.
Для решения оной юзаем макрос
Code:
  1.     ; ********************************************
  2.     ; align memory *
  3.     ; reg has the address of the memory to align *
  4.     ; number is the required alignment *
  5.     ; EXAMPLE : memalign esi, 16 *
  6.     ; ********************************************
  7.  
  8.       memalign MACRO reg, number
  9.         add reg, number - 1
  10.         and reg, -number
  11.       ENDM


В начале функции memalign rsp,16


Ранг: 150.7 (ветеран)
Статус: Участник

Создано: 17 августа 2018 08:54 New!
Цитата · Личное сообщение · #7

BlackCode, да причину-то я и сам понял, еще до создания темы.
Другое дело что мне было неясно, как при этом поступать с аргументами, которые передаются через стэк. Как выравнивать - до них или после.
Archer дал ссылку на статью, где это проясняется - выделяем фрейм размером <кол-во стековых аргументов>*8+0х20, округляем rsp вниз до 0х10 и стэковые аргументы не толкаем, а вписываем как-то так: mov [rsp+20h], arg5; mov [rsp+28h], arg6; и т.д.
И разумеется, перед каждым таким фреймом нужно сохранять rsp, так как после округления его уже простой математикой не восстановишь.


Ранг: 244.0 (наставник)
Статус: Участник

Создано: 17 августа 2018 08:58 New!
Цитата · Личное сообщение · #8

-=AkaBOSS=- пишет:
его уже простой математикой не восстановишь

Инструкцией leave такое округление восстановится само.


Ранг: 150.7 (ветеран)
Статус: Участник

Создано: 17 августа 2018 09:09 · Поправил: -=AkaBOSS=- New!
Цитата · Личное сообщение · #9

f13nd пишет:
Инструкцией leave такое округление восстановится само.

если регистр не был предварительно сохранён - нет

f13nd пишет:
это всяко лучше

ну вообще в целом это уже зависит от того, как и для чего использовать стэк)


Ранг: 244.0 (наставник)
Статус: Участник

Создано: 17 августа 2018 09:15 New!
Цитата · Личное сообщение · #10

-=AkaBOSS=- пишет:
если регистр не был предварительно сохранён - нет

это всяко лучше, чем "перед каждым таким фреймом сохранять rsp"


Ранг: 63.2 (постоянный)
Статус: Участник

Создано: 17 августа 2018 11:49 New!
Цитата · Личное сообщение · #11

-=AkaBOSS=-

Ты какой компилятор используешь?
Я UASM64, ранее JWASM..
Как правило компилятор сам заботится об сохранении параметров и выделении стека под аргументы.
В заголовке у меня такие параметры
Code:
  1.     .686
  2.     .MMX
  3.     .XMM
  4.     .x64
  5.     option casemap:none
  6.     option frame:auto
  7.     option win64:11
  8.     option evex:1
  9.     option arch:AVX


Ранг: 2008.7 (!!!!)
Статус: Модератор
retired

Создано: 17 августа 2018 11:49 New!
Цитата · Личное сообщение · #12

Leave-это просто автоматизированный аналог mov Xsp,Xbp; pop Xbp. Если в Xbp никто до этого не положил Xsp, будет мусор.
И в x64 фреймы используются достаточно нечасто в скомпилированном коде. В том числе и потому, что никто не делает там and Xsp,imm. А не делает потому, что на входе в функцию стек уже определённым образом выровнен, чем и пользуются.


Ранг: 325.1 (мудрец)
Статус: Участник

Создано: 18 августа 2018 01:24 New!
Цитата · Личное сообщение · #13

И из за компилерных фич трассировка ветвлений(backtrace) выполняется через брутфорс адресов

Ранг: 370.2 (мудрец)
Статус: Участник

Создано: 24 августа 2018 08:34 New!
Цитата · Личное сообщение · #14

BlackCode пишет:
UASM64

Не подскажешь поддерживает ли этот компилятор COMDAT сегменты?


Ранг: 666.4 (! !)
Статус: Участник
CyberMonk

Создано: 24 августа 2018 12:40 · Поправил: mak New!
Цитата · Личное сообщение · #15

ntldr пишет:
Не подскажешь поддерживает ли этот компилятор COMDAT сегменты?


Ассемблер, UASM64 ешё не компилятор .. поэтому COMDAT в основном не поддерживает, только на уровне самих сегментов, точно так же, как и масм64. Пример для уасм можно посмотреть здесь - --> Link <--

Ранг: 1.0 (гость)
Статус: Участник

Создано: 14 декабря 2018 20:57 New!
Цитата · Личное сообщение · #16

Привет всем мимо проходящим
Также приветствую собратьев ассемблерщиков
Хотел спросить кто в какой программе любит кодить, как вам Sublime Text ?
Вроде как неплохой редактор, с очень удобной подсветкой синтаксиса и прочих плюшек

Ранг: 68.4 (постоянный)
Статус: Участник

Создано: 14 декабря 2018 21:00 New!
Цитата · Личное сообщение · #17

HabibQq пишет:
Привет всем мимо проходящим

Дык ,по ходу это ты..

Ранг: 1.0 (гость)
Статус: Участник

Создано: 14 декабря 2018 21:06 New!
Цитата · Личное сообщение · #18

HabibQq пишет:
Привет всем мимо проходящим
Также приветствую собратьев ассемблерщиков
Хотел спросить кто в какой программе любит кодить, как вам Sublime Text ?
Вроде как неплохой редактор, с очень удобной подсветкой синтаксиса и прочих плюшек


Мне лично Atom по душе...или Komodo Edit
Подсветка синтаксиса это не самое важное как мне кажется


Ранг: 244.0 (наставник)
Статус: Участник

Создано: 14 декабря 2018 21:12 New!
Цитата · Личное сообщение · #19

HabibQq пишет:
Также приветствую собратьев ассемблерщиков

Sublime Text поддерживает следующие форматы:
- C, CPP, H, HPP, INL, CC, D, ERL, DOT, HTML, HS, JAVA, JS, TEX, LISP, LUA, PL, PY, R, SQL, TCL, XML

Жалкая попытка "беспалевной" рекламы. Ну хоть бы тему правильно выбрал куда постить.
 eXeL@B —› Программирование —› Вопрос по х64 асму

Видеокурс ВЗЛОМ