C++ 用户模式调用 NtCreateThread

/********************************************************************
	Created:	2012/02/01  18:17
	Filename: 	NativeAPI.h
	Author:		rrrfff
	Url:	    http://blog.csdn.net/rrrfff
*********************************************************************/
#ifndef USE_NATIVEAPI
#define USE_NATIVEAPI
#include "../RLib.h"
#include <WinNT.h>
#include <winternl.h>
//////////////////////////////////////////////////////////////////////////
typedef struct _CLIENT_ID {
	HANDLE UniqueProcess;
	HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
typedef struct _INITIAL_TEB {
	struct {
		PVOID OldStackBase;
		PVOID OldStackLimit;
	} OldInitialTeb;
	PVOID StackBase;
	PVOID StackLimit;
	PVOID StackAllocationBase;
} INITIAL_TEB, *PINITIAL_TEB;
typedef enum _BASE_CONTEXT_TYPE {
	BaseContextTypeProcess,
	BaseContextTypeThread,
	BaseContextTypeFiber
} BASE_CONTEXT_TYPE, *PBASE_CONTEXT_TYPE;
typedef struct __TEB {
	NT_TIB                  Tib;
	PVOID                   EnvironmentPointer;
	CLIENT_ID               Cid;
	PVOID                   ActiveRpcInfo;
	PVOID                   ThreadLocalStoragePointer;
	PPEB                    Peb;
	ULONG                   LastErrorValue;
	ULONG                   CountOfOwnedCriticalSections;
	PVOID                   CsrClientThread;
	PVOID                   Win32ThreadInfo;
	ULONG                   Win32ClientInfo[0x1F];
	PVOID                   WOW32Reserved;
	ULONG                   CurrentLocale;
	ULONG                   FpSoftwareStatusRegister;
	PVOID                   SystemReserved1[0x36];
	PVOID                   Spare1;
	ULONG                   ExceptionCode;
	ULONG                   SpareBytes1[0x28];
	PVOID                   SystemReserved2[0xA];
	ULONG                   GdiRgn;
	ULONG                   GdiPen;
	ULONG                   GdiBrush;
	CLIENT_ID               RealClientId;
	PVOID                   GdiCachedProcessHandle;
	ULONG                   GdiClientPID;
	ULONG                   GdiClientTID;
	PVOID                   GdiThreadLocaleInfo;
	PVOID                   UserReserved[5];
	PVOID                   GlDispatchTable[0x118];
	ULONG                   GlReserved1[0x1A];
	PVOID                   GlReserved2;
	PVOID                   GlSectionInfo;
	PVOID                   GlSection;
	PVOID                   GlTable;
	PVOID                   GlCurrentRC;
	PVOID                   GlContext;
	NTSTATUS                LastStatusValue;
	UNICODE_STRING          StaticUnicodeString;
	WCHAR                   StaticUnicodeBuffer[0x105];
	PVOID                   DeallocationStack;
	PVOID                   TlsSlots[0x40];
	LIST_ENTRY              TlsLinks;
	PVOID                   Vdm;
	PVOID                   ReservedForNtRpc;
	PVOID                   DbgSsReserved[0x2];
	ULONG                   HardErrorDisabled;
	PVOID                   Instrumentation[0x10];
	PVOID                   WinSockData;
	ULONG                   GdiBatchCount;
	ULONG                   Spare2;
	ULONG                   Spare3;
	ULONG                   Spare4;
	PVOID                   ReservedForOle;
	ULONG                   WaitingOnLoaderLock;
	PVOID                   StackCommit;
	PVOID                   StackCommitMax;
	PVOID                   StackReserved;
} TEB_, *PTEB_;
typedef struct __PEB {
	BOOLEAN                 InheritedAddressSpace;
	BOOLEAN                 ReadImageFileExecOptions;
	BOOLEAN                 BeingDebugged;
	BOOLEAN                 Spare;
	HANDLE                  Mutant;
	PVOID                   ImageBaseAddress;
	PPEB_LDR_DATA           LoaderData;
	PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
	PVOID                   SubSystemData;
	PVOID                   ProcessHeap;
	PVOID                   FastPebLock;
	PVOID/*PPEBLOCKROUTINE*/FastPebLockRoutine;
	PVOID/*PPEBLOCKROUTINE */FastPebUnlockRoutine;
	ULONG                   EnvironmentUpdateCount;
	PVOID/*PPVOID*/         KernelCallbackTable;
	PVOID                   EventLogSection;
	PVOID                   EventLog;
	PVOID/*PPEB_FREE_BLOCK*/FreeList;
	ULONG                   TlsExpansionCounter;
	PVOID                   TlsBitmap;
	ULONG                   TlsBitmapBits[0x2];
	PVOID                   ReadOnlySharedMemoryBase;
	PVOID                   ReadOnlySharedMemoryHeap;
	PVOID/*PPVOID*/         ReadOnlyStaticServerData;
	PVOID                   AnsiCodePageData;
	PVOID                   OemCodePageData;
	PVOID                   UnicodeCaseTableData;
	ULONG                   NumberOfProcessors;
	ULONG                   NtGlobalFlag;
	BYTE                    Spare2[0x4];
	LARGE_INTEGER           CriticalSectionTimeout;
	ULONG                   HeapSegmentReserve;
	ULONG                   HeapSegmentCommit;
	ULONG                   HeapDeCommitTotalFreeThreshold;
	ULONG                   HeapDeCommitFreeBlockThreshold;
	ULONG                   NumberOfHeaps;
	ULONG                   MaximumNumberOfHeaps;
	PVOID/*PPVOID*/        *ProcessHeaps;
	PVOID                   GdiSharedHandleTable;
	PVOID                   ProcessStarterHelper;
	PVOID                   GdiDCAttributeList;
	PVOID                   LoaderLock;
	ULONG                   OSMajorVersion;
	ULONG                   OSMinorVersion;
	ULONG                   OSBuildNumber;
	ULONG                   OSPlatformId;
	ULONG                   ImageSubSystem;
	ULONG                   ImageSubSystemMajorVersion;
	ULONG                   ImageSubSystemMinorVersion;
	ULONG                   GdiHandleBuffer[0x22];
	ULONG                   PostProcessInitRoutine;
	ULONG                   TlsExpansionBitmap;
	BYTE                    TlsExpansionBitmapBits[0x80];
	ULONG                   SessionId;
} PEB_, *PPEB_;
typedef struct _FILE_NETWORK_OPEN_INFORMATION {
	LARGE_INTEGER CreationTime;
	LARGE_INTEGER LastAccessTime;
	LARGE_INTEGER LastWriteTime;
	LARGE_INTEGER ChangeTime;
	LARGE_INTEGER AllocationSize;
	LARGE_INTEGER EndOfFile;
	ULONG         FileAttributes;
} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;
typedef struct _FILE_DISPOSITION_INFORMATION {
	BOOLEAN Delete;
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;
typedef struct _FILE_RENAME_INFORMATION {
	BOOLEAN ReplaceIfExists;
	HANDLE  RootDirectory;
	ULONG   FileNameLength;
	WCHAR   FileName[MAX_PATH + 4];
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;
typedef struct _FILE_POSITION_INFORMATION {
	LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;
typedef struct _FILE_END_OF_FILE_INFORMATION {
	LARGE_INTEGER EndOfFile;
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;
typedef enum _THREAD_INFORMATION_CLASS {
	ThreadBasicInformation,
	ThreadTimes,
	ThreadPriority,
	ThreadBasePriority,
	ThreadAffinityMask,
	ThreadImpersonationToken,
	ThreadDescriptorTableEntry,
	ThreadEnableAlignmentFaultFixup,
	ThreadEventPair,
	ThreadQuerySetWin32StartAddress,
	ThreadZeroTlsCell,
	ThreadPerformanceCount,
	ThreadAmILastThread,
	ThreadIdealProcessor,
	ThreadPriorityBoost,
	ThreadSetTlsArrayAddress,
	ThreadIsIoPendingRRRFFF,//重定义
	ThreadHideFromDebugger
} THREAD_INFORMATION_CLASS, *PTHREAD_INFORMATION_CLASS;

//
// Determine if an argument is present by testing the value of the pointer
// to the argument value.
//
#define ARGUMENT_PRESENT(ArgumentPointer)    (\
	(CHAR *)((ULONG_PTR)(ArgumentPointer)) != (CHAR *)(NULL) )
#define NtCurrentPeb() (PPEB_(((TEB_ *)NtCurrentTeb())->Peb))
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0xF)
#define ROUND_UP(x, align) (((int) (x) + (align - 1)) & ~(align - 1))
#define SET_THREAD_ENTRY_ROUTINE 9  

extern "C"
{
	HANDLE NTAPI BaseGetNamedObjectDirectory();
	POBJECT_ATTRIBUTES NTAPI BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes, IN PUNICODE_STRING ObjectName);
	VOID NTAPI BaseInitializeContext(OUT PCONTEXT Context,IN PVOID Parameter OPTIONAL,IN PVOID InitialPc OPTIONAL,
	 		IN PVOID InitialSp OPTIONAL,IN BASE_CONTEXT_TYPE ContextType);
	VOID NTAPI RtlAcquirePebLock(VOID);
	VOID NTAPI RtlReleasePebLock(VOID);

	HANDLE NTAPI CreateRemoteThreadS(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, 
		LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);

	NTSTATUS NTAPI BaseCreateStack(IN HANDLE Process, IN SIZE_T StackSize, IN SIZE_T MaximumStackSize, OUT PINITIAL_TEB InitialTeb);

	PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(PVOID);
	PVOID RtlImageDirectoryEntryToData(IN PVOID Base, IN BOOLEAN MappedAsImage, IN USHORT DirectoryEntry, OUT PULONG Size);

	VOID BaseThreadStart(PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam);
	VOID NTAPI BaseProcessStart(LPVOID lpfnStartRoutine);

	NTSTATUS NTAPI NtOpenDirectoryObject(__out PHANDLE DirectoryHandle, __in ACCESS_MASK DesiredAccess, __in POBJECT_ATTRIBUTES ObjectAttributes);
	NTSTATUS NTAPI NtAllocateVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, ULONG_PTR ZeroBits, PULONG RegionSize, ULONG AllocationType, ULONG Protect);
	NTSTATUS NTAPI NtFreeVirtualMemory(HANDLE ProcessHandle, PVOID *BaseAddress, PULONG RegionSize, ULONG FreeType);
	NTSTATUS NTAPI NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UnsafeBaseAddress, IN OUT SIZE_T *UnsafeNumberOfBytesToProtect,
		IN ULONG NewAccessProtection, OUT PULONG UnsafeOldAccessProtection);
	NTSTATUS NTAPI NtSetInformationThread(IN HANDLE ThreadHandle, IN THREAD_INFORMATION_CLASS ThreadInformationClass, IN PVOID ThreadInformation, 
		IN ULONG ThreadInformationLength );
	NTSTATUS NTAPI NtSuspendThread(IN HANDLE ThreadHandle, OUT PULONG PreviousSuspendCount OPTIONAL);
	NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle,  OUT PULONG PreviousSuspendCount OPTIONAL);
	NTSTATUS NTAPI NtWaitForSingleObject(HANDLE Handle, BOOLEAN Alertable, PLARGE_INTEGER Timeout OPTIONAL);
	NTSTATUS NTAPI NtTerminateThread(HANDLE ThreadHandle, LONG ExitStatus);
	NTSTATUS NTAPI NtCreateThread(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
		HANDLE ProcessHandle, PCLIENT_ID ClientId, PCONTEXT ThreadContext, PINITIAL_TEB InitialTeb, BOOLEAN CreateSuspended);
};
extern "C"
{
	NTSTATUS NTAPI NtQueryFullAttributesFile(
		__in   POBJECT_ATTRIBUTES ObjectAttributes,
		__out  PFILE_NETWORK_OPEN_INFORMATION FileInformation
		);
	NTSTATUS NTAPI NtSetInformationFile(
		__in   HANDLE FileHandle,
		__out  PIO_STATUS_BLOCK IoStatusBlock,
		__in   PVOID FileInformation,
		__in   ULONG Length,
		__in   FILE_INFORMATION_CLASS FileInformationClass
		);
	NTSTATUS NTAPI NtQueryInformationFile(
		__in   HANDLE FileHandle,
		__out  PIO_STATUS_BLOCK IoStatusBlock,
		__out  PVOID FileInformation,
		__in   ULONG Length,
		__in   FILE_INFORMATION_CLASS FileInformationClass
		);
	NTSTATUS NTAPI NtReadFile(
		__in      HANDLE FileHandle,
		__in_opt  HANDLE Event,
		__in_opt  PIO_APC_ROUTINE ApcRoutine,
		__in_opt  PVOID ApcContext,
		__out     PIO_STATUS_BLOCK IoStatusBlock,
		__out     PVOID Buffer,
		__in      ULONG Length,
		__in_opt  PLARGE_INTEGER ByteOffset,
		__in_opt  PULONG Key
		);
	NTSTATUS NTAPI NtWriteFile(
		__in      HANDLE FileHandle,
		__in_opt  HANDLE Event,
		__in_opt  PIO_APC_ROUTINE ApcRoutine,
		__in_opt  PVOID ApcContext,
		__out     PIO_STATUS_BLOCK IoStatusBlock,
		__in      PVOID Buffer,
		__in      ULONG Length,
		__in_opt  PLARGE_INTEGER ByteOffset,
		__in_opt  PULONG Key
		);
};
#endif


