常见注入手法第二讲,APC注入
常見注入手法第二講,APC注入
轉(zhuǎn)載注明出處
首先,我們要了解下什么是APC
APC 是一個(gè)簡稱,具體名字叫做異步過程調(diào)用,我們看下MSDN中的解釋,異步過程調(diào)用,屬于是同步對象中的函數(shù),所以去同步對象中查看.
首先介紹一下APC,會(huì)了正想開發(fā)就會(huì)逆向注入
首先第一個(gè)函數(shù)
QueueUserApc: 函數(shù)作用,添加制定的異步函數(shù)調(diào)用(回調(diào)函數(shù))到執(zhí)行的線程的APC隊(duì)列中
APCproc: 函數(shù)作用: 回調(diào)函數(shù)的寫法.
我們首先要知道異步函數(shù)調(diào)用的原理,
異步過程調(diào)用是一種能在特定線程環(huán)境中異步執(zhí)行的系統(tǒng)機(jī)制。
往線程APC隊(duì)列添加APC,系統(tǒng)會(huì)產(chǎn)生一個(gè)軟中斷。在線程下一次被調(diào)度的時(shí)候,就會(huì)執(zhí)行APC函數(shù),APC有兩種形式,由系統(tǒng)產(chǎn)生的APC稱為內(nèi)核模式APC,由應(yīng)用程序產(chǎn)生的APC被稱為用戶模式APC
這里介紹一下應(yīng)用程序的APC
APC是往線程中插入一個(gè)回調(diào)函數(shù),但是用的APC調(diào)用這個(gè)回調(diào)函數(shù)是有條件的.我們看下Msdn怎么寫
MSDN說,要使用SleepEx,signalObjectAndWait.....等等這些函數(shù)才會(huì)觸發(fā)
那么使用APC場合的注入就有了,
1.必須是多線程環(huán)境下
2.注入的程序必須會(huì)調(diào)用上面的那些同步對象.
那么我們可以注入APC,注意下條件,也不是所有都能注入的.
注入方法的原理:
1.當(dāng)對面程序執(zhí)行到某一個(gè)上面的等待函數(shù)的時(shí)候,系統(tǒng)會(huì)產(chǎn)生一個(gè)中斷
2.當(dāng)線程喚醒的時(shí)候,這個(gè)線程會(huì)優(yōu)先去Apc隊(duì)列中調(diào)用回調(diào)函數(shù)
3.我們利用QueueUserApc,往這個(gè)隊(duì)列中插入一個(gè)回調(diào)
4.插入回調(diào)的時(shí)候,把插入的回調(diào)地址改為LoadLibrary,插入的參數(shù)我們使用VirtualAllocEx申請內(nèi)存,并且寫入進(jìn)去
使用方法:
1.利用快照枚舉所有的線程
2.寫入遠(yuǎn)程內(nèi)存,寫入的是Dll的路徑
3.插入我們的DLL即可
①丶首先先寫一個(gè)測試程序.
編寫一個(gè)MFC程序,這個(gè)程序的作用就是調(diào)用上面的SleepEx.
這個(gè)程序啥也不干,就是調(diào)用等待,注意第二個(gè)參數(shù)給TRUE,第二個(gè)參數(shù)決定了你的APC是否調(diào)用
②.編寫一個(gè)簡單的DLL用作注入使用
直接生成一個(gè)簡單的帶有DllMain的入口的DLL即可.
在DLL附加的時(shí)候,調(diào)用一個(gè)MessageBox
③丶編寫注入程序
我們要注入的是MFC,也就是寫的測試程序,那么現(xiàn)在我們直接打開進(jìn)程,打開線程,然后插入APC即可
在按鈕下面寫入我們的代碼.
//1.查找窗口
HWND hWnd = ::FindWindow(NULL, TEXT("APCTest"));
if (NULL == hWnd)
{
return;
}
/*2.獲得進(jìn)程的PID,當(dāng)然通用的則是你把進(jìn)程PID當(dāng)做要注入的程序,這樣不局限
于窗口了.這里簡單編寫,進(jìn)程PID可以快照遍歷獲取
*/
DWORD dwPid = 0;
DWORD dwTid = 0;
dwTid = GetWindowThreadProcessId(hWnd, &dwPid);
//3.打開進(jìn)程
HANDLE hProcess = NULL;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (NULL == hProcess)
{
return;
}
//4.成功了,申請遠(yuǎn)程內(nèi)存
void *lpAddr = NULL;
lpAddr = VirtualAllocEx(hProcess, 0, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (NULL == lpAddr)
{
return;
}
//5.寫入我們的DLL路徑,這里我寫入當(dāng)前根目錄下的路徑
char szBuf[] = "MyDll.dll";
BOOL bRet = WriteProcessMemory(hProcess, lpAddr, szBuf, strlen(szBuf) + 1, NULL);
if (!bRet)
{
return;
}
//6.根據(jù)線程Tid,打開線程句柄
HANDLE hThread = NULL;
hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwTid);
if (NULL == hThread)
{
return;
}
//7.給APC隊(duì)列中插入回調(diào)函數(shù)
QueueUserAPC((PAPCFUNC)LoadLibraryA, hThread, (ULONG_PTR)lpAddr);
CloseHandle(hThread);
CloseHandle(hProcess);
代碼很簡單,就這幾行,其實(shí)可以遍歷進(jìn)程快照,獲取線程的TID,然后判斷快照中的進(jìn)程PID是否和注入程序的PID相等,相等的話就可以注入了.
這里我寫死了,按理說根據(jù)PID就和TID就可以注入,這里我偷懶,根據(jù)窗口找進(jìn)程的TID和PID
看下程序結(jié)果
注意,我偷懶了,這幾個(gè)程序要放在一起,主要是DLL,要和被注入的程序放在一起
,打開注入程序和被注入程序,被注入程序要點(diǎn)擊按鈕,讓其執(zhí)行SleepEX
DLL功能被執(zhí)行了,我們用PCHunter看下被注入程序是否多了一個(gè)DLL
原創(chuàng)不易,如果你認(rèn)為寫的還好,請推薦加評論,好人一生平安,如果不太懂,可以評論,看到會(huì)回復(fù).
課堂資料:
鏈接:http://pan.baidu.com/s/1bo1M6BH 密碼:tcu8
博客園IBinary原創(chuàng) 博客連接:http://www.cnblogs.com/iBinary/
轉(zhuǎn)載請注明出處,謝謝
總結(jié)
以上是生活随笔為你收集整理的常见注入手法第二讲,APC注入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中配置JDK的环境变量
- 下一篇: FFI (语言交互接口(Foreign