CreateRemoteThread函數
創建在另一個進程的虛擬地址空間中運行的線程。
使用CreateRemoteThreadEx函數創建在另一個進程的虛擬地址空間中運行的線程,并可選擇指定擴展屬性。
語法
HANDLE CreateRemoteThread(HANDLE hProcess,LPSECURITY_ATTRIBUTES lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId
);
參數
- hProcess
要創建線程的進程的句柄。句柄必須具有PROCESS_CREATE_THREAD,PROCESS_QUERY_INFORMATION,PROCESS_VM_OPERATION,PROCESS_VM_WRITE和PROCESS_VM_READ訪問權限,并且在某些平臺上沒有這些權限時可能會失敗。有關更多信息,請參閱 進程安全性和訪問權限。
- lpThreadAttributes
指向SECURITY_ATTRIBUTES結構的指針,該 結構指定新線程的安全描述符,并確定子進程是否可以繼承返回的句柄。如果lpThreadAttributes為NULL,則線程獲取默認安全描述符,并且不能繼承句柄。線程的默認安全描述符中的訪問控制列表(ACL)來自創建者的主令牌。
Windows XP: 線程的默認安全描述符中的ACL來自創建者的主要或模擬令牌。Windows XP SP2和Windows Server 2003更改了此行為。
- dwStackSize
堆棧的初始大小,以字節為單位。系統將此值四舍五入到最近的頁面。如果此參數為0(零),則新線程將使用可執行文件的默認大小。有關更多信息,請參閱 線程堆棧大小。
- lpStartAddress
指向由線程執行的LPTHREAD_START_ROUTINE類型的應用程序定義函數的指針,表示遠程進程中線程的起始地址。該功能必須存在于遠程進程中。有關更多信息,請參閱 ThreadProc。
- lpParameter
指向要傳遞給線程函數的變量的指針。
- dwCreationFlags
控制線程創建的標志。
值 | 含義 |
---|---|
0 | 該線程在創建后立即運行。 |
CREATE_SUSPENDED 0x00000004 | 線程是在掛起狀態下創建的,并且在調用ResumeThread函數之前不會運行 。 |
STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 | 所述dwStackSize參數指定堆棧的初始保留大小。如果未指定此標志,則dwStackSize指定提交大小。 |
- lpThreadId
指向接收線程標識符的變量的指針。
如果此參數為NULL,則不返回線程標識符。
返回值
如果函數成功,則返回值是新線程的句柄。
如果函數失敗,則返回值為NULL。要獲取擴展錯誤信息,請調用 GetLastError。
請注意,即使lpStartAddress指向數據,代碼或無法訪問, CreateRemoteThread也可能成功。如果線程運行時起始地址無效,則發生異常,并且線程終止。由于無效的起始地址導致的線程終止被視為線程進程的錯誤退出。此行為類似于CreateProcess的異步特性, 即使創建進程無效或缺少動態鏈接庫(DLL),也會創建該進程。
備注
該遠程線程函數會導致一個新的執行線程指定進程的地址空間開始。該線程可以訪問進程打開的所有對象。
終端服務按設計隔離每個終端會話。因此,如果目標進程與調用進程位于不同的會話中,則 CreateRemoteThread將失敗。
創建新的線程句柄,可以完全訪問新線程。如果未提供安全描述符,則句柄可用于需要線程對象句柄的任何函數中。當提供安全描述符時,在授予訪問權限之前,對句柄的所有后續使用執行訪問檢查。如果訪問檢查拒絕訪問,則請求進程無法使用句柄來獲取對線程的訪問權限。
如果線程是在可運行狀態下創建的(即,如果未使用CREATE_SUSPENDED標志),則線程可以在CreateThread返回之前開始運行,特別是在調用者接收到創建的線程的句柄和標識符之前。
創建的線程的線程優先級為THREAD_PRIORITY_NORMAL。使用 GetThreadPriority和 SetThreadPriority函數來獲取和設置線程的優先級值。
當線程終止時,線程對象獲得信號狀態,該狀態滿足等待對象的線程。
線程對象保留在系統中,直到線程終止并且通過調用CloseHandle關閉它的所有 句柄。
ExitProcess, ExitThread, CreateThread, CreateRemoteThread的功能,以及正在啟動一個過程(作為結果 的CreateProcess呼叫)的過程中彼此之間串行化。這些事件中只有一個一次發生在地址空間中。這意味著以下限制:
- 在進程啟動和DLL初始化例程期間,可以創建新線程,但是在為進程執行DLL初始化之前它們不會開始執行。
- 進程中只有一個線程可以一次處于DLL初始化或分離例程中。
- 所有線程完成DLL初始化或分離例程后,ExitProcess返回。
此函數的一個常見用途是將線程注入正在調試的進程中以發出中斷。但是,建議不要使用此方法,因為額外的線程會使調試應用程序的人感到困惑,并且使用此技術會產生一些副作用:
- 它將單線程應用程序轉換為多線程應用程序。
- 它改變了進程的時序和內存布局。
- 它導致調用進程中每個DLL的入口點。
此函數的另一個常見用途是將一個線程注入進程以查詢堆或其他進程信息。這可能會導致前一段中提到的相同副作用。此外,如果線程嘗試獲取另一個線程正在使用的鎖的所有權,則應用程序可能會死鎖。