通过 VirtualAlloc Win32 API 进行内存分配工作顺利,但是,尝试按如下方式进行直接系统调用会导致 0xc0000005 错误 (STATUS_ACCESS_VIOLATION)。
代码如下:
逃避.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
extern "C" NTSTATUS myNtAllocateVirtualMemory(
HANDLE ProcessHandle,
PVOID *BaseAddress,
ULONG ZeroBits,
PULONG RegionSize,
ULONG AllocationType,
ULONG Protect
);
int main(int argc, char* argv[])
{
LPVOID rb;
NTSTATUS res = myNtAllocateVirtualMemory(GetCurrentProcess(), &rb, 0, (PULONG)0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
printf("STATUS: %x\n", res);
return 0;
}
系统调用.asm:
section .text
global myNtAllocateVirtualMemory
myNtAllocateVirtualMemory:
mov r10, rcx
mov eax, 18h
syscall
ret
在 Linux for Windows 10 x86-64 上编译如下:
nasm -f win64 -o syscall.o syscall.asm
x86_64-w64-mingw32-g++ -m64 -c evasion.c -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -Wall -shared -fpermissive
x86_64-w64-mingw32-gcc evasion.o syscall.o -o evasion.exe
任何建议都非常欢迎!
正如@Luke和@OldBoy在评论中所述,RegionSize参数应该是指向该值的指针。正如 @TedLyngmo 提到的:BaseAddress 指针应该初始化为 NULL;
相应地调整这两个变量就可以了。
这是工作代码:
...
ULONG regionsize = 0x1000;
int main(int argc, char* argv[])
{
LPVOID rb = NULL;
NTSTATUS res = myNtAllocateVirtualMemory(GetCurrentProcess(), &rb, 0, ®ionsize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
...
}
感谢你们的帮助,伙计们。抱歉,C 不是我的主要语言。