im trying to make a super simple direct syscall. I have 2 file, 1 is the asm file and 1 is the main source file. The ASM look likes:
EXTERN wNtAllocateVirtualMemory: DWORD
.CODE
NtAllocateVirtualMemory proc
mov r10, rcx
mov eax, wNtAllocateVirtualMemory
syscall
ret
NtAllocateVirtualMemory endp
END
The source file:
#include<Windows.h>
#include<stdio.h>
DWORD wNtAllocateVirtualMemory;
typedef long NTSTATUS;
typedef NTSTATUS* PNTSTATUS;
extern "C" { NTSTATUS NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect); }
int main() {
PVOID allocBuffer = NULL;
SIZE_T buffSize = 0x1000;
HANDLE hNtdll = GetModuleHandleA("ntdll");
if (hNtdll == NULL) {
perror("Fail to get handle");
return 0;
}
PVOID pNtAllocateVirtualMemory = GetProcAddress((HMODULE) hNtdll, "NtAllocateVirtualMemory");
wNtAllocateVirtualMemory = *((char*)pNtAllocateVirtualMemory + 4);
NtAllocateVirtualMemory((HANDLE)-1, (PVOID*)&allocBuffer, (ULONG_PTR)0, &buffSize, (ULONG)(MEM_COMMIT | MEM_RESERVE), PAGE_EXECUTE_READWRITE);
}
There is no error when i change the source type from c++ to c, but if the source type is c++, error happends.
Error LNK2019 unresolved external symbol wNtAllocateVirtualMemory referenced in function NtAllocateVirtualMemory syscall_direct <path>temp.obj 1
Why is this happend and how can i fix it ?
As others mentioned, in C++
, names are mangled to support function overloading, while in C
, names are not mangled. You can resolve this issue by using extern "C"
for the declaration of wNtAllocateVirtualMemory
to ensure it has C
linkage.
#include <Windows.h>
#include <stdio.h>
extern "C" DWORD wNtAllocateVirtualMemory;
typedef long NTSTATUS;
typedef NTSTATUS* PNTSTATUS;
extern "C" {
NTSTATUS NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, ULONG_PTR ZeroBits, PSIZE_T RegionSize, ULONG AllocationType, ULONG Protect);
}
int main() {
PVOID allocBuffer = NULL;
SIZE_T buffSize = 0x1000;
HANDLE hNtdll = GetModuleHandleA("ntdll");
if (hNtdll == NULL) {
perror("Fail to get handle");
return 0;
}
PVOID pNtAllocateVirtualMemory = GetProcAddress((HMODULE)hNtdll, "NtAllocateVirtualMemory");
wNtAllocateVirtualMemory = *((char*)pNtAllocateVirtualMemory + 4);
NtAllocateVirtualMemory((HANDLE)-1, (PVOID*)&allocBuffer, (ULONG_PTR)0, &buffSize, (ULONG)(MEM_COMMIT | MEM_RESERVE), PAGE_EXECUTE_READWRITE);
}