36BOOL haveLoadedFunctionsForFork(
void);
44 UCHAR ObjectTypeNumber;
48 ACCESS_MASK GrantedAccess;
57 PVOID SecurityDescriptor;
58 PVOID SecurityQualityOfService;
61typedef enum _MEMORY_INFORMATION_
63 MemoryBasicInformation,
66 MemoryBasicVlmInformation
67} MEMORY_INFORMATION_CLASS;
78 PVOID FixedStackLimit;
79 PVOID ExpandableStackBase;
80 PVOID ExpandableStackLimit;
81 PVOID ExpandableStackBottom;
84typedef LONG KPRIORITY;
85typedef ULONG_PTR KAFFINITY;
86typedef KAFFINITY *PKAFFINITY;
93 KAFFINITY AffinityMask;
95 KPRIORITY BasePriority;
98typedef enum _SYSTEM_INFORMATION_CLASS
100 SystemHandleInformation = 0x10
101} SYSTEM_INFORMATION_CLASS;
103typedef NTSTATUS(NTAPI *ZwWriteVirtualMemory_t)(
104 IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID
Buffer,
105 IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL);
107typedef NTSTATUS(NTAPI *ZwCreateProcess_t)(
108 OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess,
110 IN BOOLEAN InheritHandles, IN HANDLE SectionHandle OPTIONAL,
111 IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL);
113typedef NTSTATUS(WINAPI *ZwQuerySystemInformation_t)(
114 SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation,
115 ULONG SystemInformationLength, PULONG ReturnLength);
116typedef NTSTATUS(NTAPI *ZwQueryVirtualMemory_t)(
117 IN HANDLE ProcessHandle, IN PVOID BaseAddress,
118 IN MEMORY_INFORMATION_CLASS MemoryInformationClass,
119 OUT PVOID MemoryInformation, IN ULONG MemoryInformationLength,
120 OUT PULONG ReturnLength OPTIONAL);
122typedef NTSTATUS(NTAPI *ZwGetContextThread_t)(IN HANDLE ThreadHandle,
123 OUT PCONTEXT Context);
124typedef NTSTATUS(NTAPI *ZwCreateThread_t)(
125 OUT PHANDLE ThreadHandle, IN ACCESS_MASK DesiredAccess,
127 OUT
PCLIENT_ID ClientId, IN PCONTEXT ThreadContext,
128 IN
PUSER_STACK UserStack, IN BOOLEAN CreateSuspended);
130typedef NTSTATUS(NTAPI *ZwResumeThread_t)(IN HANDLE ThreadHandle,
131 OUT PULONG SuspendCount OPTIONAL);
132typedef NTSTATUS(NTAPI *ZwClose_t)(IN HANDLE ObjectHandle);
133typedef NTSTATUS(NTAPI *ZwQueryInformationThread_t)(
134 IN HANDLE ThreadHandle, IN THREAD_INFORMATION_CLASS ThreadInformationClass,
135 OUT PVOID ThreadInformation, IN ULONG ThreadInformationLength,
136 OUT PULONG ReturnLength OPTIONAL);
138static ZwCreateProcess_t ZwCreateProcess = NULL;
139static ZwQuerySystemInformation_t ZwQuerySystemInformation = NULL;
140static ZwQueryVirtualMemory_t ZwQueryVirtualMemory = NULL;
141static ZwCreateThread_t ZwCreateThread = NULL;
142static ZwGetContextThread_t ZwGetContextThread = NULL;
143static ZwResumeThread_t ZwResumeThread = NULL;
144static ZwClose_t ZwClose = NULL;
145static ZwQueryInformationThread_t ZwQueryInformationThread = NULL;
146static ZwWriteVirtualMemory_t ZwWriteVirtualMemory = NULL;
148#define NtCurrentProcess() ((HANDLE)-1)
149#define NtCurrentThread() ((HANDLE)-2)
151#define ZwCurrentProcess() NtCurrentProcess()
152#define ZwCurrentThread() NtCurrentThread()
153#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
154#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
160static int child_entry(
void)
166static BOOL haveLoadedFunctionsForFork(
void)
168 HMODULE ntdll = GetModuleHandle(
"ntdll");
174 if (ZwCreateProcess && ZwQuerySystemInformation && ZwQueryVirtualMemory &&
175 ZwCreateThread && ZwGetContextThread && ZwResumeThread &&
176 ZwQueryInformationThread && ZwWriteVirtualMemory && ZwClose)
182 (ZwCreateProcess_t)GetProcAddress(ntdll,
"ZwCreateProcess");
183 ZwQuerySystemInformation = (ZwQuerySystemInformation_t)GetProcAddress(
184 ntdll,
"ZwQuerySystemInformation");
185 ZwQueryVirtualMemory =
186 (ZwQueryVirtualMemory_t)GetProcAddress(ntdll,
"ZwQueryVirtualMemory");
187 ZwCreateThread = (ZwCreateThread_t)GetProcAddress(ntdll,
"ZwCreateThread");
189 (ZwGetContextThread_t)GetProcAddress(ntdll,
"ZwGetContextThread");
190 ZwResumeThread = (ZwResumeThread_t)GetProcAddress(ntdll,
"ZwResumeThread");
191 ZwQueryInformationThread = (ZwQueryInformationThread_t)GetProcAddress(
192 ntdll,
"ZwQueryInformationThread");
193 ZwWriteVirtualMemory =
194 (ZwWriteVirtualMemory_t)GetProcAddress(ntdll,
"ZwWriteVirtualMemory");
195 ZwClose = (ZwClose_t)GetProcAddress(ntdll,
"ZwClose");
197 if (ZwCreateProcess && ZwQuerySystemInformation && ZwQueryVirtualMemory &&
198 ZwCreateThread && ZwGetContextThread && ZwResumeThread &&
199 ZwQueryInformationThread && ZwWriteVirtualMemory && ZwClose)
205 ZwCreateProcess = NULL;
206 ZwQuerySystemInformation = NULL;
207 ZwQueryVirtualMemory = NULL;
208 ZwCreateThread = NULL;
209 ZwGetContextThread = NULL;
210 ZwResumeThread = NULL;
211 ZwQueryInformationThread = NULL;
212 ZwWriteVirtualMemory = NULL;
220 HANDLE hProcess = 0, hThread = 0;
222 MEMORY_BASIC_INFORMATION mbi;
228 CONTEXT context = {CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS |
229 CONTEXT_FLOATING_POINT};
231 if (setjmp(jenv) != 0)
238 if (!ZwCreateProcess && !haveLoadedFunctionsForFork())
244 ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, &oa, NtCurrentProcess(),
248 ZwGetContextThread(NtCurrentThread(), &context);
254 context.Rip = (ULONG)child_entry;
256 context.Eip = (ULONG)child_entry;
260 ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Rsp,
261 MemoryBasicInformation, &mbi,
sizeof mbi, 0);
263 ZwQueryVirtualMemory(NtCurrentProcess(), (PVOID)context.Esp,
264 MemoryBasicInformation, &mbi,
sizeof mbi, 0);
267 stack.FixedStackBase = 0;
268 stack.FixedStackLimit = 0;
269 stack.ExpandableStackBase = (PCHAR)mbi.BaseAddress + mbi.RegionSize;
270 stack.ExpandableStackLimit = mbi.BaseAddress;
271 stack.ExpandableStackBottom = mbi.AllocationBase;
274 ZwCreateThread(&hThread, THREAD_ALL_ACCESS, &oa, hProcess, &cid, &context,
278 ZwQueryInformationThread(NtCurrentThread(), ThreadMemoryPriority, &tbi,
280 tib = (PNT_TIB)tbi.TebBaseAddress;
281 ZwQueryInformationThread(hThread, ThreadMemoryPriority, &tbi,
sizeof tbi,
283 ZwWriteVirtualMemory(hProcess, tbi.TebBaseAddress, &tib->ExceptionList,
284 sizeof tib->ExceptionList, 0);
287 ZwResumeThread(hThread, 0);
294 return (
int)cid.UniqueProcess;
struct buffer Buffer
struct used to store character in certain times