嘿,所以我在尝试编译代码时遇到未定义的函数错误,我不知道为什么。
这是我的文件: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
指令。 可能您传递了错误的参数,或者以错误的方式传递了它们,或者使用了错误的呼叫号码。
syscall
ABI 在 Windows 上没有文档且不受支持,并且可以在内核版本之间更改。https://j00ru.vexillium.org/syscalls/nt/64/说NtWriteVirtualMem
的呼叫号码在所有Windows 10版本上都3Ah
,但我不知道您是否正确传递了其他参数。 在Windows的早期版本中,0x3a
是不同的系统调用。
我将把这部分问题留给使用 Windows 并知道系统调用的作用的人。