Win32

xiaoxiao2025-07-26  31

线程句柄与线程ID:

线程是由Windows内核负责创建与管理的,句柄相当于一个令牌,有了这个令牌就可以使用线程对象.

线程ID是身份证,唯一的,系统进行线程调度的时候要使用的.

HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全属性 通常为NULL SIZE_T dwStackSize, // 参数用于设定线程可以将多少地址空间用于它自己的堆栈 // 每个线程拥有它自己的堆栈 LPTHREAD_START_ROUTINE lpStartAddress, // 参数用于指明想要新线程执行的线程函数的地址 LPVOID lpParameter, // 线程函数的参数 // 在线程启动执行时将该参数传递给线程函数 // 既可以是数字,也可以是指向包含其他信息的一个数据结构的指针 DWORD dwCreationFlags, // 0 创建完毕立即调度 CREATE_SUSPENDED创建后挂起 LPDWORD lpThreadId // 线程ID ); // 返回值:线程句柄

创建线程代码:

//创建一个新的线程

HANDLE hThread = ::CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);

//如果不在其他的地方引用它 关闭句柄

::CloseHandle(hThread); DWORD WINAPI ThreadProc(LPVOID lpParameter) { printf("%x\n",(int)lpParameter); return 0; } int main() { int a = 5; printf("%d\n",a); HANDLE hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)a, 0, NULL); CloseHandle(hThread); return 0; }

当我们创建一个线程的时候,如果不进行阻塞,有可能cpu根本没有给线程分配应有的东西,导致线程在main函数执行完了都还没开始启动 所以 要在创建线程以后使用sleep等待

int main() { int a = 5; printf("%d\n",a); HANDLE hThread = CreateThread(NULL, 0, ThreadProc, (LPVOID)a, 0, NULL); Sleep(1000); CloseHandle(hThread); return 0; }

在初期的实验中只有这样才能保证线程一定会执行


线程的挂起,恢复和终止

::SuspendThread(hThread); //挂起线程 ::ResumeThread(hThread); //恢复线程 ::ExitThread(DWORD dwExitCode); //线程终止1 ::TerminateThread(hThread,2); //线程终止2 ::WaitForSingleObject(hThread,INFINITE);

在自己的进程空间里拉伸pe,挂起主线程,并且将主线程的eip改变到拉伸的pe里

SuspendThread(线程句柄); context.ContextFlags = CONTEXT_CONTROL; BOOL ok = ::GetThreadContext(hThread,&context); context.Eip = 0x401000; SetThreadContext(hThread,&context);

获取线程上下文结构,设置eip为拉伸的pe的imagebase

转载请注明原文地址: https://www.6miu.com/read-5033761.html

最新回复(0)