使用DLL_THREAD_ATTACH阻止远程线程

         当进程创建一个线程的的时候,系统会检查当前映射到该进程的地址空间中的所有DLL文件映像,并用DLL_THREAD_ATTACH来调用每个DLL的DllMain函数,新创建的线程负责执行所有DLL的DllMain函数中的代码。系统不会让进程的主线程调用DLL_THREAD_ATTACH的值来调用DllMain函数。
       此时新线程已经被创建但尚未执行,更精确的说已经创建了线程内核对象、线程堆栈等资源,正处于初始化阶段。只有在每个DLL都正常处理DLL_THREAD_ATTCH通知,新线程才能开始执行!

   远程线程本质与本地线程一样,区别只是由其他进程创建。我们就是要写个DLL,在收到DLL_THREAD_ATTACH时通知结束线程,那么远程线程就无法执行了。

代码:

// 创建标识
// 创建线程之前设置为TRUE,表示需要创建一个合法的线程
// 只有合法线程才能正常创建
BOOL bStatus = FALSE ;


VOID MY_OutputDebugStringA ( const char* szFormat,...)
{
	char szBuf[1024] ;

	va_list argList ;
	va_start ( argList, szFormat ) ;
	vsprintf ( szBuf, szFormat, argList ) ;
	va_end ( argList ) ;

	OutputDebugStringA ( szBuf ) ;
}

// 设置线程创建标识
VOID  SetStatus ( BOOL status )
{
	bStatus = status ;
}
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
		MY_OutputDebugStringA ( "DLL_THREAD_ATTACH ThreadId=%d", GetCurrentThreadId() ) ;

		// 检测线程创建标识
		if ( bStatus == FALSE )
		{
			// 如果线程创建标识为FALSE,就直接结束线程
			MY_OutputDebugStringA ( "Terminate unvalid thread!" ) ;
			TerminateThread (GetCurrentThread(),0 ) ;
		}
		else
		{
			// 每次创建合法线程后,自动关闭创建标识
			// 每次设置合法线程标识只能使用一次
			SetStatus ( FALSE ) ;
		}
		break;
	case DLL_THREAD_DETACH:
		MY_OutputDebugStringA ( "DLL_THREAD_DETACH ThreadId=%d", GetCurrentThreadId() ) ;
		break ;
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

SetStatus函数要导出一下

为了能使本程序自身正常创建线程

代码:

SetStatus(TRUE);
	CreateThread(NULL,0,NewThread,NULL,0,NULL);


你可能感兴趣的:(thread,list,null,dll)