Функция делающая системный вызов x64

Тема в разделе "WASM.BEGINNERS", создана пользователем bambinorest1, 9 сен 2024.

  1. bambinorest1

    bambinorest1 New Member

    Публикаций:
    0
    Регистрация:
    9 сен 2024
    Сообщения:
    3
    Функция должна принимать первым аргументом номер системного вызова, а дальше любое количество параметров которые требует системный вызов и при этом не делая перекладывание аргументов. Значит в rcx номер системного вызова, а дальше все остальные аргументы. Вот код который мог бы работать:
    Код (ASM):
    1. .code
    2.  
    3. SyscallX64 proc
    4.     mov rax, rcx
    5.     mov rcx, rdx
    6.     mov rdx, r8
    7.     mov r8, r9
    8.     mov r9, [rsp+28h]
    9.     mov r10, rcx
    10.     add rsp, 8
    11.     syscall
    12.     sub rsp, 8
    13.     ret
    14. SyscallX64 endp
    15.  
    16. end
    В большинстве случаев это работает, но если будет исключение, то ничего не сработает. Как еще можно было такое решить?
     
  2. CaptainObvious

    CaptainObvious Member

    Публикаций:
    1
    Регистрация:
    18 янв 2024
    Сообщения:
    87
    Код (ASM):
    1. SyscallX64 proc
    2.     push rdx
    3.     push r8
    4.     push r9
    5.     mov rax, rcx
    6.     mov rcx, [rsp+16]  ; Получаем первый аргумент из стека
    7.     mov rdx, [rsp+24]  ; Получаем второй аргумент из стека
    8.     mov r8, [rsp+32]   ; Получаем третий аргумент из стека
    9.     mov r9, [rsp+40]   ; Получаем четвертый аргумент из стека
    10.     syscall
    11.     pop r9
    12.     pop r8
    13.     pop rdx
    14.     ret
    15. SyscallX64 endp
     
  3. bambinorest1

    bambinorest1 New Member

    Публикаций:
    0
    Регистрация:
    9 сен 2024
    Сообщения:
    3
    Нейросеть уже бала попробована)
     
  4. CaptainObvious

    CaptainObvious Member

    Публикаций:
    1
    Регистрация:
    18 янв 2024
    Сообщения:
    87
    [​IMG]
     
    alex_dz нравится это.
  5. miilalex

    miilalex New Member

    Публикаций:
    0
    Регистрация:
    8 сен 2024
    Сообщения:
    8
    в этом фрагменте кода на мой взгляд нельзя прибавлять rsp 8 до вызова syscall и соответственно вычитать после.

    потому что любая последующая операция push вычтет 8 из указателя стека и перезапишет его вершину другим значением

    то есть, когда/если мы сохраняли в стек регистр где-то ранее в коде, это значение будет утрачено/затерто и при попытке извлечь из стека - мы получим какое-то другое значение. вообще говоря, произвольное
    и программа обрушится

    если поменять местами эти команды, то есть до вызова вычесть указатель стека, а после прибавить, это обеспечит резервирование памяти в стеке, но не приведет к разрушению сохраненных в нем данных
     
  6. f13nd

    f13nd Well-Known Member

    Публикаций:
    0
    Регистрация:
    22 июн 2009
    Сообщения:
    1.993
    Там как я понял идея убрать адрес возврата с верхушки стека, потому что:
    Не знаю как работает макрос proc масма, фасм в принудительном порядке создает стекфрейм и уже 16 байт надо со стека убирать:
    Код (ASM):
    1. push rbp
    2. mov rbp,rsp
    3. mov rax,rcx
    4. mov rcx,rdx
    5. mov rdx,r8
    6. mov r8,r9
    7. mov r9,qword ptr ss:[rsp+28]
    8. mov r10,rcx
    9. add rsp,8
    10. syscall
    11. sub rsp,8
    12. leave
    13. ret
    Мне нравится, что истинная причина неуспеха даже не изучалась.

    ЗЫ: я бы наплодил сколько надо процедур с каким надо количеством аргументов под каждый нужный сискол, их же в конце конца не сотни разных, чтобы об этом переживать. Выкидывать адрес возврата за борт это однозначно авантюра.
    --- Сообщение объединено, 14 сен 2024 ---
    ЗЗЫ: но если жестить по-черному, почему бы не установить обработчик seh перед вызовом процедуры и намеренно не вызывать исключение после syscall'а? Обработчик будет знать куда вернуть управление. Выглядит гораздо надежней, чем временно потерять адрес возврата.
     
  7. R81...

    R81... Active Member

    Публикаций:
    0
    Регистрация:
    1 фев 2020
    Сообщения:
    149
    bambinorest1, имя SysCallX64
    не работал я с x64, но (на уровне мнения) MASM.
    Если Ваш код ~работает и...:

    1. есть r??, "не занятый Вами"
    и сохраняемый системой, то:
    Код (ASM):
    1. SysCallX64 Proc
    2.   Mov rAx, rCx
    3.   Mov r10, rDx
    4.   Mov rDx, r8
    5.   Mov r8, r9
    6.   Mov r9, [rSp+28h]
    7.  
    8.   Pop r??
    9.   SysCall
    10.   Jmp r??
    11. SysCallX64 EndP
    2. все r?? "Вами заняты", но есть
    r??, хотя бы сохраняемый системой,
    то как удобнее в макро или...
    Код (ASM):
    1.   Push  r??  ; "обернуть"
    2. ;....
    3.   Call  SysCallX64 ; см. выше
    4. ;....
    5.   Pop  r??  ; "обернуть"
    3. Внутри SysCall Windows
    допускает [rSp] /= rXX, то:
    Код (ASM):
    1. SysCallX64 Proc
    2.   Mov rAx, rCx
    3.   Mov r10, rDx
    4.   Mov rDx, r8
    5.   Mov r8, r9
    6.   Mov r9, [rSp+28h]
    7.  
    8.   Pop [rSp + 8]
    9.   SysCall
    10.   Ret
    11. SysCallX64 EndP
    4. Вы допускаете SysCall
    после Call SysCallX64, то:
    Код (ASM):
    1.  SysCallX64 Proc
    2.   Mov rAx, rCx
    3.   Mov r10, rDx
    4.   Mov rDx, r8
    5.   Mov r8, r9
    6.   Mov r9, [rSp+28h]
    7.  
    8.   Ret
    9.  SysCallX64 EndP
    10. ;....
    11. ; как удобнее в макро или...
    12.   Call SysCallX64
    13.   SysCall