/********************************************************************
	Created:	2012/02/01  18:17
	Filename: 	NativeAPI.cpp
	Author:		rrrfff
	Url:	    http://blog.csdn.net/rrrfff
*********************************************************************/
#include "../Lib_Base.h"
#include "NativeAPI.h"
#pragma comment(lib, "Lib/ntoskrnl.lib")
/************************************************************************/
POBJECT_ATTRIBUTES NTAPI BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes,IN PUNICODE_STRING ObjectName)
{
	HANDLE RootDirectory;
	ULONG Attributes;
	PVOID SecurityDescriptor = NULL;

	if (ARGUMENT_PRESENT(ObjectName) ) {
		if ( ARGUMENT_PRESENT(ObjectName) ) {
			RootDirectory = BaseGetNamedObjectDirectory();
		}
		else {
			RootDirectory = NULL;
		}

		if ( ARGUMENT_PRESENT(ObjectName) ) {
			Attributes |= OBJ_OPENIF;
		}

		InitializeObjectAttributes(
			ObjectAttributes,
			ObjectName,
			Attributes,
			RootDirectory,
			SecurityDescriptor
			);
		return ObjectAttributes;
	}else{
		return NULL;
	}
}

NTSTATUS NTAPI BaseCreateStack(IN HANDLE Process, IN SIZE_T StackSize, IN SIZE_T MaximumStackSize, OUT PINITIAL_TEB InitialTeb)
{
	NTSTATUS Status;
	PCH Stack;
	BOOLEAN GuardPage;
	SIZE_T RegionSize;
	ULONG OldProtect;
	SIZE_T ImageStackSize, ImageStackCommit;
	PIMAGE_NT_HEADERS NtHeaders;
	PPEB_ Peb;
	ULONG PageSize;

	Peb = NtCurrentPeb();

	//BaseStaticServerData = BASE_SHARED_SERVER_DATA;
	PageSize = System::AppBase::GetSystemInfo()->PhysicalPageSize/*BASE_SYSINFO.PageSize*/;

	//
	// If the stack size was not supplied, then use the sizes from the
	// image header.
	//

	NtHeaders = RtlImageNtHeader(Peb->ImageBaseAddress);
	ImageStackSize = NtHeaders->OptionalHeader.SizeOfStackReserve;
	ImageStackCommit = NtHeaders->OptionalHeader.SizeOfStackCommit;

	if ( !MaximumStackSize ) {
		MaximumStackSize = ImageStackSize;
	}
	if (!StackSize) {
		StackSize = ImageStackCommit;
	}
	else {

		//
		// Now Compute how much additional stack space is to be
		// reserved. This is done by... If the StackSize is <=
		// Reserved size in the image, then reserve whatever the image
		// specifies. Otherwise, round up to 1Mb.
		//

		if ( StackSize >= MaximumStackSize ) {
			MaximumStackSize = ROUND_UP(StackSize, (1024*1024));
		}
	}

	//
	// Align the stack size to a page boundry and the reserved size
	// to an allocation granularity boundry.
	//

	StackSize = ROUND_UP( StackSize, PageSize );

	MaximumStackSize = ROUND_UP(
		MaximumStackSize,
		System::AppBase::GetSystemInfo()->AllocationGranularity
		);

#if !defined (_IA64_)

	//
	// Reserve address space for the stack
	//

	Stack = NULL,
		Status = NtAllocateVirtualMemory(
		Process,
		(PVOID *)&Stack,
		0,
		&MaximumStackSize,
		MEM_RESERVE,
		PAGE_READWRITE
		);
#else

	//
	// Take RseStack into consideration.
	// RSE stack has same size as memory stack, has same StackBase,
	// has a guard page at the end, and grows upwards towards higher
	// memory addresses
	//

	//
	// Reserve address space for the two stacks
	//
	{
		SIZE_T TotalStackSize = MaximumStackSize * 2;

		Stack = NULL,
			Status = NtAllocateVirtualMemory(
			Process,
			(PVOID *)&Stack,
			0,
			&TotalStackSize,
			MEM_RESERVE,
			PAGE_READWRITE
			);
	}

#endif // IA64
	if ( !NT_SUCCESS( Status ) ) {
		return Status;
	}

	InitialTeb->OldInitialTeb.OldStackBase = NULL;
	InitialTeb->OldInitialTeb.OldStackLimit = NULL;
	InitialTeb->StackAllocationBase = Stack;
	InitialTeb->StackBase = Stack + MaximumStackSize;

#if defined (_IA64_)
	InitialTeb->OldInitialTeb.OldBStoreLimit = NULL;
#endif //IA64

	Stack += MaximumStackSize - StackSize;
	if (MaximumStackSize > StackSize) {
		Stack -= PageSize;
		StackSize += PageSize;
		GuardPage = TRUE;
	}
	else {
		GuardPage = FALSE;
	}

	//
	// Commit the initially valid portion of the stack
	//

#if !defined(_IA64_)

	Status = NtAllocateVirtualMemory(
		Process,
		(PVOID *)&Stack,
		0,
		&StackSize,
		MEM_COMMIT,
		PAGE_READWRITE
		);
#else
	{
		//
		// memory and rse stacks are expected to be contiguous
		// reserver virtual memory for both stack at once
		//
		SIZE_T NewCommittedStackSize = StackSize * 2;

		Status = NtAllocateVirtualMemory(
			Process,
			(PVOID *)&Stack,
			0,
			&NewCommittedStackSize,
			MEM_COMMIT,
			PAGE_READWRITE
			);
	}

#endif //IA64

	if ( !NT_SUCCESS( Status ) ) {

		//
		// If the commit fails, then delete the address space for the stack
		//

		RegionSize = 0;
		NtFreeVirtualMemory(
			Process,
			(PVOID *)&Stack,
			&RegionSize,
			MEM_RELEASE
			);

		return Status;
	}

	InitialTeb->StackLimit = Stack;

#if defined(_IA64_)
	InitialTeb->BStoreLimit = Stack + 2 * StackSize;
#endif

	//
	// if we have space, create a guard page.
	//

	if (GuardPage) {
		RegionSize = PageSize;
		Status = NtProtectVirtualMemory(
			Process,
			(PVOID *)&Stack,
			&RegionSize,
			PAGE_GUARD | PAGE_READWRITE,
			&OldProtect
			);
		if ( !NT_SUCCESS( Status ) ) {
			return Status;
		}
		InitialTeb->StackLimit = (PVOID)((PUCHAR)InitialTeb->StackLimit + RegionSize);

#if defined(_IA64_)
		//
		// additional code to Create RSE stack guard page
		//
		Stack = ((PCH)InitialTeb->StackBase) + StackSize - PageSize;
		RegionSize = PageSize;
		Status = NtProtectVirtualMemory(
			Process,
			(PVOID *)&Stack,
			&RegionSize,
			PAGE_GUARD | PAGE_READWRITE,
			&OldProtect
			);
		if ( !NT_SUCCESS( Status ) ) {
			return Status;
		}
		InitialTeb->BStoreLimit = (PVOID)Stack;

#endif // IA64

	}

	return STATUS_SUCCESS;
}

