首页 > 解决方案 > 带有外部“c”和程序集的未定义函数

问题描述

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

这是我的文件: 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 是否有效并且确实有效。NtWriteVirtualMem此外,当我将鼠标悬停在 C 源代码中的名称上时,我的 IDE 显示仍然未定义。

编辑 2。

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

标签: c++windowsassemblyabint-native-api

解决方案


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

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

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


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

ABI在syscallWindows 上未记录且不受支持,并且可以在内核版本之间更改。 https://j00ru.vexillium.org/syscalls/nt/64/表示所有 Windows 10 版本上的NtWriteVirtualMem索书号3Ah,但我不知道您是否正确传递了其他参数。在早期版本的 Windows 上,0x3a是一个不同的系统调用。

我将把这部分问题留给使用 Windows 并且知道该系统调用做什么的人。


推荐阅读