Убедитесь, что значение находится в определенном регистре как в GCC, так и в MSVC в Windows X64C++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Убедитесь, что значение находится в определенном регистре как в GCC, так и в MSVC в Windows X64

Сообщение Anonymous »

Цель состоит в том, чтобы гарантировать, что R10 и R11 устанавливаются на определенные значения перед вызовом функции сборки: < /p>

Код: Выделить всё

template
int wrapper(int val1, int val2, Args... args) {
// somehow place val1 in r10
// somehow place val2 in r11
foo(args...);
}
< /code>
Из-за того, что MSVC по какой-то причине не поддерживает встроенную сборку на x64 Я попытался определить две функции сборки, которые установили бы регистры перед вызовом: < /p>
extern "C" setr10(int);
extern "C" setr11(int);
< /code>
Затем вызов выглядит следующим образом: < /p>
template
int wrapper(int val1, int val2, Args... args) {
setr10(val1);
setr11(val2);
foo(args...);
}
Но это до сих пор не гарантирует, что эти регистры не будут затронуты компилятором во время распаковки args , о которых я мучительно узнал. Я попробовал это в программе тестирования, а затем это сработало, я также позаботился о том, чтобы отключить оптимизацию. (Вероятно, сделал что -то не так, но во всей кодовой базе, за исключением этого случая, с реестрами нет никаких действий, только обычный код). Тем не менее, мне нужно что -то, что будет работать на MSVC. Это решение, однако, решение, которое я пытаюсь избежать из-за обширного использования сборки, в котором оно требуется (с которым, как правило, у меня не было бы проблемы, но из-за внешних обстоятельств это не жизнеспособно). < /P>
Я также думал, что использование нелетучи Возвращение, не между различными вызовами функций. Так что это также не помогает. < /P>
Так что пересылает аргументы с ассамблеей, неизбежным? В случае реального использования я делаю косвенные Syscalls (это библиотека, которая также служит POC), поэтому первый ARG должен быть в R10 , и номер SYCALL должен быть в RAX . Функция передается по номеру Syscall, адрес Syscall Stub (означающий syscall; ret ) и количество аргументов в стеке, подпись функции будет:

Код: Выделить всё

extern "C" NTSTATUS NTAPI trampoline(size_t syscallNo, uintptr_t syscallAddr, size_t stackArgumentCount, ...);
< /code>
trampoline:
# Preserve
push r15
push r14
push r13
push r12
push rsi
push rdi
mov r13, rcx                    # Preserve syscall number
mov r14, rdx                    # Preserve syscall stub instruction address
mov r15, r8                     # Preserve amount of arguments that will be pushed onto the stack

# Forward arguments of the caller
mov rcx, r9
mov rdx, [rsp + 40 + 48]        # 32 - shadow store, 8 - return address, add 48 to account for registers pushed onto the stack
mov r8,  [rsp + 48 + 48]
mov r9,  [rsp + 56 + 48]

# copy
push rdx                        # Preserve rdx
mov rax, 8
mul r15                         # Multiply by 8 to get bytes to reserve stack space
pop rdx
mov r12, rax                    # Preserve the size of the arguments that need to be copied onto the stack
sub rsp, rax                    # Increase the stack by the amount needed by the arguments on the stack that need to be copied
lea rsi, [rsp + rax + 64 + 48]
mov rdi, rsp                    # Copy to the current top of the stack
push rcx                        # Preserve rcx
mov rcx, r15
rep movsq                       # Copy the arguments that are supposed to be allocated on the stack
pop rcx

mov r10, rcx                    # Preserve rcx
mov rax, r13
sub rsp, 32                     # Shadow space

call r14                        # Jump to syscall stub

add r12, 32
add rsp, r12

pop rdi
pop rsi
pop r12
pop r13
pop r14
pop r15
ret
Если у кого -то есть идея для более короткой функции, которая, безусловно, приветствуется.


Подробнее здесь: https://stackoverflow.com/questions/797 ... indows-x64
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C++»