Неопределенная функция с extern "c" и сборкой - PullRequest
1 голос
/ 16 февраля 2020

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

Вот мои файлы: Api.h

extern "C" NTSTATUS NtWriteVirtualMem(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten);

API_ASM.asm

.code
_NtWriteVirtualMem:
    mov r10, rcx
    mov eax, 3Ah
    syscall
    ret

end

Они оба компилируются правильно, но я получаю ошибку, потому что NtWriteVirtualMem определен, но я определил его в своем asm?

РЕДАКТИРОВАТЬ 1.

Поэтому я изменил свой код на:

PUBLIC NtWriteVirtualMem

_TEXT SEGMENT
NtWriteVirtualMem PROC
    mov r10, rcx
    mov eax, 3Ah
    syscall
    ret
    NtWriteVirtualMem ENDP
_TEXT ENDS
END

Программа теперь компилируется, но запись не работает. Я проверил это, чтобы видеть, работает ли writeprocessmemory, и это делает. Кроме того, моя среда IDE показывает, что NtWriteVirtualMem по-прежнему не определено, когда я наведите курсор на имя в источнике C.

EDIT 2.

Кроме того, NTSTATUS Код возврата для операции - отрицательное максимальное целое число.

1 Ответ

1 голос
/ 16 февраля 2020

Windows x64 не использует начальное подчеркивание _ в именах символов asm . Ваше имя метки asm должно быть просто NtWriteVirtualMem, что соответствует имени функции extern "C".

См., Например, руководство по соглашениям о вызовах Agner Fog. http://www.agner.org/optimize/calling_conventions.pdf

(Также убедитесь, что вы указываете ассемблеру экспортировать его, если необходимо. Как и в случае с NASM, вы бы использовали global, чтобы изменить это объявление метки. IDK, если требуется MASM pro c / endp или если метка может работать.)


Ваша фиксированная версия правильно связывается, и вы подтвердили, что выполнение выполняется с помощью инструкции syscall. Возможно, вы передаете неправильные аргументы, или неправильно передаете их, или используете неправильный номер вызова.

ABI syscall недокументирован и не поддерживается на Windows и может меняться между версии ядра. https://j00ru.vexillium.org/syscalls/nt/64/ говорит, что номер вызова для NtWriteVirtualMem равен 3Ah во всех Windows 10 версиях, но я не знаю, правильно ли вы передаете другие аргументы , В предыдущих версиях Windows, 0x3a - это другой системный вызов.

Я оставлю эту часть вопроса тому, кто использует Windows и знает, что делает этот системный вызов.

...