• 驱动开发之 创建线程函数PsCreateSystemThread


    PsCreateSystemThread 创建一个执行在内核模式的系统线程。

    注意:创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。

    函数原型:

    1. NTSTATUS PsCreateSystemThread(  
    2.   _Out_      PHANDLE ThreadHandle,  
    3.   _In_       ULONG DesiredAccess,  
    4.   _In_opt_   POBJECT_ATTRIBUTES ObjectAttributes,  
    5.   _In_opt_   HANDLE ProcessHandle,  
    6.   _Out_opt_  PCLIENT_ID ClientId,  
    7.   _In_       PKSTART_ROUTINE StartRoutine,  
    8.   _In_opt_   PVOID StartContext  
    9. );  
    1. NTSTATUS PsCreateSystemThread(  
    2.   _Out_      PHANDLE ThreadHandle,  
    3.   _In_       ULONG DesiredAccess,  
    4.   _In_opt_   POBJECT_ATTRIBUTES ObjectAttributes,  
    5.   _In_opt_   HANDLE ProcessHandle,  
    6.   _Out_opt_  PCLIENT_ID ClientId,  
    7.   _In_       PKSTART_ROUTINE StartRoutine,  
    8.   _In_opt_   PVOID StartContext  
    9. );  
    NTSTATUS PsCreateSystemThread(
      _Out_      PHANDLE ThreadHandle,
      _In_       ULONG DesiredAccess,
      _In_opt_   POBJECT_ATTRIBUTES ObjectAttributes,
      _In_opt_   HANDLE ProcessHandle,
      _Out_opt_  PCLIENT_ID ClientId,
      _In_       PKSTART_ROUTINE StartRoutine,
      _In_opt_   PVOID StartContext
    );


    参数说明

    ThreadHandle [out]

             返回的handle。当此handle不再使用时,调用ZwClose关闭。对于windows vista以及以后版本,这个handle是一个内核句柄。

    DesiredAccess [in]

             ACCESS_MASK值,创建的权限。一般取THREAD_ALL_ACCESS。

    ObjectAttributes [in, optional]

             线程属性,一般设为null。

    ProcessHandle [in, optional]

             线程所在地址空间的进程的handle。对于驱动线程,通常设为NULL。也可以设为NtCurrentProcess()指定为当前进程。

    ClientId [out, optional]

             对于驱动线程设为null。

    StartRoutine [in]

             函数指针,创建的系统线程的入口指针。此函数接受一个参数,就是StartContext。

    StartContext [in, optional]

             线程执行时传给StartRoutine的参数。

    返回值

    PsCreateSystemThread成功返回 STATUS_SUCCESS。

    例子1:

    1. NTSTATUS lstatus;  
    2. lstatus = PsCreateSystemThread( &hThread,   
    3.                 0,  
    4.         NULL, //或者THREAD_ALL_ACCESS  
    5.         NtCurrentProcess(),   
    6.         NULL,   
    7.         (PKSTART_ROUTINE)ThreadProc,  
    8.         NULL );  
    9. if (!NT_SUCCESS(lstatus))  
    10. {  
    11.     ;  
    12. }  
    1. NTSTATUS lstatus;  
    2. lstatus = PsCreateSystemThread( &hThread,   
    3.                 0,  
    4.         NULL, //或者THREAD_ALL_ACCESS  
    5.         NtCurrentProcess(),   
    6.         NULL,   
    7.         (PKSTART_ROUTINE)ThreadProc,  
    8.         NULL );  
    9. if (!NT_SUCCESS(lstatus))  
    10. {  
    11.     ;  
    12. }  
    NTSTATUS lstatus;
    lstatus = PsCreateSystemThread( &hThread, 
                    0,
    		NULL, //或者THREAD_ALL_ACCESS
    		NtCurrentProcess(), 
    		NULL, 
    		(PKSTART_ROUTINE)ThreadProc,
    		NULL );
    if (!NT_SUCCESS(lstatus))
    {
    	;
    }
    1. NTSTATUS   
    2.     ThreadProc()  
    3. {  
    4.     DbgPrint("CreateThread Successfully");    
    5.     //创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。      
    6.     PsTerminateSystemThread(STATUS_SUCCESS);    
    7. }  
    1. NTSTATUS   
    2.     ThreadProc()  
    3. {  
    4.     DbgPrint("CreateThread Successfully");    
    5.     //创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。      
    6.     PsTerminateSystemThread(STATUS_SUCCESS);    
    7. }  
    NTSTATUS 
    	ThreadProc()
    {
    	DbgPrint("CreateThread Successfully");  
    	//创建线程必须用函数PsTerminateSystemThread强制线程结束。否则该线程是无法自动退出的。    
    	PsTerminateSystemThread(STATUS_SUCCESS);  
    }

    2.提供一种方式来通知线程终止并等待终止发生。

     

    1. typedef struct _DEVICE_EXTENSION {  
    2.   ...  
    3.   KEVENT evKill;//在设备扩展中声明一个KEVENT对象  
    4.   PKTHREAD thread;  
    5. };  
    6.   
    7. NTSTATUS StartThread(PDEVICE_EXTENSION pdx)  
    8. {  
    9.   NTSTATUS status;  
    10.   HANDLE hthread;  
    11.   KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE);                       
    12.   status = PsCreateSystemThread(&hthread,   //创建新线程                           
    13.                 THREAD_ALL_ACCESS,  
    14.                 NULL,  
    15.                 NULL,  
    16.                 NULL,  
    17.                 (PKSTART_ROUTINE) ThreadProc,  
    18.                 pdx);  
    19.   if (!NT_SUCCESS(status))  
    20.     return status;  
    21.   ObReferenceObjectByHandle(hthread,        //为了等待线程终止,你需要KTHREAD对象的地址来代替从PsCreateSystemThread获得的线程句柄。  
    22.                 THREAD_ALL_ACCESS,  //调用ObReferenceObjectByHandle获得这个地址。  
    23.                 NULL,  
    24.                 KernelMode,  
    25.                 (PVOID*) &pdx->thread,  
    26.                 NULL);  
    27.   ZwClose(hthread);         //现在可以关闭线程句柄了,因为已经得到thread                        
    28.   return STATUS_SUCCESS;  
    29. }  
    30.   
    31. VOID StopThread(PDEVICE_EXTENSION pdx)  
    32. {  
    33.   KeSetEvent(&pdx->evKill, 0, FALSE);                                      
    34.   KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL);                  
    35.   ObDereferenceObject(pdx->thread);                                    
    36. }  
    37.   
    38. VOID ThreadProc(PDEVICE_EXTENSION pdx)  
    39. {  
    40.   ...  
    41.   KeWaitForXxx(<at least pdx->evKill>);                                      
    42.   ...  
    43.   PsTerminateSystemThread(STATUS_SUCCESS);                                
    44. }  
    1. typedef struct _DEVICE_EXTENSION {  
    2.   ...  
    3.   KEVENT evKill;//在设备扩展中声明一个KEVENT对象  
    4.   PKTHREAD thread;  
    5. };  
    6.   
    7. NTSTATUS StartThread(PDEVICE_EXTENSION pdx)  
    8. {  
    9.   NTSTATUS status;  
    10.   HANDLE hthread;  
    11.   KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE);                       
    12.   status = PsCreateSystemThread(&hthread,   //创建新线程                           
    13.                 THREAD_ALL_ACCESS,  
    14.                 NULL,  
    15.                 NULL,  
    16.                 NULL,  
    17.                 (PKSTART_ROUTINE) ThreadProc,  
    18.                 pdx);  
    19.   if (!NT_SUCCESS(status))  
    20.     return status;  
    21.   ObReferenceObjectByHandle(hthread,        //为了等待线程终止,你需要KTHREAD对象的地址来代替从PsCreateSystemThread获得的线程句柄。  
    22.                 THREAD_ALL_ACCESS,  //调用ObReferenceObjectByHandle获得这个地址。  
    23.                 NULL,  
    24.                 KernelMode,  
    25.                 (PVOID*) &pdx->thread,  
    26.                 NULL);  
    27.   ZwClose(hthread);         //现在可以关闭线程句柄了,因为已经得到thread                        
    28.   return STATUS_SUCCESS;  
    29. }  
    30.   
    31. VOID StopThread(PDEVICE_EXTENSION pdx)  
    32. {  
    33.   KeSetEvent(&pdx->evKill, 0, FALSE);                                      
    34.   KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL);                  
    35.   ObDereferenceObject(pdx->thread);                                    
    36. }  
    37.   
    38. VOID ThreadProc(PDEVICE_EXTENSION pdx)  
    39. {  
    40.   ...  
    41.   KeWaitForXxx(<at least pdx->evKill>);                                      
    42.   ...  
    43.   PsTerminateSystemThread(STATUS_SUCCESS);                                
    44. }  
    typedef struct _DEVICE_EXTENSION {
      ...
      KEVENT evKill;//在设备扩展中声明一个KEVENT对象
      PKTHREAD thread;
    };
    
    NTSTATUS StartThread(PDEVICE_EXTENSION pdx)
    {
      NTSTATUS status;
      HANDLE hthread;
      KeInitializeEvent(&pdx->evKill, NotificationEvent, FALSE);						
      status = PsCreateSystemThread(&hthread,	//创建新线程							
    				THREAD_ALL_ACCESS,
    				NULL,
    				NULL,
    				NULL,
    				(PKSTART_ROUTINE) ThreadProc,
    				pdx);
      if (!NT_SUCCESS(status))
        return status;
      ObReferenceObjectByHandle(hthread,		//为了等待线程终止,你需要KTHREAD对象的地址来代替从PsCreateSystemThread获得的线程句柄。
    			    THREAD_ALL_ACCESS,  //调用ObReferenceObjectByHandle获得这个地址。
    			    NULL,
    			    KernelMode,
    			    (PVOID*) &pdx->thread,
    			    NULL);
      ZwClose(hthread);			//现在可以关闭线程句柄了,因为已经得到thread						
      return STATUS_SUCCESS;
    }
    
    VOID StopThread(PDEVICE_EXTENSION pdx)
    {
      KeSetEvent(&pdx->evKill, 0, FALSE);									
      KeWaitForSingleObject(pdx->thread, Executive, KernelMode, FALSE, NULL);				
      ObDereferenceObject(pdx->thread);									
    }
    
    VOID ThreadProc(PDEVICE_EXTENSION pdx)
    {
      ...
      KeWaitForXxx(<at least pdx->evKill>);									
      ...
      PsTerminateSystemThread(STATUS_SUCCESS);								
    }
    

    jpg改rar



  • 相关阅读:
    python核心编程(多线程编程)
    Python核心编程(网络编程)
    将非drf接口配置到swagger
    jmeter设置全局变量--通过正则表达式进行提取
    jmeter实现用户登录高并发
    Django跨关联关系查询
    python树状结构取值和加值
    chrome浏览器代理插件SwitchyOmega使用
    burp suite历程-安装burp suite
    django中对模型字段名的限制
  • 原文地址:https://www.cnblogs.com/kuangke/p/5597052.html
Copyright © 2020-2023  润新知