extern "C" {
#define NTAPI __stdcall
typedef struct _PEB *PPEB;
#define PAGE_SIZE 0x1000
typedef LONG NTSTATUS;
#define DECLSPEC_IMPORT __declspec(dllimport)
#define NTSYSAPI DECLSPEC_IMPORT
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
typedef CLIENT_ID *PCLIENT_ID;
typedef struct _PORT_MESSAGE {
USHORT DataSize;
USHORT MessageSize;
USHORT MessageType;
USHORT VirtualRangesOffset;
CLIENT_ID ClientId;
ULONG MessageId;
ULONG SectionSize;
// UCHAR Data[];
} PORT_MESSAGE, *PPORT_MESSAGE;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
// typedef struct _UNICODE_STRING {
// USHORT Length;
// USHORT MaximumLength;
// #ifdef MIDL_PASS
// [size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT * Buffer;
// #else // MIDL_PASS
// PWSTR Buffer;
// #endif // MIDL_PASS
// } UNICODE_STRING;
// typedef UNICODE_STRING *PUNICODE_STRING;
typedef struct _PROCESS_PARAMETERS {
ULONG AllocationSize;
ULONG Size;
ULONG Flags;
ULONG Zero;
LONG Console;
ULONG ProcessGroup;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
UNICODE_STRING CurrentDirectoryName;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImageFile;
UNICODE_STRING CommandLine;
PWSTR Environment;
ULONG dwX;
ULONG dwY;
ULONG dwXSize;
ULONG dwYSize;
ULONG dwXCountChars;
ULONG dwYCountChars;
ULONG dwFillAttribute;
ULONG dwFlags;
ULONG wShowWindow;
UNICODE_STRING WindowTitle;
UNICODE_STRING Desktop;
UNICODE_STRING Reserved;
UNICODE_STRING Reserved2;
} PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_VALID_ATTRIBUTES 0x000003F2L
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
PUNICODE_STRING ObjectName;
ULONG Attributes;
PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef unsigned long ULONG_PTR, *PULONG_PTR;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
typedef struct _SECTION_IMAGE_INFORMATION { // Information Class 1
PVOID EntryPoint;
ULONG Unknown1;
ULONG StackReserve;
ULONG StackCommit;
ULONG Subsystem;
USHORT MinorSubsystemVersion;
USHORT MajorSubsystemVersion;
ULONG Unknown2;
ULONG Characteristics;
USHORT ImageNumber;
BOOLEAN Executable;
UCHAR Unknown3;
ULONG Unknown4[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
typedef enum _SECTION_INFORMATION_CLASS {
SectionBasicInformation,
SectionImageInformation
} SECTION_INFORMATION_CLASS;
typedef struct _USER_STACK {
PVOID FixedStackBase;
PVOID FixedStackLimit;
PVOID ExpandableStackBase;
PVOID ExpandableStackLimit;
PVOID ExpandableStackBottom;
} USER_STACK, *PUSER_STACK;
typedef LONG KPRIORITY;
typedef struct _PROCESS_BASIC_INFORMATION {
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
ULONG_PTR AffinityMask;
KPRIORITY BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION;
typedef PROCESS_BASIC_INFORMATION *PPROCESS_BASIC_INFORMATION;
typedef enum _PROCESSINFOCLASS {
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
MaxProcessInfoClass
} PROCESSINFOCLASS;
#define InitializeObjectAttributes(p, n, a, r, s){ \
(p)->Length = sizeof(OBJECT_ATTRIBUTES) ; \
(p)->RootDirectory = r; \
(p)->Attributes = a; \
(p)->ObjectName = n; \
(p)->SecurityDescriptor = s; \
(p)->SecurityQualityOfService = NULL; \
}
#define FILE_OPEN 0x00000001
#define DIRECTORY_QUERY (0x0001)
typedef NTSTATUS
(
NTAPI *
fnCsrClientCallServer)
(
IN PVOID Message,
IN PVOID,
IN ULONG Opcode,
IN ULONG Size);
fnCsrClientCallServer CsrClientCallServer;
typedef NTSYSAPI
NTSTATUS
(
NTAPI *
fnZwAllocateVirtualMemory)
(
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG AllocationSize,
IN ULONG AllocationType,
IN ULONG Protect);
fnZwAllocateVirtualMemory ZwAllocateVirtualMemory;
typedef NTSYSAPI
NTSTATUS
(
NTAPI *
fnZwWriteVirtualMemory)
(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG BufferLength,
OUT PULONG ReturnLength OPTIONAL);
fnZwWriteVirtualMemory ZwWriteVirtualMemory;
typedef NTSTATUS
(
NTAPI *
fnRtlCreateProcessParameters)
(
OUT PPROCESS_PARAMETERS *ProcessParameters,
IN PUNICODE_STRING ImageFile,
IN PUNICODE_STRING DllPath OPTIONAL,
IN PUNICODE_STRING CurrentDirectory OPTIONAL,
IN PUNICODE_STRING CommandLine OPTIONAL,
IN ULONG CreationFlags,
IN PUNICODE_STRING WindowTitle OPTIONAL,
IN PUNICODE_STRING Desktop OPTIONAL,
IN PUNICODE_STRING Reserved OPTIONAL,
IN PUNICODE_STRING Reserved2 OPTIONAL);
fnRtlCreateProcessParameters RtlCreateProcessParameters;
typedef NTSTATUS
(
NTAPI *
fnRtlDestroyProcessParameters)
(
IN PPROCESS_PARAMETERS ProcessParameters);
fnRtlDestroyProcessParameters RtlDestroyProcessParameters;
typedef NTSYSAPI
NTSTATUS
(
NTAPI *
fnZwOpenFile)
(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG ShareAccess,
IN ULONG OpenOptions);
fnZwOpenFile ZwOpenFile;
typedef NTSYSAPI
NTSTATUS
(
NTAPI *
fnZwDeleteFile)
(
IN POBJECT_ATTRIBUTES ObjectAttributes);
fnZwDeleteFile ZwDeleteFile;
typedef NTSYSAPI
NTSTATUS
(
NTAPI *
fnZwCreateSection)
(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PLARGE_INTEGER SectionSize OPTIONAL,
IN ULONG Protect,
IN ULONG Attributes,
IN HANDLE FileHandle);
fnZwCreateSection ZwCreateSection;
typedef NTSYSAPI
NTSTATUS
(
NTAPI *
fnZwClose)
(
IN HANDLE Handle);
fnZwClose ZwClose;
typedef NTSYSAPI NTSTATUS
( NTAPI *
fnZwCreateProcess)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN HANDLE InheritFromProcessHandle,
IN BOOLEAN InheritHandles,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL);
fnZwCreateProcess ZwCreateProcess;
#define NtCurrentProcess() ((HANDLE)-1)
typedef NTSYSAPI NTSTATUS (NTAPI *fnZwQuerySection)(
IN HANDLE SectionHandle,
IN SECTION_INFORMATION_CLASS SectionInformationClass,
OUT PVOID SectionInformation,
IN ULONG SectionInformationLength,
OUT PULONG ResultLength OPTIONAL);
fnZwQuerySection ZwQuerySection;
typedef NTSYSAPI NTSTATUS (NTAPI *fnZwProtectVirtualMemory)(
IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN OUT PULONG ProtectSize,
IN ULONG NewProtect,
OUT PULONG OldProtect);
fnZwProtectVirtualMemory ZwProtectVirtualMemory;
typedef NTSYSAPI NTSTATUS (NTAPI *fnZwCreateThread)(
OUT PHANDLE ThreadHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN HANDLE ProcessHandle,
OUT PCLIENT_ID ClientId,
IN PCONTEXT ThreadContext,
IN PUSER_STACK UserStack,
IN BOOLEAN CreateSuspended);
fnZwCreateThread ZwCreateThread;
typedef NTSYSAPI NTSTATUS (NTAPI *fnZwQueryInformationProcess)(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);
fnZwQueryInformationProcess ZwQueryInformationProcess;
typedef NTSTATUS(NTAPI *fnZwResumeThread)(
IN HANDLE ThreadHandle,
OUT PULONG SuspendCount OPTIONAL);
fnZwResumeThread ZwResumeThread;
typedef NTSYSAPI
VOID
(
NTAPI *
fnRtlInitUnicodeString)
(
PUNICODE_STRING DestinationString,
PCWSTR SourceString);
fnRtlInitUnicodeString RtlInitUnicodeString;
typedef NTSYSAPI
NTSTATUS
(
NTAPI *
fnZwCreateFile)
(
OUT PHANDLE FileHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PLARGE_INTEGER AllocationSize OPTIONAL,
IN ULONG FileAttributes,
IN ULONG ShareAccess,
IN ULONG CreateDisposition,
IN ULONG CreateOptions,
IN PVOID EaBuffer OPTIONAL,
IN ULONG EaLength);
fnZwCreateFile ZwCreateFile;
}
VOID InformCsrss(HANDLE hProcess, HANDLE hThread, ULONG pid, ULONG tid)
{
struct CSRSS_MESSAGE {
ULONG Unknown1;
ULONG Opcode;
ULONG Status;
ULONG Unknown2;
};
struct {
PORT_MESSAGE PortMessage;
CSRSS_MESSAGE CsrssMessage;
PROCESS_INFORMATION ProcessInformation;
CLIENT_ID Debugger;
ULONG CreationFlags;
ULONG VdmInfo[2];
} csrmsg = { { 0 }, { 0 }, { hProcess, hThread, pid, tid }, { 0 }, 0, { 0 } };
CsrClientCallServer(&csrmsg, 0, 0x10000, 0x24);
}
PWSTR CopyEnvironment(HANDLE hProcess)
{
PWSTR env = GetEnvironmentStringsW();
ULONG n;
for (n = 0; env[n] != 0; n += wcslen(env + n) + 1); n *= sizeof *env;
ULONG m = n;
PVOID p = 0;
ZwAllocateVirtualMemory(hProcess, &p, 0, &m, MEM_COMMIT, PAGE_READWRITE);
ZwWriteVirtualMemory(hProcess, p, env, n, 0);
return PWSTR(p);
}
VOID CreateProcessParameters(HANDLE hProcess, PPEB Peb, PUNICODE_STRING ImageFile)
{
PPROCESS_PARAMETERS pp;
RtlCreateProcessParameters(&pp, ImageFile, 0, 0, 0, 0, 0, 0, 0, 0);
pp->Environment = CopyEnvironment(hProcess);
ULONG n = pp->Size;
PVOID p = 0;
ZwAllocateVirtualMemory(hProcess, &p, 0, &n, MEM_COMMIT, PAGE_READWRITE);
ZwWriteVirtualMemory(hProcess, p, pp, pp->Size, 0);
ZwWriteVirtualMemory(hProcess, PCHAR(Peb) + 0x10, &p, sizeof p, 0);
RtlDestroyProcessParameters(pp);
}
int exec(PUNICODE_STRING name, PWSTR param)
{
//
PWSTR tmp;
HANDLE hProcess, hThread, hSection, hFile;
OBJECT_ATTRIBUTES oa;
RtlZeroMemory(&oa, sizeof(OBJECT_ATTRIBUTES));
InitializeObjectAttributes(&oa, name, OBJ_CASE_INSENSITIVE, 0, NULL);
IO_STATUS_BLOCK iosb;
NTSTATUS ret = ZwOpenFile(&hFile, FILE_READ_DATA | FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb,
FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
oa.ObjectName = 0;
ret = ZwCreateSection(&hSection, SECTION_ALL_ACCESS, 0, 0, PAGE_EXECUTE, SEC_IMAGE, hFile);
ret = ZwClose(hFile);
HANDLE hep = OpenProcess(PROCESS_ALL_ACCESS, 0, wcstol(param, &tmp, 10));
ret = ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, 0,
hep, TRUE, hSection, 0, 0);
CloseHandle(hep);
SECTION_IMAGE_INFORMATION sii;
ret = ZwQuerySection(hSection, SectionImageInformation, &sii, sizeof sii, 0);
ret = ZwClose(hSection);
USER_STACK stack = { 0 };
ULONG n = sii.StackReserve;
ret = ZwAllocateVirtualMemory(hProcess, &stack.ExpandableStackBottom, 0, &n,
MEM_RESERVE, PAGE_READWRITE);
stack.ExpandableStackBase = PCHAR(stack.ExpandableStackBottom) + sii.StackReserve;
stack.ExpandableStackLimit = PCHAR(stack.ExpandableStackBase) - sii.StackCommit;
n = sii.StackCommit + PAGE_SIZE;
PVOID p = PCHAR(stack.ExpandableStackBase) - n;
ret = ZwAllocateVirtualMemory(hProcess, &p, 0, &n, MEM_COMMIT, PAGE_READWRITE);
ULONG x; n = PAGE_SIZE;
ret = ZwProtectVirtualMemory(hProcess, &p, &n, PAGE_READWRITE | PAGE_GUARD, &x);
CONTEXT context = { CONTEXT_FULL };
context.SegGs = 0;
context.SegFs = 0x38;
context.SegEs = 0x20;
context.SegDs = 0x20;
context.SegSs = 0x20;
context.SegCs = 0x18;
context.EFlags = 0x3000;
context.Esp = ULONG(stack.ExpandableStackBase) - 4;
context.Eip = ULONG(sii.EntryPoint);
CLIENT_ID cid;
ret = ZwCreateThread(&hThread, THREAD_ALL_ACCESS, 0, hProcess, &cid, &context, &stack, TRUE);
PROCESS_BASIC_INFORMATION pbi;
ret = ZwQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof pbi, 0);
CreateProcessParameters(hProcess, pbi.PebBaseAddress, name);
InformCsrss(hProcess, hThread, ULONG(cid.UniqueProcess), ULONG(cid.UniqueThread));
ret = ZwResumeThread(hThread, 0);
ret = ZwClose(hProcess);
ret = ZwClose(hThread);
return int(cid.UniqueProcess);
}
HMODULE ntdll = LoadLibrary("ntdll.dll");
if (ntdll == NULL) return 0;
ZwResumeThread = (fnZwResumeThread)GetProcAddress(ntdll, "ZwResumeThread");
CsrClientCallServer = (fnCsrClientCallServer)GetProcAddress(ntdll, "CsrClientCallServer");
ZwAllocateVirtualMemory = (fnZwAllocateVirtualMemory)GetProcAddress(ntdll, "ZwAllocateVirtualMemory");
ZwWriteVirtualMemory = (fnZwWriteVirtualMemory)GetProcAddress(ntdll, "ZwWriteVirtualMemory");
RtlCreateProcessParameters = (fnRtlCreateProcessParameters)GetProcAddress(ntdll, "RtlCreateProcessParameters");
RtlDestroyProcessParameters = (fnRtlDestroyProcessParameters)GetProcAddress(ntdll, "RtlDestroyProcessParameters");
ZwOpenFile = (fnZwOpenFile)GetProcAddress(ntdll, "ZwOpenFile");
ZwDeleteFile = (fnZwDeleteFile)GetProcAddress(ntdll, "ZwDeleteFile");
ZwCreateSection = (fnZwCreateSection)GetProcAddress(ntdll, "ZwCreateSection");
ZwClose = (fnZwClose)GetProcAddress(ntdll, "ZwClose");
ZwCreateProcess = (fnZwCreateProcess)GetProcAddress(ntdll, "ZwCreateProcess");
ZwQuerySection = (fnZwQuerySection)GetProcAddress(ntdll, "ZwQuerySection");
ZwProtectVirtualMemory = (fnZwProtectVirtualMemory)GetProcAddress(ntdll, "ZwProtectVirtualMemory");
ZwCreateThread = (fnZwCreateThread)GetProcAddress(ntdll, "ZwCreateThread");
ZwQueryInformationProcess = (fnZwQueryInformationProcess)GetProcAddress(ntdll, "ZwQueryInformationProcess");
ZwResumeThread = (fnZwResumeThread)GetProcAddress(ntdll, "ZwResumeThread");
RtlInitUnicodeString = (fnRtlInitUnicodeString)GetProcAddress(ntdll, "RtlInitUnicodeString");
ZwCreateFile = (fnZwCreateFile)GetProcAddress(ntdll, "ZwCreateFile");
// ppp.exe \ ? ? \c : \qqq.exe ***
UNICODE_STRING ImageFile;
RtlInitUnicodeString(&ImageFile, L"\\??\\F:\\Windows\\System32\\notepad.exe");
exec(&ImageFile, L"2928");