/*********************************************************************** * VirtualProtectEx (KERNEL32.@) * * Changes the access protection on a region of committed pages in the * virtual address space of a specified process. * * PARAMS * process [I] Handle of process. * addr [I] Address of region of committed pages. * size [I] Size of region. * new_prot [I] Desired access protection. * old_prot [O] Address of variable to get old protection. * * RETURNS * Success: TRUE. * Failure: FALSE. */ BOOL WINAPI VirtualProtectEx( HANDLE process, LPVOID addr, SIZE_T size, DWORD new_prot, LPDWORD old_prot ) { NTSTATUS status = NtProtectVirtualMemory( process, &addr, &size, new_prot, old_prot ); if (status) SetLastError( RtlNtStatusToDosError(status) ); return !status; }
LONG WINAPI BasepCheckForReadOnlyResource(IN PVOID Ptr) { PVOID Data; ULONG Size, OldProtect; SIZE_T Size2; MEMORY_BASIC_INFORMATION mbi; NTSTATUS Status; LONG Ret = EXCEPTION_CONTINUE_SEARCH; /* Check if it was an attempt to write to a read-only image section! */ Status = NtQueryVirtualMemory(NtCurrentProcess(), Ptr, MemoryBasicInformation, &mbi, sizeof(mbi), NULL); if (NT_SUCCESS(Status) && mbi.Protect == PAGE_READONLY && mbi.Type == MEM_IMAGE) { /* Attempt to treat it as a resource section. We need to use SEH here because we don't know if it's actually a resource mapping */ _SEH2_TRY { Data = RtlImageDirectoryEntryToData(mbi.AllocationBase, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &Size); if (Data != NULL && (ULONG_PTR)Ptr >= (ULONG_PTR)Data && (ULONG_PTR)Ptr < (ULONG_PTR)Data + Size) { /* The user tried to write into the resources. Make the page writable... */ Size2 = 1; Status = NtProtectVirtualMemory(NtCurrentProcess(), &Ptr, &Size2, PAGE_READWRITE, &OldProtect); if (NT_SUCCESS(Status)) { Ret = EXCEPTION_CONTINUE_EXECUTION; } } } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { } _SEH2_END; }
BOOL engine_UnHookFunctionInProcess(HANDLE hProcess,LPSTR lpModuleName,LPSTR lpFunctionName,LPVOID lpOldFunctionAddress,DWORD dwFunctionSize) { LPVOID lpModule=NULL; LPVOID lpFunction=NULL; MEMORY_BASIC_INFORMATION mbi; CHAR lpLocalStub[MAX_FUNC_LEN*2]; DWORD dwFree=0; DWORD dwBytesWritten; // Get module address lpModule=(LPVOID)engine_GetRemoteModuleHandle(hProcess,lpModuleName); if (!lpModule) return FALSE; // Get function address lpFunction=engine_GetRemoteProcAddress(hProcess,lpModule,lpFunctionName); if (!lpFunction) return FALSE; // Get info about the function address if (!NT_SUCCESS(SafeNtQueryVirtualMemory(hProcess,lpFunction,MemoryBasicInformation,&mbi,sizeof(mbi),NULL))) return FALSE; // Flush instruction cache NtFlushInstructionCache(hProcess,mbi.BaseAddress,mbi.RegionSize); // Change the protection for the region if (!NT_SUCCESS(NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,PAGE_EXECUTE_READWRITE,&mbi.Protect))) return FALSE; // Read old functions instructions if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpOldFunctionAddress,lpLocalStub,dwFunctionSize,NULL))) { // restore protection NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); return FALSE; } // Restore original function if (!NT_SUCCESS(NtWriteVirtualMemory(hProcess,lpFunction,lpLocalStub,dwFunctionSize,&dwBytesWritten))) { // restore protection NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); return FALSE; } // Free stub memory NtFreeVirtualMemory(hProcess,&lpOldFunctionAddress,&dwFree,MEM_RELEASE); // Restore protection NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); return TRUE; }
/*********************************************************************** * VirtualProtectEx (KERNEL32.@) * * Changes the access protection on a region of committed pages in the * virtual address space of a specified process. * * PARAMS * process [I] Handle of process. * addr [I] Address of region of committed pages. * size [I] Size of region. * new_prot [I] Desired access protection. * old_prot [O] Address of variable to get old protection. * * RETURNS * Success: TRUE. * Failure: FALSE. */ BOOL WINAPI VirtualProtectEx( HANDLE process, LPVOID addr, SIZE_T size, DWORD new_prot, LPDWORD old_prot ) { NTSTATUS status; DWORD prot; /* Win9x allows passing NULL as old_prot while this fails on NT */ if (!old_prot && (GetVersion() & 0x80000000)) old_prot = &prot; status = NtProtectVirtualMemory( process, &addr, &size, new_prot, old_prot ); if (status) SetLastError( RtlNtStatusToDosError(status) ); return !status; }
static NTSTATUS NTAPI TerminatorM2( _In_ HANDLE ProcessId ) { NTSTATUS status; HANDLE processHandle; if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION, ProcessId ))) { PVOID baseAddress; MEMORY_BASIC_INFORMATION basicInfo; ULONG oldProtect; baseAddress = (PVOID)0; while (NT_SUCCESS(NtQueryVirtualMemory( processHandle, baseAddress, MemoryBasicInformation, &basicInfo, sizeof(MEMORY_BASIC_INFORMATION), NULL ))) { SIZE_T regionSize; regionSize = basicInfo.RegionSize; NtProtectVirtualMemory( processHandle, &basicInfo.BaseAddress, ®ionSize, PAGE_NOACCESS, &oldProtect ); baseAddress = PTR_ADD_OFFSET(baseAddress, basicInfo.RegionSize); } NtClose(processHandle); } return status; }
// Figure out what combination of protections and states pages in a single allocation // can have. Can protections be mixed? How about states (COMMIT/RESERVE/FREE)? void test_prot_mem( void ) { VOID *address, *a; ULONG size, old; NTSTATUS r; HANDLE handle = (HANDLE) ~0; // allocate 16 pages address = NULL; size = 0x10000; r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_RESERVE, PAGE_NOACCESS ); ok(r == STATUS_SUCCESS, "wrong return code\n"); ok(address != NULL, "address wrong\n"); ok(size == 0x10000, "size wrong\n"); a = address; // try change access immediately size = 0x1000; r = NtProtectVirtualMemory( handle, &address, &size, PAGE_NOACCESS, &old ); ok(r == STATUS_NOT_COMMITTED, "wrong return code (%08lx)\n", r); // commit the page address = a; size = 0x1000; r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_COMMIT, PAGE_NOACCESS ); ok(r == STATUS_SUCCESS, "wrong return code\n"); ok(size == 0x1000, "size wrong\n"); // try change access again address = a; size = 0x1000; r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READONLY, &old ); ok(r == STATUS_SUCCESS, "wrong return code\n"); ok(old == PAGE_NOACCESS, "wrong access\n"); ok(size == 0x1000, "size wrong\n"); // and again address = a; size = 0x1000; r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READWRITE, &old ); ok(r == STATUS_SUCCESS, "wrong return code\n"); ok(old == PAGE_READONLY, "wrong access\n"); ok(size == 0x1000, "size wrong\n"); // change the second page address = a + 0x1000; size = 0x1000; old = 0; r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READWRITE, &old ); ok(r == STATUS_NOT_COMMITTED, "wrong return code (%08lx)\n", r); ok(size == 0x1000, "size wrong\n"); ok(old == PAGE_READONLY, "wrong access\n"); // commit the second page, overlapping with the first page address = a; size = 0x2000; r = NtAllocateVirtualMemory( handle, &address, 0, &size, MEM_COMMIT, PAGE_EXECUTE ); ok(r == STATUS_SUCCESS, "wrong return code\n"); ok(size == 0x2000, "size wrong\n"); ok(old == PAGE_READONLY, "wrong access\n"); // overlaps the next uncommitted page address = a + 0x1000; size = 0x2000; r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READWRITE, &old ); ok(r == STATUS_NOT_COMMITTED, "wrong return code (%08lx)\n", r); ok(size == 0x2000, "size wrong\n"); #ifdef WIN2K ok(old == PAGE_READONLY, "wrong access\n"); #endif // the page we just committed address = a + 0x1000; size = 0x1000; r = NtProtectVirtualMemory( handle, &address, &size, PAGE_READWRITE, &old ); ok(r == STATUS_SUCCESS, "wrong return code (%08lx)\n", r); ok(size == 0x1000, "size wrong\n"); ok(old == PAGE_EXECUTE, "wrong access\n"); // free all the memory address = a; size = 0x10000; r = NtFreeVirtualMemory( handle, &address, &size, MEM_RELEASE ); ok(r == STATUS_SUCCESS, "wrong return code\n"); }
_CRTAPI1 main() { LONG i, j; PULONG p4, p3, p2, p1, Ro3, Noaccess; ULONG 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 %lx size %lx\n", status, (ULONG)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 %lx size %lx\n", status, (ULONG)p2, Size2); id = fork () + id; DbgPrint("fork complete id %lx\n",id); p3 = p1 + 8 * 1024; Size3 = 16 * 4096; DbgPrint("deleting va from %lx for %lx bytes\n",p3, Size3); status = NtFreeVirtualMemory (CurrentProcessHandle,(PVOID *)&p3, &Size3, MEM_RELEASE); DbgPrint("free vm status %X start %lx size %lx\n", status, (ULONG)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 %lx size %lx\n", status, (ULONG)p3, Size3); Ro3 = (PULONG)NULL; SizeRo3 = 393933; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&Ro3, 0, &SizeRo3, MEM_COMMIT, PAGE_READONLY); DbgPrint("created vm4 status %X start %lx size %lx\n", status, (ULONG)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)p4) { DbgPrint("bad value in cell %lx value is %lx\n",p4, *p4); } p4 += 1; *p4 = (ULONG)p4; p4 = p4 + 1026; } *p3 = (ULONG)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 %lx size %lx\n", status, (ULONG)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 %lx, 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 %lx, 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 %lx, size %lx, old protect %lx\n", status, Ro3, Size1, OldProtect); p1 += 1; while (p3 < p2) { *p1 = (ULONG)p1; if (*p3 != (ULONG)p3) { DbgPrint("bad value in cell %lx value is %lx\n",p3, *p3); } p3 += 1027; p1 += 1027; } DbgPrint("trying noacess 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); }
static INT_PTR CALLBACK PhpMemoryProtectDlgProc( _In_ HWND hwndDlg, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { switch (uMsg) { case WM_INITDIALOG: { SetProp(hwndDlg, PhMakeContextAtom(), (HANDLE)lParam); SetDlgItemText(hwndDlg, IDC_INTRO, L"Possible values:\r\n" L"\r\n" L"0x01 - PAGE_NOACCESS\r\n" L"0x02 - PAGE_READONLY\r\n" L"0x04 - PAGE_READWRITE\r\n" L"0x08 - PAGE_WRITECOPY\r\n" L"0x10 - PAGE_EXECUTE\r\n" L"0x20 - PAGE_EXECUTE_READ\r\n" L"0x40 - PAGE_EXECUTE_READWRITE\r\n" L"0x80 - PAGE_EXECUTE_WRITECOPY\r\n" L"Modifiers:\r\n" L"0x100 - PAGE_GUARD\r\n" L"0x200 - PAGE_NOCACHE\r\n" L"0x400 - PAGE_WRITECOMBINE\r\n" ); SetFocus(GetDlgItem(hwndDlg, IDC_VALUE)); } break; case WM_DESTROY: { RemoveProp(hwndDlg, PhMakeContextAtom()); } break; case WM_COMMAND: { switch (LOWORD(wParam)) { case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); break; case IDOK: { NTSTATUS status; PMEMORY_PROTECT_CONTEXT context = (PMEMORY_PROTECT_CONTEXT)GetProp(hwndDlg, PhMakeContextAtom()); HANDLE processHandle; ULONG64 protect; PhStringToInteger64(&PHA_GET_DLGITEM_TEXT(hwndDlg, IDC_VALUE)->sr, 0, &protect); if (NT_SUCCESS(status = PhOpenProcess( &processHandle, PROCESS_VM_OPERATION, context->ProcessItem->ProcessId ))) { PVOID baseAddress; SIZE_T regionSize; ULONG oldProtect; baseAddress = context->MemoryItem->BaseAddress; regionSize = context->MemoryItem->Size; status = NtProtectVirtualMemory( processHandle, &baseAddress, ®ionSize, (ULONG)protect, &oldProtect ); if (NT_SUCCESS(status)) context->MemoryItem->Protection = (ULONG)protect; } if (NT_SUCCESS(status)) { EndDialog(hwndDlg, IDOK); } else { PhShowStatus(hwndDlg, L"Unable to change memory protection", status, 0); SetFocus(GetDlgItem(hwndDlg, IDC_VALUE)); Edit_SetSel(GetDlgItem(hwndDlg, IDC_VALUE), 0, -1); } } break; } } break; } return FALSE; }
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg) { HANDLE hThread; OBJECT_ATTRIBUTES oaThreadAttrs; CLIENT_ID ciId; CONTEXT cxThreadContext; INITIAL_TEB itInitialTeb; BOOLEAN fSuspended; ULONG nOldPageProtection; NTSTATUS nErrCode; /* initialize generic object attributes */ oaThreadAttrs.Length = sizeof(OBJECT_ATTRIBUTES); oaThreadAttrs.RootDirectory = NULL; oaThreadAttrs.ObjectName = NULL; oaThreadAttrs.Attributes = 0; oaThreadAttrs.SecurityDescriptor = NULL; oaThreadAttrs.SecurityQualityOfService = NULL; /* initialize thread attributes */ fSuspended = FALSE; /* FIXME? really needed? can we hardcode this to FALSE? */ /* stack attributes */ FIXME("stack size defaulted to 0x100000 - thread attributes ignored"); /* stack reserve size */ itInitialTeb.StackReserve = 0x100000; /* stack commit size */ itInitialTeb.StackCommit = itInitialTeb.StackReserve - PAGE_SIZE; /* guard page */ itInitialTeb.StackCommit += PAGE_SIZE; /* reserve stack */ itInitialTeb.StackAllocate = NULL; nErrCode = NtAllocateVirtualMemory ( NtCurrentProcess(), &itInitialTeb.StackAllocate, 0, &itInitialTeb.StackReserve, MEM_RESERVE, PAGE_READWRITE ); if(!NT_SUCCESS(nErrCode)) { return (__status_to_errno(nErrCode)); /* FIXME? TODO? pthread specific error codes? */ } itInitialTeb.StackBase = (PVOID)((ULONG)itInitialTeb.StackAllocate + itInitialTeb.StackReserve); itInitialTeb.StackLimit = (PVOID)((ULONG)itInitialTeb.StackBase - itInitialTeb.StackCommit); /* commit stack */ nErrCode = NtAllocateVirtualMemory ( NtCurrentProcess(), &itInitialTeb.StackLimit, 0, &itInitialTeb.StackCommit, MEM_COMMIT, PAGE_READWRITE ); if(!NT_SUCCESS(nErrCode)) { NtFreeVirtualMemory ( NtCurrentProcess(), itInitialTeb.StackAllocate, &itInitialTeb.StackReserve, MEM_RELEASE ); return (__status_to_errno(nErrCode)); } /* protect guard page */ nErrCode = NtProtectVirtualMemory ( NtCurrentProcess(), itInitialTeb.StackLimit, PAGE_SIZE, PAGE_GUARD | PAGE_READWRITE, &nOldPageProtection ); if(!NT_SUCCESS(nErrCode)) { NtFreeVirtualMemory ( NtCurrentProcess(), itInitialTeb.StackAllocate, &itInitialTeb.StackReserve, MEM_RELEASE ); return (__status_to_errno(nErrCode)); } /* initialize thread registers */ //#ifdef __i386__ memset(&cxThreadContext, 0, sizeof(CONTEXT)); cxThreadContext.Eip = (LONG)__threadentry; cxThreadContext.SegGs = USER_DS; cxThreadContext.SegFs = TEB_SELECTOR; cxThreadContext.SegEs = USER_DS; cxThreadContext.SegDs = USER_DS; cxThreadContext.SegCs = USER_CS; cxThreadContext.SegSs = USER_DS; cxThreadContext.Esp = (ULONG)itInitialTeb.StackBase - 12; cxThreadContext.EFlags = (1<<1) + (1<<9); /* initialize call stack */ *((PULONG)((ULONG)itInitialTeb.StackBase - 4)) = (ULONG)arg; /* thread argument */ *((PULONG)((ULONG)itInitialTeb.StackBase - 8)) = (ULONG)start_routine; /* thread start routine */ *((PULONG)((ULONG)itInitialTeb.StackBase - 12)) = 0xDEADBEEF; /* "shouldn't see me" */ //#else //#error Unsupported architecture //#endif INFO("about to create new thread - start routine at %#x, argument %#x", start_routine, arg); /* create thread */ nErrCode = NtCreateThread ( &hThread, THREAD_ALL_ACCESS, &oaThreadAttrs, NtCurrentProcess(), &ciId, &cxThreadContext, &itInitialTeb, fSuspended ); if(!NT_SUCCESS(nErrCode)) { NtFreeVirtualMemory ( NtCurrentProcess(), itInitialTeb.StackAllocate, &itInitialTeb.StackReserve, MEM_RELEASE ); return (__status_to_errno(nErrCode)); } /* FIXME? should we return the thread handle or the thread id? */ if(thread != 0) *thread = (pthread_t)&ciId.UniqueThread; /* for the moment, we return the id */ return (0); }
_CRTAPI1 main() { LONG i, j; PULONG p4, p3, p2, p1, oldp1, vp1; ULONG Size1, Size2, Size3; NTSTATUS status, alstatus; HANDLE CurrentProcessHandle; HANDLE GiantSection; HANDLE Section2, Section4; MEMORY_BASIC_INFORMATION MemInfo; ULONG OldProtect; STRING Name3; HANDLE Section1; OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES Object1Attributes; ULONG ViewSize; LARGE_INTEGER Offset; LARGE_INTEGER SectionSize; UNICODE_STRING Unicode; CurrentProcessHandle = NtCurrentProcess(); DbgPrint(" Memory Management Tests - AllocVm, FreeVm, ProtectVm, QueryVm\n"); p1 = (PULONG)0x20020000; Size1 = 0xbc0000; alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Size1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(alstatus)) { DbgPrint("failed first created vm status %X start %lx size %lx\n", alstatus, (ULONG)p1, Size1); DbgPrint("******** FAILED TEST 1 **************\n"); } status = NtQueryVirtualMemory (CurrentProcessHandle, p1, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 2 **************\n"); DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n", status, p1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } if ((MemInfo.RegionSize != Size1) || (MemInfo.BaseAddress != p1) || (MemInfo.Protect != PAGE_READWRITE) || (MemInfo.Type != MEM_PRIVATE) || (MemInfo.State != MEM_COMMIT)) { DbgPrint("******** FAILED TEST 3 **************\n"); DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n", status, p1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } p2 = (PULONG)NULL; Size2 = 0x100000; alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, 3, &Size2, MEM_TOP_DOWN | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(alstatus)) { DbgPrint("failed first created vm status %lC start %lx size %lx\n", status, (ULONG)p1, Size1); DbgPrint("******** FAILED TEST 3a.1 **************\n"); NtTerminateProcess(NtCurrentProcess(),status); } // // Touch every other page. // vp1 = p2 + 3000; while (vp1 < (PULONG)((PCHAR)p2 + Size2)) { *vp1 = 938; vp1 += 3000; } // // Decommit pages. // Size3 = Size2 - 5044; vp1 = p2 + 3000; status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, &Size3, MEM_DECOMMIT); if (!(NT_SUCCESS(status))) { DbgPrint(" free vm failed - status %lx\n",status); DbgPrint("******** FAILED TEST 3a.4 **************\n"); NtTerminateProcess(NtCurrentProcess(),status); } // // Split the memory block using MEM_RELEASE. // vp1 = p2 + 5000; Size3 = Size2 - 50000; status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&vp1, &Size3, MEM_RELEASE); if (!(NT_SUCCESS(status))) { DbgPrint(" free vm failed - status %lx\n",status); DbgPrint("******** FAILED TEST 3a.b **************\n"); NtTerminateProcess(NtCurrentProcess(),status); } vp1 = p2 + 3000; Size3 = 41; status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&vp1, &Size3, MEM_RELEASE); if (!(NT_SUCCESS(status))) { DbgPrint(" free vm failed - status %lx\n",status); DbgPrint("******** FAILED TEST 3a.5 **************\n"); NtTerminateProcess(NtCurrentProcess(),status); } // // free every page, ignore the status. // vp1 = p2; Size3 = 30; while (vp1 < (PULONG)((PCHAR)p2 + Size2)) { status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&vp1, &Size3, MEM_RELEASE); vp1 += 128; } p2 = (PULONG)NULL; Size2 = 0x10000; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, 3, &Size2, MEM_TOP_DOWN | MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(status)) { DbgPrint("failed first created vm status %X start %lx size %lx\n", status, (ULONG)p1, Size1); DbgPrint("******** FAILED TEST 3.1 **************\n"); } else { if (p2 != (PVOID)0x1fff0000) { DbgPrint("******** FAILED TEST 3.2 **************\n"); DbgPrint("p2 = %lx\n",p2); } status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, &Size2, MEM_RELEASE); if (!(NT_SUCCESS(status))) { DbgPrint(" free vm failed - status %lx\n",status); DbgPrint("******** FAILED TEST 3.3 **************\n"); NtTerminateProcess(NtCurrentProcess(),status); } } if (NT_SUCCESS(alstatus)) { status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Size1, MEM_RELEASE); } if (!(NT_SUCCESS(status))) { DbgPrint(" free vm failed - status %lx\n",status); DbgPrint("******** FAILED TEST 4 **************\n"); NtTerminateProcess(NtCurrentProcess(),status); } p1 = (PULONG)NULL; Size1 = 16 * 4096; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Size1, MEM_RESERVE, PAGE_READWRITE | PAGE_GUARD); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 5 **************\n"); DbgPrint("created vm status %X start %lx size %lx\n", status, (ULONG)p1, Size1); } status = NtQueryVirtualMemory (CurrentProcessHandle, p1, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 6 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, p1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx alloc_protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.AllocationProtect, MemInfo.Type); } if ((MemInfo.RegionSize != Size1) || (MemInfo.BaseAddress != p1) || (MemInfo.AllocationProtect != (PAGE_READWRITE | PAGE_GUARD)) || (MemInfo.Protect != 0) || (MemInfo.Type != MEM_PRIVATE) || (MemInfo.State != MEM_RESERVE)) { DbgPrint("******** FAILED TEST 7 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, p1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx alloc_protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.AllocationProtect, MemInfo.Type); } Size2 = 8192; oldp1 = p1; p1 = p1 + 14336; // 64k -8k /4 status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Size2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 8 **************\n"); DbgPrint("created vm status %X start %lx size %lx\n", status, (ULONG)p1, Size1); } status = NtQueryVirtualMemory (CurrentProcessHandle, oldp1, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 9 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, oldp1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } if ((MemInfo.RegionSize != 56*1024) || (MemInfo.BaseAddress != oldp1) || (MemInfo.AllocationProtect != (PAGE_READWRITE | PAGE_GUARD)) || (MemInfo.Protect != 0) || (MemInfo.Type != MEM_PRIVATE) || (MemInfo.State != MEM_RESERVE)) { DbgPrint("******** FAILED TEST 10 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, oldp1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx alloc_protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.AllocationProtect, MemInfo.Type); } status = NtQueryVirtualMemory (CurrentProcessHandle, p1, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 11 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, p1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } if ((MemInfo.RegionSize != Size2) || (MemInfo.BaseAddress != p1) || (MemInfo.Protect != PAGE_EXECUTE_READWRITE) || (MemInfo.Type != MEM_PRIVATE) || (MemInfo.State != MEM_COMMIT) || (MemInfo.AllocationBase != oldp1)) { DbgPrint("******** FAILED TEST 12 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, oldp1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } Size1 = Size2; status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Size1, PAGE_READONLY | PAGE_NOCACHE, &OldProtect); if ((!NT_SUCCESS(status)) || (OldProtect != PAGE_EXECUTE_READWRITE)) { DbgPrint("******** FAILED TEST 13 **************\n"); DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n", status, p1, Size1, OldProtect); } status = NtQueryVirtualMemory (CurrentProcessHandle, p1, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if ((!NT_SUCCESS(status)) || MemInfo.Protect != (PAGE_NOCACHE | PAGE_READONLY)) { DbgPrint("******** FAILED TEST 14 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, p1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } i = *p1; status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Size1, PAGE_NOACCESS | PAGE_NOCACHE, &OldProtect); if (status != STATUS_INVALID_PAGE_PROTECTION) { DbgPrint("******** FAILED TEST 15 **************\n"); DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n", status, p1, Size1, OldProtect, i); } status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Size1, PAGE_READONLY, &OldProtect); if ((!NT_SUCCESS(status)) || (OldProtect != (PAGE_NOCACHE | PAGE_READONLY))) { DbgPrint("******** FAILED TEST 16 **************\n"); DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n", status, p1, Size1, OldProtect); } status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Size1, PAGE_READWRITE, &OldProtect); if ((!NT_SUCCESS(status)) || (OldProtect != (PAGE_READONLY))) { DbgPrint("******** FAILED TEST 17 **************\n"); DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n", status, p1, Size1, OldProtect); } for (i = 1; i < 12; i++) { p2 = (PULONG)NULL; Size2 = i * 4096; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, 0, &Size2, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 18 **************\n"); DbgPrint("created vm status %X start %lx size %lx\n", status, (ULONG)p2, Size2); } if (i==4) { p3 = p2; } if (i == 8) { Size3 = 12000; status = NtFreeVirtualMemory (CurrentProcessHandle,(PVOID *)&p3, &Size3, MEM_RELEASE); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 19 **************\n"); DbgPrint("free vm status %X start %lx size %lx\n", status, (ULONG)p3, Size3); } } } p3 = p1 + 8 * 1024; status = NtQueryVirtualMemory (CurrentProcessHandle, p3, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 20 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, p3, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } p3 = p1 - 8 * 1024; status = NtQueryVirtualMemory (CurrentProcessHandle, p3, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 21 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, p3, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } Size3 = 16 * 4096; status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, &Size3, MEM_RELEASE); if (status != STATUS_UNABLE_TO_FREE_VM) { DbgPrint("******** FAILED TEST 22 **************\n"); DbgPrint("free vm status %X start %lx size %lx\n", status, (ULONG)p3, Size3); } Size3 = 1 * 4096; status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, &Size3, MEM_RELEASE); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 23 **************\n"); DbgPrint("free vm status %X start %lx size %lx\n", status, (ULONG)p3, Size3); } p3 = (PULONG)NULL; Size3 = 300 * 4096; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p3, 0, &Size3, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 24 **************\n"); DbgPrint("created vm status %X start %lx size %lx\n", status, (ULONG)p3, Size3); } p1 = p3; p2 = ((PULONG)((PUCHAR)p3 + Size3)); p4 = p1; j = 0; while (p3 < p2) { j += 1; if (j % 8 == 0) { if (*p4 != (ULONG)p4) { DbgPrint("bad value in xcell %lx value is %lx\n",p4, *p4); } p4 += 1; *p4 = (ULONG)p4; p4 = p4 + 1026; } *p3 = (ULONG)p3; p3 += 1027; } DbgPrint("checking values\n"); status = NtQueryVirtualMemory (CurrentProcessHandle, p3, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 25 **************\n"); DbgPrint("query vm status %X address %lx Base %lx size %lx\n", status, p3, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } p3 = p1; while (p3 < p2) { if (*p3 != (ULONG)p3) { DbgPrint("bad value in 1cell %lx value is %lx\n",p3, *p3); } p3 += 1027; } p3 = p1; while (p3 < p2) { if (*p3 != (ULONG)p3) { DbgPrint("bad value in 2cell %lx value is %lx\n",p3, *p3); } p3 += 1027; } p3 = p1; while (p3 < p2) { if (*p3 != (ULONG)p3) { DbgPrint("bad value in 3cell %lx value is %lx\n",p3, *p3); } p3 += 1027; } p3 = p1; while (p3 < p2) { if (*p3 != (ULONG)p3) { DbgPrint("bad value in 4cell %lx value is %lx\n",p3, *p3); } p3 += 1027; } p3 = p1; while (p3 < p2) { if (*p3 != (ULONG)p3) { DbgPrint("bad value in 5cell %lx value is %lx\n",p3, *p3); } p3 += 1027; } p3 = p1; while (p3 < p2) { if (*p3 != (ULONG)p3) { DbgPrint("bad value in cell %lx value is %lx\n",p3, *p3); } p3 += 1027; } // // Check physical frame mapping. // // // Check physical frame mapping. // RtlInitAnsiString (&Name3, "\\Device\\PhysicalMemory"); status = RtlAnsiStringToUnicodeString(&Unicode,&Name3,TRUE); if (!NT_SUCCESS(status)) { printf("string conversion failed status %lx\n", status); ExitProcess (status); } InitializeObjectAttributes( &ObjectAttributes, &Unicode, OBJ_CASE_INSENSITIVE, NULL, NULL ); status = NtOpenSection ( &Section1, SECTION_MAP_READ | SECTION_MAP_WRITE, &ObjectAttributes ); RtlFreeUnicodeString(&Unicode); if (status != 0) { DbgPrint("******** FAILED TEST 26 **************\n"); DbgPrint("open physical section failed %lx\n", status); } p1 = NULL; Offset.LowPart = 0x810ff033; Offset.HighPart = 0; ViewSize = 300*4096; status = NtMapViewOfSection (Section1, NtCurrentProcess(), (PVOID *)&p1, 0, ViewSize, &Offset, &ViewSize, ViewUnmap, 0, PAGE_READWRITE ); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 27 **************\n"); DbgPrint ("map physical section %X offset = %lx, base %lx\n",status, Offset.LowPart, p1); } p1 = NULL; Size1 = 8 * 1024 * 1024; alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Size1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(alstatus)) { DbgPrint("failed first created vm status %X start %lx size %lx\n", alstatus, (ULONG)p1, Size1); DbgPrint("******** FAILED TEST 28 **************\n"); } RtlZeroMemory (p1, Size1); Size1 -= 20000; (PUCHAR)p1 += 5000; status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, &Size1 , MEM_DECOMMIT); if (!(NT_SUCCESS(status))) { DbgPrint(" free vm failed - status %lx\n",status); DbgPrint("******** FAILED TEST 29 **************\n"); NtTerminateProcess(NtCurrentProcess(),status); } Size1 -= 20000; (PUCHAR)p1 += 5000; alstatus = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Size1, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(alstatus)) { DbgPrint("failed first created vm status %X start %lx size %lx\n", alstatus, (ULONG)p1, Size1); DbgPrint("******** FAILED TEST 30 **************\n"); } RtlZeroMemory (p1, Size1); Size1 = 28 * 4096; p1 = NULL; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Size1, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD); if (!NT_SUCCESS(status)) { DbgPrint("failed first created vm status %X start %lx size %lx\n", status, (ULONG)p1, Size1); DbgPrint("******** FAILED TEST 31 **************\n"); } try { // // attempt to write the guard page. // *p1 = 973; DbgPrint("************ FAILURE TEST 31.3 guard page exception did not occur\n"); } except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); if (status != STATUS_GUARD_PAGE_VIOLATION) { DbgPrint("******** FAILED TEST 32 ******\n"); } } p2 = NULL; Size2 = 200*1024*1024; //200MB status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, 0, &Size2, MEM_COMMIT, PAGE_READWRITE); if (NT_SUCCESS(status)) { status = NtFreeVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, &Size2, MEM_RELEASE); } else { if ((status != STATUS_COMMITMENT_LIMIT) && (status != STATUS_PAGEFILE_QUOTA_EXCEEDED)) { DbgPrint("******** FAILED TEST 33 ************** %lx\n",status); } } // // Create a giant section (2gb) // InitializeObjectAttributes( &Object1Attributes, NULL, 0, NULL, NULL ); SectionSize.LowPart = 0x7f000000; SectionSize.HighPart = 0; status = NtCreateSection (&GiantSection, SECTION_MAP_READ | SECTION_MAP_WRITE, &Object1Attributes, &SectionSize, PAGE_READWRITE, SEC_RESERVE, NULL); if (!NT_SUCCESS(status)) { DbgPrint("failed create big section status %X\n", status); DbgPrint("******** FAILED TEST 41 **************\n"); } // // Attempt to map the section (this should fail). // p1 = NULL; ViewSize = 0; status = NtMapViewOfSection (GiantSection, CurrentProcessHandle, (PVOID *)&p1, 0L, 0, 0, &ViewSize, ViewUnmap, 0, PAGE_READWRITE ); if (status != STATUS_NO_MEMORY) { DbgPrint("failed map big section status %X\n", status); DbgPrint("******** FAILED TEST 42 **************\n"); } #ifdef i386 // // Test MEM_DOS_LIM support. // InitializeObjectAttributes( &Object1Attributes, NULL, OBJ_CASE_INSENSITIVE, NULL, NULL ); SectionSize.LowPart = 1575757, SectionSize.HighPart = 0; status = NtCreateSection (&Section4, SECTION_MAP_READ | SECTION_MAP_WRITE, &Object1Attributes, &SectionSize, PAGE_READWRITE, SEC_COMMIT, NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 42 **************\n"); DbgPrint("t1 create section status %X section handle %lx\n", status, (ULONG)Section4); } p3 = (PVOID)0x9001000; ViewSize = 8000; status = NtMapViewOfSection (Section4, CurrentProcessHandle, (PVOID *)&p3, 0L, 0, 0, &ViewSize, ViewUnmap, MEM_DOS_LIM, PAGE_READWRITE ); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 43 **************\n"); DbgPrint("t1 map section status %X base %lx size %lx\n", status, (ULONG)p3, ViewSize); NtTerminateProcess(NtCurrentProcess(),STATUS_SUCCESS); } p2 = (PVOID)0x9003000; ViewSize = 8000; status = NtMapViewOfSection (Section4, CurrentProcessHandle, (PVOID *)&p2, 0L, 0, 0, &ViewSize, ViewUnmap, MEM_DOS_LIM, PAGE_READWRITE ); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 44 **************\n"); DbgPrint("t1 map section status %X base %lx size %lx\n", status, (ULONG)p3, ViewSize); NtTerminateProcess(NtCurrentProcess(),STATUS_SUCCESS); } status = NtQueryVirtualMemory (CurrentProcessHandle, p3, MemoryBasicInformation, &MemInfo, sizeof (MEMORY_BASIC_INFORMATION), NULL); if (!NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 44 **************\n"); DbgPrint("FAILURE query vm status %X address %lx Base %lx size %lx\n", status, p1, MemInfo.BaseAddress, MemInfo.RegionSize); DbgPrint(" state %lx protect %lx type %lx\n", MemInfo.State, MemInfo.Protect, MemInfo.Type); } *p3 = 98; if (*p3 != *p2) { DbgPrint("******** FAILED TEST 45 **************\n"); } Size2 = 8; p1 = (PVOID)((ULONG)p2 - 0x3000); status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p1, 0, &Size2, MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (NT_SUCCESS(status)) { DbgPrint("******** FAILED TEST 46 **************\n"); DbgPrint("created vm status %X start %lx size %lx\n", status, (ULONG)p1, Size1); } #endif DbgPrint(" End of Memory Management Tests - CreateSection, MapView\n"); DbgPrint("creating too much virtual address space\n"); i = 0; do { p2 = NULL; Size2 = 8*1024*1024 + 9938; i += 1; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID *)&p2, 0, &Size2, MEM_RESERVE, PAGE_READWRITE); } while (NT_SUCCESS (status)); if (status != STATUS_NO_MEMORY) { DbgPrint("******** FAILED TEST 46 **************\n"); } DbgPrint("created vm done (successfully) status %X, number of allocs %ld\n", status, i); DbgPrint(" End of Memory Management Tests - AllocVm, FreeVm, ProtectVm, QueryVm\n"); { ULONG size, Size; PVOID BaseAddress; NTSTATUS Status; Size = 50*1024; size = Size - 1; BaseAddress = (PVOID)1; // we pass an address of 1, so mm will round it down to 0. if we // passed 0, it looks like a not present argument // N.B. We have to make two separate calls to allocatevm, because // we want a specific virtual address. If we don't first reserve // the address, the mm fails the commit call. Status = NtAllocateVirtualMemory( NtCurrentProcess(), &BaseAddress, 0L, &size, MEM_RESERVE, PAGE_READWRITE ); if (!NT_SUCCESS(Status)) { DbgPrint("NtReserveVirtualMemory failed !!!! Status = %lx\n", Status); } size = Size - 1; BaseAddress = (PVOID)1; Status = NtAllocateVirtualMemory( NtCurrentProcess(), &BaseAddress, 0L, &size, MEM_COMMIT, PAGE_READWRITE ); if (!NT_SUCCESS(Status)) { DbgPrint("NtCommitVirtualMemory failed !!!! Status = %lx\n", Status); } } ExitProcess (0); }
/* * Creates a stack for a thread or fiber */ NTSTATUS WINAPI BaseCreateStack(HANDLE hProcess, SIZE_T StackReserve, SIZE_T StackCommit, PINITIAL_TEB InitialTeb) { NTSTATUS Status; PIMAGE_NT_HEADERS Headers; ULONG_PTR Stack; ULONG PageSize, Dummy, AllocationGranularity; SIZE_T StackReserveHeader, StackCommitHeader, GuardPageSize, GuaranteedStackCommit; DPRINT("BaseCreateStack (hProcess: %p, Max: %lx, Current: %lx)\n", hProcess, StackReserve, StackCommit); /* Read page size */ PageSize = BaseStaticServerData->SysInfo.PageSize; AllocationGranularity = BaseStaticServerData->SysInfo.AllocationGranularity; /* Get the Image Headers */ Headers = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress); if (!Headers) return STATUS_INVALID_IMAGE_FORMAT; StackCommitHeader = Headers->OptionalHeader.SizeOfStackCommit; StackReserveHeader = Headers->OptionalHeader.SizeOfStackReserve; if (!StackReserve) StackReserve = StackReserveHeader; if (!StackCommit) { StackCommit = StackCommitHeader; } else if (StackCommit >= StackReserve) { StackReserve = ROUND_UP(StackCommit, 1024 * 1024); } StackCommit = ROUND_UP(StackCommit, PageSize); StackReserve = ROUND_UP(StackReserve, AllocationGranularity); GuaranteedStackCommit = NtCurrentTeb()->GuaranteedStackBytes; if ((GuaranteedStackCommit) && (StackCommit < GuaranteedStackCommit)) { StackCommit = GuaranteedStackCommit; } if (StackCommit >= StackReserve) { StackReserve = ROUND_UP(StackCommit, 1024 * 1024); } StackCommit = ROUND_UP(StackCommit, PageSize); StackReserve = ROUND_UP(StackReserve, AllocationGranularity); /* Reserve memory for the stack */ Stack = 0; Status = NtAllocateVirtualMemory(hProcess, (PVOID*)&Stack, 0, &StackReserve, MEM_RESERVE, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failure to reserve stack: %lx\n", Status); return Status; } /* Now set up some basic Initial TEB Parameters */ InitialTeb->AllocatedStackBase = (PVOID)Stack; InitialTeb->StackBase = (PVOID)(Stack + StackReserve); InitialTeb->PreviousStackBase = NULL; InitialTeb->PreviousStackLimit = NULL; /* Update the Stack Position */ Stack += StackReserve - StackCommit; /* Allocate memory for the stack */ Status = NtAllocateVirtualMemory(hProcess, (PVOID*)&Stack, 0, &StackCommit, MEM_COMMIT, PAGE_READWRITE); if (!NT_SUCCESS(Status)) { DPRINT1("Failure to allocate stack\n"); GuardPageSize = 0; NtFreeVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, MEM_RELEASE); return Status; } /* Now set the current Stack Limit */ InitialTeb->StackLimit = (PVOID)Stack; /* Create a guard page */ GuardPageSize = PageSize; Status = NtProtectVirtualMemory(hProcess, (PVOID*)&Stack, &GuardPageSize, PAGE_GUARD | PAGE_READWRITE, &Dummy); if (!NT_SUCCESS(Status)) { DPRINT1("Failure to set guard page\n"); return Status; } /* Update the Stack Limit keeping in mind the Guard Page */ InitialTeb->StackLimit = (PVOID)((ULONG_PTR)InitialTeb->StackLimit + GuardPageSize); /* We are done! */ return STATUS_SUCCESS; }
LPVOID engine_HookFunctionInProcess(HANDLE hProcess,LPSTR lpModuleName,LPSTR lpFunctionName,LPVOID lpHookFunctionAddress,PDWORD pdwHookFunctionSize,LPVOID* lpFunctionAddress,INT iRndJmp) { LPVOID lpModule=NULL; LPVOID lpFunction=NULL; MEMORY_BASIC_INFORMATION mbi; CHAR lpTmpFunction[MAX_FUNC_LEN*2]; CHAR lpLocalStub[MAX_FUNC_LEN*3]; CHAR lpLocalFunc[MAX_FUNC_LEN*3]; DWORD dwBytesRead; DWORD dwReadLen=0; DWORD dwExistingJMP=0; DWORD dwStubSize; DWORD dwFree=0; DWORD dwBytesWritten; DWORD dwOldProtect; LPVOID lpRemoteStub=NULL; INT iFuncLen; PBYTE pReadAddress; NTSTATUS ntStatus; // Get module address lpModule=(LPVOID)engine_GetRemoteModuleHandle(hProcess,lpModuleName); if (!lpModule) return NULL; // Get function address lpFunction=engine_GetRemoteProcAddress(hProcess,lpModule,lpFunctionName); if (!lpFunction) return NULL; // Get info about the function address if (!NT_SUCCESS(SafeNtQueryVirtualMemory(hProcess,lpFunction,MemoryBasicInformation,&mbi,sizeof(mbi),NULL))) return NULL; // Flush instruction cache NtFlushInstructionCache(hProcess,mbi.BaseAddress,mbi.RegionSize); // Change the protection for the region if (!NT_SUCCESS(NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,PAGE_EXECUTE_READWRITE,&mbi.Protect))) return NULL; // Fill stub buffer with nops RtlFillMemory(lpLocalStub,MAX_FUNC_LEN*3,NOP); // Read MAX_FUNC_LEN instruction(s) from the function into our function buffer if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpFunction,lpTmpFunction,MAX_FUNC_LEN*2,&dwBytesRead))) { NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); return NULL; } pReadAddress=(PBYTE)lpTmpFunction; // check if first opcode in the function is a another jump if (*pReadAddress==LONG_JMP_OPCODE) { // get relative address memcpy(&dwExistingJMP,pReadAddress+1,4); // get absolute address dwExistingJMP=(DWORD)lpFunction+dwExistingJMP; // readlen dwReadLen=jtJmpTable[RELATIVE_JMP].iCodeSize engine_BuildJMPBuffer((CHAR*)lpLocalStub,((DWORD)lpRemoteStub+dwReadLen)-dwExistingJMP,RELATIVE_JMP); NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); return NULL; } // Get the length of the first instruction(s) // This part is done by Z0MBiE's LDE32 v1.05 iFuncLen=disasm_main(pReadAddress); // get first instruction length while (iFuncLen!=-1 && dwReadLen<(DWORD)jtJmpTable[iRndJmp].iCodeSize) { dwReadLen+=iFuncLen; pReadAddress+=iFuncLen; iFuncLen=disasm_main(pReadAddress); // next instruction length } // API code is too short or too long too hook this way (for now ;)) if (dwReadLen<(DWORD)jtJmpTable[iRndJmp].iCodeSize||dwReadLen>MAX_FUNC_LEN*2) { NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); return NULL; } // Read the first instruction(s) from the function into our stub buffer if (!NT_SUCCESS(SafeNtReadVirtualMemory(hProcess,lpFunction,lpLocalStub,dwReadLen,&dwBytesRead))) { NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); return NULL; } // Allocate space with read/write access for our "stub" // note: always use a relative jump for our stub -> RELATIVE_JMP dwStubSize=dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize; if (!NT_SUCCESS(NtAllocateVirtualMemory(hProcess,&lpRemoteStub,0,&dwStubSize,MEM_COMMIT|MEM_TOP_DOWN,PAGE_READWRITE))) { NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); return NULL; } // Check if (dwStubSize<dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize) { NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); // Free allocated buffer NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE); return NULL; } engine_BuildJMPBuffer((CHAR*)lpLocalStub+dwReadLen,jtJmpTable[RELATIVE_JMP].jcStub((DWORD)lpFunction+dwReadLen,(DWORD)lpRemoteStub,dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize),RELATIVE_JMP); // Copy the "stub" buffer to process memory if (!NT_SUCCESS(NtWriteVirtualMemory(hProcess,lpRemoteStub,lpLocalStub,dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize,&dwBytesWritten))) { NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); // Free allocated buffer NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE); return NULL; } // Check if (dwBytesWritten<dwReadLen+jtJmpTable[RELATIVE_JMP].iCodeSize) { NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); // Free allocated buffer NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE); return NULL; } // change access if (!NT_SUCCESS(NtProtectVirtualMemory(hProcess,&lpRemoteStub,&dwStubSize,PAGE_EXECUTE_READ,&dwOldProtect))) { NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); // Free allocated buffer NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE); return NULL; } // Fill it with NOP RtlFillMemory(lpLocalFunc,MAX_FUNC_LEN*3,NOP); // Prepare jmpcode engine_BuildJMPBuffer((CHAR*)lpLocalFunc,jtJmpTable[iRndJmp].jcFunc((DWORD)lpHookFunctionAddress,(DWORD)lpFunction,(DWORD)jtJmpTable[iRndJmp].iCodeSize),iRndJmp); ntStatus=NtWriteVirtualMemory(hProcess,lpFunction,lpLocalFunc,dwReadLen,&dwBytesWritten); // Check that we really wrote our jmpcode completely if (!NT_SUCCESS(ntStatus) || dwBytesWritten!=dwReadLen) { // Try to fix stuff if (dwBytesWritten) NtWriteVirtualMemory(hProcess,lpFunction,lpRemoteStub,dwBytesWritten,&dwBytesWritten); NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); // Free allocated buffer NtFreeVirtualMemory(hProcess,&lpRemoteStub,&dwFree,MEM_RELEASE); return NULL; } // Restore protection NtProtectVirtualMemory(hProcess,&mbi.BaseAddress,&mbi.RegionSize,mbi.Protect,NULL); // Save size of read function length if (pdwHookFunctionSize) *pdwHookFunctionSize=dwReadLen; // Save address of function if (lpFunctionAddress) *lpFunctionAddress=lpFunction; return lpRemoteStub; }
NTSTATUS NTAPI LdrpSnapIAT(IN PLDR_DATA_TABLE_ENTRY ExportLdrEntry, IN PLDR_DATA_TABLE_ENTRY ImportLdrEntry, IN PIMAGE_IMPORT_DESCRIPTOR IatEntry, IN BOOLEAN EntriesValid) { PVOID Iat; NTSTATUS Status; PIMAGE_THUNK_DATA OriginalThunk, FirstThunk; PIMAGE_NT_HEADERS NtHeader; PIMAGE_SECTION_HEADER SectionHeader; PIMAGE_EXPORT_DIRECTORY ExportDirectory; LPSTR ImportName; ULONG ForwarderChain, i, Rva, OldProtect, IatSize, ExportSize; SIZE_T ImportSize; DPRINT("LdrpSnapIAT(%wZ %wZ %p %d)\n", &ExportLdrEntry->BaseDllName, &ImportLdrEntry->BaseDllName, IatEntry, EntriesValid); /* Get export directory */ ExportDirectory = RtlImageDirectoryEntryToData(ExportLdrEntry->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize); /* Make sure it has one */ if (!ExportDirectory) { /* Fail */ DbgPrint("LDR: %wZ doesn't contain an EXPORT table\n", &ExportLdrEntry->BaseDllName); return STATUS_INVALID_IMAGE_FORMAT; } /* Get the IAT */ Iat = RtlImageDirectoryEntryToData(ImportLdrEntry->DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IAT, &IatSize); ImportSize = IatSize; /* Check if we don't have one */ if (!Iat) { /* Get the NT Header and the first section */ NtHeader = RtlImageNtHeader(ImportLdrEntry->DllBase); if (!NtHeader) return STATUS_INVALID_IMAGE_FORMAT; SectionHeader = IMAGE_FIRST_SECTION(NtHeader); /* Get the RVA of the import directory */ Rva = NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; /* Make sure we got one */ if (Rva) { /* Loop all the sections */ for (i = 0; i < NtHeader->FileHeader.NumberOfSections; i++) { /* Check if we are inside this section */ if ((Rva >= SectionHeader->VirtualAddress) && (Rva < (SectionHeader->VirtualAddress + SectionHeader->SizeOfRawData))) { /* We are, so set the IAT here */ Iat = (PVOID)((ULONG_PTR)(ImportLdrEntry->DllBase) + SectionHeader->VirtualAddress); /* Set the size */ IatSize = SectionHeader->Misc.VirtualSize; /* Deal with Watcom and other retarded compilers */ if (!IatSize) IatSize = SectionHeader->SizeOfRawData; /* Found it, get out */ break; } /* No match, move to the next section */ SectionHeader++; } } /* If we still don't have an IAT, that's bad */ if (!Iat) { /* Fail */ DbgPrint("LDR: Unable to unprotect IAT for %wZ (Image Base %p)\n", &ImportLdrEntry->BaseDllName, ImportLdrEntry->DllBase); return STATUS_INVALID_IMAGE_FORMAT; } /* Set the right size */ ImportSize = IatSize; } /* Unprotect the IAT */ Status = NtProtectVirtualMemory(NtCurrentProcess(), &Iat, &ImportSize, PAGE_READWRITE, &OldProtect); if (!NT_SUCCESS(Status)) { /* Fail */ DbgPrint("LDR: Unable to unprotect IAT for %wZ (Status %x)\n", &ImportLdrEntry->BaseDllName, Status); return Status; } /* Check if the Thunks are already valid */ if (EntriesValid) { /* We'll only do forwarders. Get the import name */ ImportName = (LPSTR)((ULONG_PTR)ImportLdrEntry->DllBase + IatEntry->Name); /* Get the list of forwaders */ ForwarderChain = IatEntry->ForwarderChain; /* Loop them */ while (ForwarderChain != -1) { /* Get the cached thunk VA*/ OriginalThunk = (PIMAGE_THUNK_DATA) ((ULONG_PTR)ImportLdrEntry->DllBase + IatEntry->OriginalFirstThunk + (ForwarderChain * sizeof(IMAGE_THUNK_DATA))); /* Get the first thunk */ FirstThunk = (PIMAGE_THUNK_DATA) ((ULONG_PTR)ImportLdrEntry->DllBase + IatEntry->FirstThunk + (ForwarderChain * sizeof(IMAGE_THUNK_DATA))); /* Get the Forwarder from the thunk */ ForwarderChain = (ULONG)FirstThunk->u1.Ordinal; /* Snap the thunk */ _SEH2_TRY { Status = LdrpSnapThunk(ExportLdrEntry->DllBase, ImportLdrEntry->DllBase, OriginalThunk, FirstThunk, ExportDirectory, ExportSize, TRUE, ImportName); /* Move to the next thunk */ FirstThunk++; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { /* Fail with the SEH error */ Status = _SEH2_GetExceptionCode(); } _SEH2_END; /* If we messed up, exit */ if (!NT_SUCCESS(Status)) break; } } else if (IatEntry->FirstThunk)
main() { LONG i, j; PULONG p4, p3, p2, p1; ULONG Size1, Size2, Size3; NTSTATUS status; HANDLE CurrentProcessHandle; MEMORY_BASIC_INFORMATION MemInfo; ULONG OldProtect; STRING Name3; HANDLE Section1; OBJECT_ATTRIBUTES ObjectAttributes; ULONG ViewSize, Offset; CurrentProcessHandle = NtCurrentProcess(); for(i=0;i<3;i++){ DbgPrint("Hello World...\n\n"); } DbgPrint("allocating virtual memory\n"); p1 = (PULONG)NULL; Size1 = 5*4096; status = NtAllocateVirtualMemory (CurrentProcessHandle, (PVOID)&p1, 0, &Size1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); DbgPrint("created vm status %X start %lx size %lx\n", status, (ULONG)p1, Size1); p2 = p1; *p2 = 99; Size2 = 4; status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID)&p2, &Size2, PAGE_GUARD | PAGE_READONLY, &OldProtect); DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n", status, p2, Size2, OldProtect); p3 = p1 + 1024; *p3 =91; Size2 = 4; status = NtProtectVirtualMemory (CurrentProcessHandle, (PVOID)&p3, &Size2, PAGE_NOACCESS, &OldProtect); DbgPrint("protected VM status %X, base %lx, size %lx, old protect %lx\n", status, p3, Size2, OldProtect); try { *p2 = 94; } except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); DbgPrint("got an exception of %X\n",status); } try { i = *p2; } except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); DbgPrint("got an exception of %X\n",status); } DbgPrint("value of p2 should be 94 is %ld\n",*p2); try { *p3 = 94; } except (EXCEPTION_EXECUTE_HANDLER) { status = GetExceptionCode(); DbgPrint("got an exception of %X\n",status); } return 0; }