日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用QueueUserAPC线程注入,

發布時間:2025/3/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用QueueUserAPC线程注入, 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
代碼1 #define?_WIN32_WINNT?0x0400
#define?WIN32_LEAN_AND_MEAN???//?從?Windows?頭中排除極少使用的資料

#include?
<iostream>
#include?
<windows.h>
#include?
<Winbase.h>
using?namespace?std;


DWORD??WINAPI?WorkThread(LPVOID?pParam)
{
????HANDLE?Event?
=?(HANDLE)pParam;
????
for(;;)
????{
????????DWORD?dwRet?
=?WaitForSingleObjectEx(Event,?INFINITE,?TRUE);
????????
if(dwRet?==?WAIT_OBJECT_0)
????????????
break;
????????
else?
????????????
if(dwRet?==?WAIT_IO_COMPLETION)
????????????????printf(
"WAIT_IO_COMPLETION\n");
????????????
????????????
return?0;
????}
}


VOID??WINAPI?APCProc(LPVOID?dwParam)
{
????printf(
"%s",?(PVOID)dwParam);
}

void?TestAPC(BOOL?bFast)
{
????
????HANDLE?QuitEvent?
=?CreateEvent(NULL,?FALSE,?FALSE,?NULL);
????HANDLE?hThread?
=?CreateThread(NULL,
????????
0,
????????WorkThread,
????????(LPVOID)QuitEvent,
????????
0,
????????NULL);
????
????
????Sleep(
100);?//?Wait?for?WorkThread?initialized.
????
????
????
for(int?i=5;?i>0;?i--)
????{????
????????QueueUserAPC((PAPCFUNC)APCProc,?hThread,?(DWORD)(PVOID)
"APC?here\n");
????????
if(!bFast)
????????????Sleep(
1000);
????}
????
????
????SetEvent(QuitEvent);
????
????WaitForSingleObject(hThread,?INFINITE);
????
????CloseHandle(hThread);????
}

int?main()
{
????TestAPC(
true);
????
return?0;
}

?

代碼2 #define?_WIN32_WINNT?0x0400
#define?WIN32_LEAN_AND_MEAN???//?從?Windows?頭中排除極少使用的資料

#include?
<windows.h>
#include?
<Tlhelp32.h>
#include?
<stdio.h>
#include?
<stdlib.h>

typedef?HANDLE?(CALLBACK?
*OPENTHREAD)?(DWORD?dwFlag,?BOOL?bUnknow,?DWORD?dwThreadId);?
typedef???unsigned???
long??????ULONG_PTR;?


typedef?
struct?_TIDLIST?
{
????DWORD?dwTid?;
????_TIDLIST?
*pNext?;
}TIDLIST;

DWORD?EnumThread(HANDLE?hProcess,?TIDLIST?
*pThreadIdList)
{
????TIDLIST?
*pCurrentTid?=?pThreadIdList?;
????HANDLE?hThread;
????
const?char?szInjectModName[]?=?"c:\\sysnap.dll"?;
????DWORD?dwLen?
=?strlen(szInjectModName)?;
????HMODULE?hDll?
=?GetModuleHandle("Kernel32.dll");?
????
????PVOID?param?
=?VirtualAllocEx(hProcess,?\
????????NULL,?dwLen,?MEM_COMMIT?
|?MEM_TOP_DOWN,?PAGE_EXECUTE_READWRITE)?;
????
????
if?(param?!=?NULL)
????{
????????DWORD?dwRet?;
????????
if?(WriteProcessMemory(hProcess,?param,?(LPVOID)szInjectModName,?dwLen,?&dwRet))
????????{
????????????
????????????
while?(pCurrentTid)
????????????{
????????????????OPENTHREAD?lpfnOpenThread?
=?(OPENTHREAD)::GetProcAddress(hDll,?"OpenThread");?
????????????????hThread?
=?lpfnOpenThread(THREAD_ALL_ACCESS,FALSE,pCurrentTid->dwTid);
????????????????
if?(hThread?!=?NULL)
????????????????{
????????????????????
//
????????????????????
//?注入DLL到指定進程
????????????????????
//
????????????????????QueueUserAPC((PAPCFUNC)LoadLibraryA,?hThread,?(ULONG_PTR)param)?;
????????????????}
????????????????
????????????????printf(
"TID:%d\n",?pCurrentTid->dwTid)?;
????????????????pCurrentTid?
=?pCurrentTid->pNext?;
????????????}
????????}
????}
????
return?0?;
}

DWORD?GetProcID(
const?char?*szProcessName)
{
????PROCESSENTRY32?pe32?
=?{0}?;
????pe32.dwSize?
=?sizeof(PROCESSENTRY32);
????
????HANDLE?hSnapshot?
=?CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,?0)?;
????
????
if?(hSnapshot?==?INVALID_HANDLE_VALUE)
????{
????????
return?0xFFFFFFFF?;
????}
????
????
if?(!Process32First(hSnapshot,?&pe32))
????{
????????
return?0xFFFFFFFF?;
????}
????
????
do?
????{
????????
if?(!_strnicmp(szProcessName,?pe32.szExeFile,?strlen(szProcessName)))
????????{
????????????printf(
"%s的PID是:%d\n",?pe32.szExeFile,?pe32.th32ProcessID);
????????????
return?pe32.th32ProcessID?;
????????}
????}?
while(Process32Next(hSnapshot,?&pe32));
????
????
return?0xFFFFFFFF?;
????
}

