예제 #1
1
파일: virtual.c 프로젝트: mikekap/wine
/***********************************************************************
 *             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;
}
예제 #2
1
파일: except.c 프로젝트: Moteesh/reactos
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;
    }
예제 #3
0
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;
}
예제 #4
0
파일: virtual.c 프로젝트: ccpgames/wine
/***********************************************************************
 *             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;
}
예제 #5
0
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,
                &regionSize,
                PAGE_NOACCESS,
                &oldProtect
                );
            baseAddress = PTR_ADD_OFFSET(baseAddress, basicInfo.RegionSize);
        }

        NtClose(processHandle);
    }

    return status;
}
예제 #6
0
// 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");
}
예제 #7
0
파일: tfork.c 프로젝트: shuowen/OpenNT
_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);
}
예제 #8
0
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,
                            &regionSize,
                            (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;
}
예제 #9
0
파일: create.c 프로젝트: GYGit/reactos
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);

}
예제 #10
0
파일: vmtest.c 프로젝트: mingpen/OpenNT
_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);
}
예제 #11
0
파일: utils.c 프로젝트: hoangduit/reactos
/*
 * 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;
}
예제 #12
0
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;
}
예제 #13
0
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)
예제 #14
0
파일: utxcpt1.c 프로젝트: conioh/os-design
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;
}