线程加载DLL RtlCreateUserThread
使用RtlCreateUserThread创建的线程一切正常, 但是在创建的线程中调用WSAStartup总是失败(错误ID:10106, 说明:无法加载或初始化请求的服务提供程序。), 如果在创建的线程外部调用WSAStartup或者使用CreateThread来创建线程的话就没有问题, 如此何解?
有答案再加分, 不浪费.
[解决办法]
HANDLE
APIENTRY
CreateRemoteThread(
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;
ULONG i;
#if !defined(BUILD_WOW6432)
BASE_API_MSG m;
PBASE_CREATETHREAD_MSG a = (PBASE_CREATETHREAD_MSG)&m.u.CreateThread;
#endif
#if defined(WX86) || defined(_AXP64_)
BOOL bWx86 = FALSE;
HANDLE Wx86Info;
PWX86TIB Wx86Tib;
#endif
//
// Allocate a stack for this thread in the address space of the target
// process.
//
Status = BaseCreateStack(
hProcess,
dwStackSize,
0L,
&InitialTeb
);
if ( !NT_SUCCESS(Status) ) {
BaseSetLastNTError(Status);
return NULL;
}
//
// Create an initial context for the new thread.
//
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
);
if (!NT_SUCCESS(Status)) {
BaseFreeThreadStack(hProcess,NULL, &InitialTeb);
BaseSetLastNTError(Status);
return NULL;
}
try {
#if defined(WX86) || defined(_AXP64_)
//
// Check the Target Processes to see if this is a Wx86 process
//
Status = NtQueryInformationProcess(hProcess,
ProcessWx86Information,
&Wx86Info,
sizeof(Wx86Info),
NULL
);
if (!NT_SUCCESS(Status)) {
leave;
}
Wx86Tib = (PWX86TIB)NtCurrentTeb()->Vdm;
//
// if Wx86 process, setup for emulation
//
if ((ULONG_PTR)Wx86Info == sizeof(WX86TIB)) {
//
// create a WX86Tib and initialize it's Teb->Vdm.
//
Status = BaseCreateWx86Tib(hProcess,
Handle,
(ULONG)((ULONG_PTR)lpStartAddress),
dwStackSize,
0L,
(Wx86Tib &&
Wx86Tib->Size == sizeof(WX86TIB) &&
Wx86Tib->EmulateInitialPc)
);
if (!NT_SUCCESS(Status)) {
leave;
}
bWx86 = TRUE;
}
else if (Wx86Tib && Wx86Tib->EmulateInitialPc) {
//
// if not Wx86 process, and caller wants to call x86 code in that
// process, fail the call.
//
Status = STATUS_ACCESS_DENIED;
leave;
}
#endif // WX86
//
// Call the Windows server to let it know about the
// process.
//
if ( !BaseRunningInServerProcess ) {
#if defined(BUILD_WOW6432)
Status = CsrBasepCreateThread(Handle,
ClientId
);
#else
a->ThreadHandle = Handle;
a->ClientId = ClientId;
CsrClientCallServer( (PCSR_API_MSG)&m,
NULL,
CSR_MAKE_API_NUMBER( BASESRV_SERVERDLL_INDEX,
BasepCreateThread
),
sizeof( *a )
);
Status = m.ReturnValue;
#endif
}
else {
if (hProcess != NtCurrentProcess()) {
CSRREMOTEPROCPROC ProcAddress;
ProcAddress = (CSRREMOTEPROCPROC)GetProcAddress(
GetModuleHandleA("csrsrv"),
"CsrCreateRemoteThread"
);
if (ProcAddress) {
Status = (ProcAddress)(Handle, &ClientId);
}
}
}
if (!NT_SUCCESS(Status)) {
Status = (NTSTATUS)STATUS_NO_MEMORY;
}
else {
if ( ARGUMENT_PRESENT(lpThreadId) ) {
*lpThreadId = HandleToUlong(ClientId.UniqueThread);
}
if (!( dwCreationFlags & CREATE_SUSPENDED) ) {
NtResumeThread(Handle,&i);
}
}
}
finally {
if (!NT_SUCCESS(Status)) {
BaseFreeThreadStack(hProcess,
Handle,
&InitialTeb
);
NtTerminateThread(Handle, Status);
NtClose(Handle);
BaseSetLastNTError(Status);
Handle = NULL;
}
}
return Handle;
}