TIDLIST
*?InsertTid(TIDLIST?*pdwTidListHead,?DWORD?dwTid)
{
????TIDLIST?
*pCurrent?=?NULL?;
????TIDLIST?
*pNewMember?=?NULL?;
????
????
if?(pdwTidListHead?==?NULL)
????{
????????
return?NULL?;
????}
????pCurrent?
=?pdwTidListHead?;
????
????
while?(pCurrent?!=?NULL)
????{
????????
????????
if?(pCurrent->pNext?==?NULL)
????????{
????????????
//
????????????
//?定位到鏈表最后一個元素
????????????
//
????????????pNewMember?=?(TIDLIST?*)malloc(sizeof(TIDLIST))?;
????????????
????????????
if?(pNewMember?!=?NULL)
????????????{
????????????????pNewMember
->dwTid?=?dwTid?;
????????????????pNewMember
->pNext?=?NULL?;
????????????????pCurrent
->pNext?=?pNewMember?;
????????????????
return?pNewMember?;
????????????}
????????????
else
????????????{
????????????????
return?NULL?;
????????????}
????????}
????????pCurrent?
=?pCurrent->pNext?;
????}
????
????
return?NULL?;
}

int?EnumThreadID(DWORD?dwPID,?TIDLIST?*pdwTidList)
{
????
int?i?=?0?;
????
????THREADENTRY32?te32?
=?{0}?;
????te32.dwSize
=?sizeof(THREADENTRY32)?;
????
????HANDLE?hSnapshot?
=?CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,dwPID)?;
????
????
if(hSnapshot?!=?INVALID_HANDLE_VALUE)
????{
????????
if(Thread32First(hSnapshot,&te32))?
????????{
????????????
do
????????????{
????????????????
if(te32.th32OwnerProcessID==dwPID)?
????????????????{
????????????????????
if?(pdwTidList->dwTid?==?0)
????????????????????{
????????????????????????pdwTidList
->dwTid?=?te32.th32ThreadID?;
????????????????????}
????????????????????
else
????????????????????{
????????????????????????
if?(NULL?==?InsertTid(pdwTidList,?te32.th32ThreadID))
????????????????????????{
????????????????????????????printf(
"插入失敗!\n")?;
????????????????????????????
return?0?;
????????????????????????}
????????????????????}
????????????????????
????????????????}?
????????????}
while(Thread32Next(hSnapshot,&te32));
????????}
????}
????
return?1?;
}

void?RemoveTid(TIDLIST?*pdwTidListHead)
{
????TIDLIST?
*pCurrent?=?NULL?;
????TIDLIST?
*pNext?=?NULL?;
????
????
????
if?(pdwTidListHead?==?NULL)
????{
????????
return;
????}
????pCurrent?
=?pdwTidListHead?;
????
????
while?(pCurrent?!=?NULL)
????{
????????
????????pNext?
=?pCurrent->pNext;
????????free(pCurrent);
????????pCurrent?
=?pNext;
????}
????
}
int?main(int?argc,?char*?argv[])
{
????TIDLIST?
*pTidHead?=?(TIDLIST?*)malloc(sizeof(TIDLIST))?;
????
????
if?(pTidHead?==?NULL)
????{
????????
return?1?;
????}

????RtlZeroMemory(pTidHead,?
sizeof(TIDLIST))?;
????
????DWORD?dwPID?
=?0?;
????
????
if?((dwPID?=?GetProcID("explorer.exe"))?==?0xFFFFFFFF)
????{
????????printf(
"進程ID獲取失敗!\n")?;
????????
return?1?;
????}
????
????
//
????
//?枚舉線程ID
????
//
????EnumThreadID(dwPID,?pTidHead)?;
????
????HANDLE?hProcess?
=?OpenProcess(PROCESS_ALL_ACCESS,?FALSE,?dwPID)?;
????
????
if?(hProcess?==?NULL)
????{
????????
return?1?;
????}
????EnumThread(hProcess,?pTidHead)?;
????
????CloseHandle(hProcess);
????
????RemoveTid(pTidHead);
????
????
return?0;
}


?

Alertable IO(告警IO)提供了更有效的異步通知形式。ReadFileEx / WriteFileEx在發出IO請求的同時,提供一個回調函數(APC過程),當IO請求完成后,一旦線程進入可告警狀態,回調函數將會執行。
   以下五個函數能夠使線程進入告警狀態:
   SleepEx
   WaitForSingleObjectEx
   WaitForMultipleObjectsEx
   SignalObjectAndWait
   MsgWaitForMultipleObjectsEx
   線程進入告警狀態時,內核將會檢查線程的APC隊列,如果隊列中有APC,將會按FIFO方式依次執行。如果隊列為空,線程將會掛起等待事件對象。以后的某個時刻,一旦APC進入隊列,線程將會被喚醒執行APC,同時等待函數返回WAIT_IO_COMPLETION。
   QueueUserAPC可以用來人為投遞APC,只要目標線程處于告警狀態時,APC就能夠得到執行。
   使用告警IO的主要缺點是發出IO請求的線程也必須是處理結果的線程,如果一個線程退出時還有未完成的IO請求,那么應用程序將永遠丟失IO完成通知。然而以后我們將會看到IO完成端口沒有這個限制。
  

轉載于:https://www.cnblogs.com/chengxin1982/archive/2010/01/20/1652398.html

總結

以上是生活随笔為你收集整理的使用QueueUserAPC线程注入,的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。