本文主要是介绍进程与线程(七)APC的实验,古老的Code,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近在看APC,顺便科普一个。APC的作用是指定一个特定线程上下文执行例程而不等待其返回值,实现异步调用。如果想看理论的话可以去看combojiang大牛的文章~apc是对线程而言的,用户模式的apc优先级最低,只有在线程处于alertable状态才可以被插入,我们可以做一个实验,利用APC向一个线程中注入DLL。
插入进程的流程与API~
申请内存,写入DLL地址,遍历进程的所有线程,向队列投入APC,n老的Code。
1 BOOL InsertDLLByAPC(DWORD dwPID,TCHAR szDLLPath[MAX_PATH]) 2 { 3 //打开进程 4 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,TRUE,dwPID); 5 if (hProcess == INVALID_HANDLE_VALUE) 6 { 7 wprintf(_T("process cannot be opened,error code: %d \n"),GetLastError()); 8 return FALSE; 9 } 10 11 DWORD dwSize = lstrlenW(szDLLPath)+1; 12 //VirtualAlloceEx参数意义?明天查啊~分配内存 13 TCHAR * pszRemoteFileName = (TCHAR *)VirtualAllocEx(hProcess,NULL,dwSize*sizeof(TCHAR),MEM_COMMIT,PAGE_READWRITE); 14 if (pszRemoteFileName == NULL) 15 { 16 wprintf(_T("memory error,error code: %d \n"),GetLastError()); 17 return FALSE; 18 } 19 if (0 != WriteProcessMemory(hProcess,(PVOID)pszRemoteFileName,(PVOID)szDLLPath,dwSize*sizeof(TCHAR),NULL)) 20 { 21 HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwPID); 22 THREADENTRY32 te32; 23 te32.dwSize = sizeof(THREADENTRY32); 24 Thread32First(hSnap,&te32); 25 do 26 { 27 if (te32.th32OwnerProcessID == dwPID) 28 { 29 HANDLE hThred = OpenThread(THREAD_ALL_ACCESS,FALSE,te32.th32ThreadID); 30 if (hThred == INVALID_HANDLE_VALUE) 31 { 32 wprintf(_T("thread cannot be opened,error code: %d \n"),GetLastError()); 33 return FALSE; 34 } 35 if(QueueUserAPC((PAPCFUNC)LoadLibrary,hThred,(ULONG_PTR)pszRemoteFileName)) 36 wprintf(_T("got it \n")); 37 } 38 } while (Thread32Next(hSnap,&te32)); 39 40 } 41 42 return FALSE; 43 }
自己实际编写的时候会遇到诸多问题,有助于加深对APC机制的理解,R3的东西会加深自己对内核感性上的认识,不懂应用就看原理实在是头痛~~
如果等待进程是控制台的话也搞不定~~
我坐在宿舍床上,屁股疼死了。。最近有点不开心,不过没关系,让傻逼们傻逼去吧。
这篇关于进程与线程(七)APC的实验,古老的Code的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!