具有外部"c"和程序集的未定义函数

Undefined function with extern "c" and assembly

本文关键字:未定义 函数 程序集 外部      更新时间:2023-10-16

嘿,所以我在尝试编译代码时遇到未定义的函数错误,我不知道为什么。

这是我的文件: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 显示,当我将鼠标悬停在 C 源代码中的名称上时,NtWriteVirtualMem仍未定义。

编辑 2.

此外,操作的 NTSTATUS 返回代码是负最大整数。

Windows x64 在 asm 符号名称中不使用前导下划线_。 您的 asm 标签名称应该只是NtWriteVirtualMem,与extern "C"函数名称匹配。

例如,请参阅Agner Fog的呼叫约定指南。 http://www.agner.org/optimize/calling_conventions.pdf

(如有必要,还要确保告诉汇编程序将其导出。 与 NASM 一样,您可以使用global来修改该标签声明。 IDK,如果MASM需要proc/endp或标签可以工作。


您的固定版本链接正确,并且您确认执行通过syscall指令。 可能您传递了错误的参数,或者以错误的方式传递了它们,或者使用了错误的呼叫号码。

syscallABI 在 Windows 上没有文档且不受支持,并且可以在内核版本之间更改。https://j00ru.vexillium.org/syscalls/nt/64/说NtWriteVirtualMem的呼叫号码在所有Windows 10版本上都3Ah,但我不知道您是否正确传递了其他参数。 在Windows的早期版本中,0x3a是不同的系统调用。

我将把这部分问题留给使用 Windows 并知道系统调用的作用的人。