HANDLE BaseNamedObjectDirectory = NULL; 
HANDLE NTAPI BaseGetNamedObjectDirectory(VOID)
{
	OBJECT_ATTRIBUTES Obja;
	NTSTATUS Status;
	ACCESS_MASK DirAccess = DIRECTORY_ALL_ACCESS &
		~(DELETE | WRITE_DAC | WRITE_OWNER);

	RtlAcquirePebLock();

	if ( !BaseNamedObjectDirectory ) {
		InitializeObjectAttributes(
			&Obja,
			NULL,
			OBJ_CASE_INSENSITIVE,
			NULL,
			NULL
			);
		Status = NtOpenDirectoryObject(
			&BaseNamedObjectDirectory,
			DirAccess,
			&Obja
			);
		if ( !NT_SUCCESS(Status) ) {
			BaseNamedObjectDirectory = NULL;
		}
	}
	RtlReleasePebLock();
	return BaseNamedObjectDirectory;
}

VOID NTAPI BaseProcessStart(LPVOID lpfnStartRoutine)     
{     
	DWORD retValue = 0;     
	__try    
	{     
		//将主线程的入口函数设置为mainCRTStartup     
		NtSetInformationThread(GetCurrentThread(),ThreadQuerySetWin32StartAddress,     
			&lpfnStartRoutine,sizeof(lpfnStartRoutine));     

		//retValue = lpfnStartRoutine();   
		__asm
		{
			call lpfnStartRoutine
			mov retValue, eax 
		}
	}     
	__except(retValue=GetExceptionCode(),  
		UnhandledExceptionFilter(GetExceptionInformation()))     
	{     
		//if(BaseRunningInServerProcess)  
		//	ExitThread(retValue);  
		//else  
			ExitProcess(retValue);  
	}  
}  

