线程
1.线程是附属在进程上的执行实体,是代码的执行流程;
2.代码必须通过线程才能执行;
/*
*test.c
*/
#include <stdio.h>
#include <windows.h>
void fun()
{
for (int i = 0; i < 10; i++){
printf("fun.......\n");
Sleep(1000);
}
}
DWORD WINAPI ThreadProc(LPVOID lpThreadParameter)
{
fun();
return 0;
}
int main()
{
HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
CloseHandle(hThread);
getchar();
return 0;
}
首先我们将test.c编译生成test.exe,并在ThreadProc线程函数处下断点,记录ThreadProc该函数在test.exe启动时的虚拟地址(注意:由于VS2013每次编译函数的虚拟地址有可能改变,自行百度能查到使它每次编译产生固定虚拟地址的设置),记录完不要重新编译该程序,然后到目录下启动该程序。
/*
*CreateRemoteThread.c
*/
#include <stdio.h>
#include <windows.h>
BOOL MyCreateRemoteThread(DWORD dwProcessID, LPTHREAD_START_ROUTINE dwProcAddress)
{
HANDLE hProcess;
HANDLE hThread;
DWORD dwThreadID;
//1.获取进程句柄
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
if (hProcess == INVALID_HANDLE_VALUE){
return FALSE;
}
//2.创建远程线程
hThread = CreateRemoteThread(hProcess, NULL, 0, dwProcAddress, NULL, 0, &dwThreadID);
if (hProcess == INVALID_HANDLE_VALUE){
CloseHandle(hProcess);
return FALSE;
}
//3.关闭资源
CloseHandle(hThread);
CloseHandle(hProcess);
return TRUE;
}
int main()
{
//此处第一个参数为任务管理器查看的刚才启动的test.exe的PID
//第二个地址为上面记录的该进程中线程处理函数的虚拟地址
MyCreateRemoteThread((DWORD)23508, (LPTHREAD_START_ROUTINE)0x001713F0);
return 0;
}
填好连个参数后我们编译启动该程序,我们可以看到test.exe又开始继续运行又打印了10个fun,如下图: