語言:VS2008
代碼實現功能:建立一個MFC Regular Dll連結庫。要求連結庫注入到目標進城後能調出Dll內部的MFC視窗.目標進程為第三方進程程式
步驟:
1,建立項目->MFC Dll;
2,在自動產生的項目代碼中添加 Dialog對話方塊資源.
3,為對話方塊資源添加 視窗類別
4,聲明一個呼出視窗函數.startmythread.此函數可以匯出也可以不匯出 匯出需要首碼:。此函數用於自己的程式 CreateRemoteThread 中遠程線程調用.使用 extern "C" __declspec(dllexpot) ;
5,在startmythread 調用::CreateThread()函數建立線程.此線程實現函數thr內部為建立視窗和訊息迴圈的代碼.
6.建立非模態視窗 void ShowTreeDlg()
{
//=(HWND)329282;
//HWND hMainWnd=FindWindowA("#32770","CheckMyDriver");//通過遍曆視窗方式擷取目標進程主視窗控制代碼
HWND hMainWnd=GetHwndByProcessId(GetCurrentProcessId());//通過進程擷取目標主視窗進程.注意:GetCurrentProcessId為目標進程Pid
if(hMainWnd!=0)
{
char a[10]={0};
itoa((ULONG)hMainWnd,a,10);
// MessageBoxA(NULL,(LPSTR)a,"",0);
}
else
{
//MessageBoxA(NULL,"調用失敗","",0);
return;
}
AFX_MANAGE_STATE(AfxGetStaticModuleState());//這句必不可少
cDlg=new CMDlg;
CWnd *pMainWnd=CWnd::FromHandle(hMainWnd);
ASSERT(pMainWnd);
BOOL retValue=cDlg->Create(IDD_DIALOG1,pMainWnd);
if (!retValue)
{
//MessageBoxA(NULL,"error","1",MB_OKCANCEL);
}
cDlg->ShowWindow(SW_SHOW);
}
7,線程函數thr實現
thr()
{
ShowTreeDlg();
MSG msg;//訊息迴圈 如果dll宿主程式為自己調用的程式 訊息迴圈可以不需要 如果宿主程式為第三方進程 如果沒有訊息迴圈 調用後視窗會閃退.
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
8,當自己的程式遠程注入dll後 需要通過startmythread遠程call此函數載入視窗.所以需要把startmythread函數地址傳給自己的程式
傳入方法:使用::PostMeaage(hwnd,message,w,l).hwnd可以通過Findwindow擷取 ..message訊息類型需要自己定義.WM_USER 以上的訊息值.
為什麼不使用SendMessage。本人exe程式和dll程式會卡死.
9 把8裡面的實現代碼放到CMyApp::InitInstance()內部.自己exe程式就會接收到startmythread函數地址.然後通過CreateReMoteThread調用之.
注意的問題:
1,為什麼建立視窗要放線上程裡.因不放線上程裡後面的訊息迴圈會把dll卡死.從而整個進程無響應.
2,為什麼不把startmythead直接放在InitInstatce調用.因為在其內部建立線程dll同樣會卡死.
看似一個簡單的dll視窗調用 花了兩天時間才搞定.新手傷不起.