VOID NTAPI BaseInitializeContext(OUT PCONTEXT Context, IN PVOID Parameter OPTIONAL, IN PVOID InitialPc OPTIONAL, 
	IN PVOID InitialSp OPTIONAL, IN BASE_CONTEXT_TYPE ContextType)

/*++

Routine Description:

    This function initializes a context structure so that it can
    be used in a subsequent call to NtCreateThread.

Arguments:

    Context - Supplies a context buffer to be initialized by this routine.

    Parameter - Supplies the thread's parameter.

    InitialPc - Supplies an initial program counter value.

    InitialSp - Supplies an initial stack pointer value.

    NewThread - Supplies a flag that specifies that this is a new
        thread, or a new process.

Return Value:

    Raises STATUS_BAD_INITIAL_STACK if the value of InitialSp is not properly
           aligned.

    Raises STATUS_BAD_INITIAL_PC if the value of InitialPc is not properly
           aligned.

--*/

{

    Context->Eax = (ULONG)InitialPc;
    Context->Ebx = (ULONG)Parameter;

    Context->SegGs = 0;
    Context->SegFs = 0x38/*KGDT_R3_TEB*/;
    Context->SegEs = 0x20/*KGDT_R3_DATA*/;
    Context->SegDs = 0x20/*KGDT_R3_DATA*/;
    Context->SegSs = 0x20/*KGDT_R3_DATA*/;
    Context->SegCs = 0x18/*KGDT_R3_CODE*/;

    //
    // Start the thread at IOPL=3.
    //

    Context->EFlags = 0x3000;

    //
    // Always start the thread at the thread start thunk.
    //

    Context->Esp = (ULONG) InitialSp;

    if ( ContextType == BaseContextTypeThread ) {
        Context->Eip = (ULONG) BaseProcessStart;
        }
    else if ( ContextType == BaseContextTypeFiber ) {
        Context->Eip = (ULONG) BaseProcessStart;
        }
    else {
        Context->Eip = (ULONG) BaseProcessStart;
        }
    //
    // add code to check alignment and raise exception...
    //

    Context->ContextFlags = CONTEXT_FULL;
    Context->Esp -= sizeof(Parameter); // Reserve room for ret address
}

HANDLE APIENTRY CreateRemoteThreadS(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, 
	LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
{
	NTSTATUS Status;
	OBJECT_ATTRIBUTES Obja;
	POBJECT_ATTRIBUTES pObja;
	HANDLE Handle;
	CONTEXT ThreadContext;
	INITIAL_TEB InitialTeb;
	CLIENT_ID ClientId;

	// Allocate a stack for this thread
	Status = BaseCreateStack(hProcess, dwStackSize, 0L, &InitialTeb );

	// Create an initial context
	BaseInitializeContext( &ThreadContext, lpParameter, (PVOID)lpStartAddress, InitialTeb.StackBase, BaseContextTypeThread);

	//pObja = BaseFormatObjectAttributes(&Obja, lpThreadAttributes, NULL);

	Status = NtCreateThread( &Handle, THREAD_ALL_ACCESS, pObja, hProcess, &ClientId, &ThreadContext, &InitialTeb, TRUE ); 
	return Handle;
}



你可能感兴趣的:(thread,C++,struct,File,Integer,attributes)