Windows2003-3790/sdktools/vmtests/tfork.c
2020-09-30 16:53:55 +02:00

291 lines
7.1 KiB
C

#include <nt.h>
#include <ntrtl.h>
#include <stdio.h>
ULONG ProcessNumber = 1;
#define DbgPrint printf
ULONG
fork ();
__cdecl
main(
)
{
LONG i, j;
PULONG p4, p3, p2, p1, Ro3, Noaccess;
SIZE_T Size1, Size2, Size3, SizeRo3, SizeNoaccess;
NTSTATUS status;
HANDLE CurrentProcessHandle;
ULONG id = 0;
ULONG OldProtect;
CurrentProcessHandle = NtCurrentProcess();
for(i=0;i<3;i++){
DbgPrint("Hello World...\n\n");
}
DbgPrint("allocating virtual memory\n");
p1 = (PULONG)NULL;
Size1 = 30 * 4096;
status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1,
0, &Size1, MEM_COMMIT, PAGE_READWRITE);
DbgPrint("created vm1 status %X start %p size %lx\n",
status, p1, Size1);
p2 = (PULONG)NULL;
Size2 = 16 * 4096;
status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2,
0, &Size2, MEM_COMMIT, PAGE_READWRITE);
DbgPrint("created vm2 status %X start %p size %lx\n",
status, p2, Size2);
id = fork () + id;
DbgPrint("fork complete id %lx\n",id);
p3 = p1 + 8 * 1024;
Size3 = 16 * 4096;
DbgPrint("deleting va from %p for %lx bytes\n",p3, Size3);
status = NtFreeVirtualMemory (CurrentProcessHandle,(PVOID *)&p3, &Size3,
MEM_RELEASE);
DbgPrint("free vm status %X start %p size %lx\n",
status, p3, Size3);
p3 = (PULONG)NULL;
Size3 = 50 * 4096;
DbgPrint("allocating 50 pages of vm\n");
status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p3,
0, &Size3, MEM_COMMIT, PAGE_READWRITE);
DbgPrint("created vm3 status %X start %p size %lx\n",
status, p3, Size3);
Ro3 = (PULONG)NULL;
SizeRo3 = 393933;
status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&Ro3,
0, &SizeRo3, MEM_COMMIT, PAGE_READONLY);
DbgPrint("created vm4 status %X start %p size %lx\n",
status, Ro3, SizeRo3);
*p3 = *Ro3;
p1 = p3;
p2 = ((PULONG)((PUCHAR)p3 + Size3));
p4 = p1;
j = 0;
while (p3 < p2) {
j += 1;
if (j % 8 == 0) {
if (*p4 != (ULONG)((ULONG_PTR)p4)) {
DbgPrint("bad value in cell %p value is %lx\n",p4, *p4);
}
p4 += 1;
*p4 = (ULONG)((ULONG_PTR)p4);
p4 = p4 + 1026;
}
*p3 = (ULONG)((ULONG_PTR)p3);
p3 += 1027;
}
p3 = p1;
//
// Protect page as no access.
//
Noaccess = NULL;
SizeNoaccess = 200*4096;
status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&Noaccess,
0, &SizeNoaccess, MEM_COMMIT, PAGE_READWRITE);
DbgPrint("created vm5 status %X start %p size %lx\n",
status, Ro3, SizeRo3);
//
// Touch all the pages.
//
RtlZeroMemory(Noaccess, SizeNoaccess);
*Noaccess = 91;
Size1 = 30 * 4097;
status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&Noaccess,
&Size1, PAGE_NOACCESS,
&OldProtect);
DbgPrint("protected VM1 status %X, base %p, size %lx, old protect %lx\n",
status, p1, Size1, OldProtect);
DbgPrint("forking a second time\n");
id = fork () + id;
DbgPrint("fork2 complete id %lx\n",id);
DbgPrint("changing page protection\n");
Size1 = 9000;
OldProtect = *p3;
status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p3,
&Size1, PAGE_EXECUTE_READWRITE | PAGE_NOCACHE,
&OldProtect);
DbgPrint("protected VM2 status %X, base %p, size %lx, old protect %lx\n",
status, p1, Size1, OldProtect);
status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&Ro3,
&Size1, PAGE_READONLY | PAGE_NOCACHE, &OldProtect);
DbgPrint("protected VM3 status %X, base %p, size %lx, old protect %lx\n",
status, Ro3, Size1, OldProtect);
p1 += 1;
while (p3 < p2) {
*p1 = (ULONG)((ULONG_PTR)p1);
if (*p3 != (ULONG)((ULONG_PTR)p3)) {
DbgPrint("bad value in cell %p value is %lx\n",p3, *p3);
}
p3 += 1027;
p1 += 1027;
}
DbgPrint("trying noaccess test\n");
try {
if (*Noaccess != 91) {
DbgPrint("*************** FAILED NOACCESS TEST 1 *************\n");
}
} except (EXCEPTION_EXECUTE_HANDLER) {
if (GetExceptionCode() != STATUS_ACCESS_VIOLATION) {
DbgPrint("*************** FAILED NOACCESS TEST 2 *************\n");
}
}
//
// Make no access page accessable.
//
status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&Noaccess,
&Size1, PAGE_READWRITE,
&OldProtect);
if (*Noaccess != 91) {
DbgPrint("*************** FAILED NOACCESS TEST 3 *************\n");
}
DbgPrint("that's all process %lx\n", id);
NtTerminateProcess(NtCurrentProcess(),STATUS_SUCCESS);
return 0;
}
ULONG
fork ()
{
LONG i;
PULONG Foo;
NTSTATUS status;
HANDLE CurrentProcessHandle;
HANDLE ProcessHandle;
CONTEXT ThreadContext;
CLIENT_ID Cid1;
HANDLE Thread1;
LARGE_INTEGER DelayTime;
PINITIAL_TEB Teb;
CurrentProcessHandle = NtCurrentProcess();
DbgPrint("creating new process\n");
status = NtCreateProcess(
&ProcessHandle,
PROCESS_ALL_ACCESS, //DesiredAccess,
NULL, //ObjectAttributes,
CurrentProcessHandle, //ParentProcess
TRUE, //InheritObjectTable,
NULL, //SectionHandle
NULL, //DebugPort OPTIONAL,
NULL //ExceptionPort OPTIONAL
);
DbgPrint("status from create process %lx\n",status);
if (!NT_SUCCESS(status)) {
return 0;
}
ThreadContext.ContextFlags = CONTEXT_FULL;
status = NtGetContextThread (NtCurrentThread(), &ThreadContext);
DbgPrint("status from get context %lx\n",status);
if (status == 0) {
#ifdef i386
ThreadContext.Eax = 0x7777;
ThreadContext.Esp -= 0x18;
Foo = (PULONG)ThreadContext.Esp;
DbgPrint("stack value is %lx\n",*Foo);
#endif
Teb= (PINITIAL_TEB) NtCurrentTeb ();
status = NtCreateThread(
&Thread1,
THREAD_ALL_ACCESS,
NULL,
ProcessHandle,
&Cid1,
&ThreadContext,
Teb,
FALSE
);
// DelayTime.HighPart = -1;
// DelayTime.LowPart = 0;
// NtDelayExecution (FALSE, &DelayTime);
return 0;
} else {
ProcessNumber += ProcessNumber;
return ProcessNumber;
}
}