291 lines
6.8 KiB
C
291 lines
6.8 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;
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|