Функция должна принимать первым аргументом номер системного вызова, а дальше любое количество параметров которые требует системный вызов и при этом не делая перекладывание аргументов. Значит в rcx номер системного вызова, а дальше все остальные аргументы. Вот код который мог бы работать: Код (ASM): .code SyscallX64 proc mov rax, rcx mov rcx, rdx mov rdx, r8 mov r8, r9 mov r9, [rsp+28h] mov r10, rcx add rsp, 8 syscall sub rsp, 8 ret SyscallX64 endp end В большинстве случаев это работает, но если будет исключение, то ничего не сработает. Как еще можно было такое решить?
Код (ASM): SyscallX64 proc push rdx push r8 push r9 mov rax, rcx mov rcx, [rsp+16] ; Получаем первый аргумент из стека mov rdx, [rsp+24] ; Получаем второй аргумент из стека mov r8, [rsp+32] ; Получаем третий аргумент из стека mov r9, [rsp+40] ; Получаем четвертый аргумент из стека syscall pop r9 pop r8 pop rdx ret SyscallX64 endp
в этом фрагменте кода на мой взгляд нельзя прибавлять rsp 8 до вызова syscall и соответственно вычитать после. потому что любая последующая операция push вычтет 8 из указателя стека и перезапишет его вершину другим значением то есть, когда/если мы сохраняли в стек регистр где-то ранее в коде, это значение будет утрачено/затерто и при попытке извлечь из стека - мы получим какое-то другое значение. вообще говоря, произвольное и программа обрушится если поменять местами эти команды, то есть до вызова вычесть указатель стека, а после прибавить, это обеспечит резервирование памяти в стеке, но не приведет к разрушению сохраненных в нем данных
Там как я понял идея убрать адрес возврата с верхушки стека, потому что: Не знаю как работает макрос proc масма, фасм в принудительном порядке создает стекфрейм и уже 16 байт надо со стека убирать: Код (ASM): push rbp mov rbp,rsp mov rax,rcx mov rcx,rdx mov rdx,r8 mov r8,r9 mov r9,qword ptr ss:[rsp+28] mov r10,rcx add rsp,8 syscall sub rsp,8 leave ret Мне нравится, что истинная причина неуспеха даже не изучалась. ЗЫ: я бы наплодил сколько надо процедур с каким надо количеством аргументов под каждый нужный сискол, их же в конце конца не сотни разных, чтобы об этом переживать. Выкидывать адрес возврата за борт это однозначно авантюра. --- Сообщение объединено, 14 сен 2024 --- ЗЗЫ: но если жестить по-черному, почему бы не установить обработчик seh перед вызовом процедуры и намеренно не вызывать исключение после syscall'а? Обработчик будет знать куда вернуть управление. Выглядит гораздо надежней, чем временно потерять адрес возврата.
bambinorest1, имя SysCallX64 не работал я с x64, но (на уровне мнения) MASM. Если Ваш код ~работает и...: 1. есть r??, "не занятый Вами" и сохраняемый системой, то: Код (ASM): SysCallX64 Proc Mov rAx, rCx Mov r10, rDx Mov rDx, r8 Mov r8, r9 Mov r9, [rSp+28h] Pop r?? SysCall Jmp r?? SysCallX64 EndP 2. все r?? "Вами заняты", но есть r??, хотя бы сохраняемый системой, то как удобнее в макро или... Код (ASM): Push r?? ; "обернуть" ;.... Call SysCallX64 ; см. выше ;.... Pop r?? ; "обернуть" 3. Внутри SysCall Windows допускает [rSp] /= rXX, то: Код (ASM): SysCallX64 Proc Mov rAx, rCx Mov r10, rDx Mov rDx, r8 Mov r8, r9 Mov r9, [rSp+28h] Pop [rSp + 8] SysCall Ret SysCallX64 EndP 4. Вы допускаете SysCall после Call SysCallX64, то: Код (ASM): SysCallX64 Proc Mov rAx, rCx Mov r10, rDx Mov rDx, r8 Mov r8, r9 Mov r9, [rSp+28h] Ret SysCallX64 EndP ;.... ; как удобнее в макро или... Call SysCallX64 SysCall