远程注入Dll,在Dll中显示对话框

来源:互联网 发布:自动作曲编曲软件 编辑:程序博客网 时间:2024/05/17 23:05

这里做个备忘。

 

远程注入Dll

Exe部分:

CString GetCurrWorkingDir()
{//
获取当前目录
 CString strPath;
 GetCurrentDirectory(MAX_PATH,strPath.GetBuffer(MAX_PATH));
 strPath.ReleaseBuffer();
 return strPath;
}
void C
进程注入EXEDlg::OnBnClickedButton1()
{//
按下按钮执行注入

 // TODO:
在此添加控件通知处理程序代码
 CString str;
 this->m_ProcessName.GetWindowTextW(str);//
读取编辑框中输入的目标窗口标题
 HWND hStart = ::FindWindow(NULL,str);
 DWORD PID, TID;
 TID = ::GetWindowThreadProcessId (hStart, &PID);//
根据hwnd获取进程ID
 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,false,PID); //
打开目标进程

 
 CString dllname;
 this->m_DllName.GetWindowTextW(dllname);//
读取编辑框中输入的要注入的Dll的名字(dll在当前目录下)
 CString dllpath=GetCurrWorkingDir()+dllname;
 USES_CONVERSION;//
使用T2A之前需要用这一句,否则报错
 LPSTR lpszDll=T2A(dllpath);
 DWORD dwSize, dwWritten;
 dwSize = lstrlenA( lpszDll ) + 1;
 LPVOID lpBuf = VirtualAllocEx( hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE );
 if ( NULL == lpBuf )
 {
  CloseHandle( hProcess );
  //
失败处理
  MessageBox(_T("NULL == lpBuf"));
 }
 if ( WriteProcessMemory( hProcess, lpBuf, (LPVOID)lpszDll, dwSize, &dwWritten ) )
 {
  //
要写入字节数与实际写入字节数不相等,仍属失败
  if ( dwWritten != dwSize )
  {
   VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
   CloseHandle( hProcess );
   //
失败处理
   MessageBox(_T("
要写入字节数与实际写入字节数不相等"));
  }
  //
使目标进程调用LoadLibrary,加载
DLL
  DWORD dwID;
  //LPVOID pFunc =GetProcAddress(GetModuleHandle (_T("Kernel32")), "LoadLibraryA"); //
搞不懂,非要使用LoadLibraryA,使用LoadLibraryW就不能注入

  LPVOID pFunc = LoadLibraryA;
  HANDLE hThread = CreateRemoteThread( hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFunc, lpBuf, 0, &dwID );
  //
等待LoadLibrary加载完毕
  WaitForSingleObject( hThread, INFINITE );
  //
释放目标进程中申请的空间
  VirtualFreeEx( hProcess, lpBuf, dwSize, MEM_DECOMMIT );
  CloseHandle( hThread );
  CloseHandle( hProcess );
 }
 else
 {
  CloseHandle( hProcess );
  //
失败处理
  MessageBox(_T("WriteProcessMemory
写入失败"));
 }

 Dll部分:

win32 dll
中有DllMain,采取的处理:
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved )
{
 switch ( fdwReason )
 {
 case DLL_PROCESS_ATTACH:
  {
   MessageBox( NULL, _T("DLL
已进入目标进程。"), _T("信息"), MB_ICONINFORMATION );
  }
  break;
 case DLL_PROCESS_DETACH:
  {
   MessageBox( NULL, _T("DLL
已从目标进程卸载。"), _T("信息
"), MB_ICONINFORMATION );
  }
  break;
 default:
  break;
 }
 return TRUE;
}

MFC DLL
中无DllMain的处理:

BOOL C
进程注入DLL2App::InitInstance()
{//MFC DLL
的初始化,相当于处理win32 dll中的
DLL_PROCESS_ATTACH
 CWinApp::InitInstance();
 
 ::AfxMessageBox(_T("DLL
注入成功
"));
 return TRUE;
}
BOOL C
进程注入
DLL2App::ExitInstance()
{//
相当于处理win32 dll中的
DLL_PROCESS_DETACH
 ::AfxMessageBox(_T("
退出DLL注入
"));
 return CWinApp::ExitInstance();
}
====================================================================================
另外以下的做一个备忘,在MFC DLL中要处理DLL_THREAD_ATTACH   and   DLL_THREAD_DETACH的问题(自己找到MFC DLLDllMain函数修改):


如果只是简单的资源分配回收可参考如下方法实现  
  ●Initializing   Regular   DLLs  
  Because   regular   DLLs   have   a   CWinApp   object,   they   should   perform   their   initialization   and   termination   tasks   in   the   same   location   as   an   MFC   application:   in   the   InitInstance   and   ExitInstance   member   functions   of   the   DLL's   CWinApp-derived   class.   Because   MFC   provides   a   DllMain   function   that   is   called   by   _DllMainCRTStartup   for   PROCESS_ATTACH   and   PROCESS_DETACH,   you   should   not   write   your   own   DllMain   function.   The   MFC-provided   DllMain   function   calls   InitInstance   when   your   DLL   is   loaded   and   it   calls   ExitInstance   before   the   DLL   is   unloaded.  
   
 
如果就是想在常规MFC   DLL中使用DllMain函数参考以下
HOWTO//From   MSDN   Knowledge   Base  
  HOWTO:   How   to   Provide   Your   Own   DllMain   in   an   MFC   Regular   DLL  
  ●SUMMARY  
  By   design,   MFC   Regular   DLLs   have   a   default   DllMain   function   provided   automatically   by   MFC.   Regular   DLLs   should   not   provide   their   own   DllMain.   Any   initialization   which   is   necessary   when   the   DLL   is   loaded   should   be   done   in   the   InitInstance   member   function   of   the   one   CWinApp-derived   class   in   the   Regular   DLL.   Deinitialization   and   termination   code   should   go   in   the   ExitInstance   member   function.    
   
  However,   InitInstance   is   only   called   by   MFC's   DllMain   when   a   process   attaches   (DLL_PROCESS_ATTACH)   to   the   DLL   and   ExitInstance   is   called   only   when   a   process   detaches   (DLL_PROCESS_DETACH)   from   the   DLL.   If   it   is   necessary   to   handle   thread   attachment   to   and   detachment   from   (DLL_THREAD_ATTACH   and   DLL_THREAD_DETACH)   in   MFC   Regular   DLL,   the   Regular   DLL   will   need   to   provide   its   own   DllMain.   This   article   explains   how   to   do   it.    
  ●MORE   INFORMATION  
  When   a   Regular   DLL   is   created,   the   MFC   source   forcibly   links   in   the   code   for   the   source   file   /Msdev/Mfc/Src/Dllmodul.cpp.   Dllmodul.cpp   contains   most   of   the   code   added   to   a   Regular   DLL   to   support   MFC   in   that   DLL.   One   of   the   most   important   functions   in   Dllmodul.cpp   is   the   DllMain   function.    
   
  To   add   code   to   MFC's   DllMain,   copy   the   /Msdev/Mfc/Src/Dllmodul.cpp   source   file   to   your   project   directory,   and   include   the   copy   in   your   project.   This   copy   of   Dllmodul.cpp   will   be   compiled   and   linked   into   your   DLL   instead   of   the   Dllmodul.cpp   in   the   Mfc/Src   directory,   so   changes   to   the   DllMain   in   it   will   show   up   in   the   final   DLL.    
   
  The   primary   caveat   is   that   this   is   not   a   recommended   solution   and   should   only   be   used   when   absolutely   necessary.   Any   changes   to   the   code   in   Dllmodul.cpp   will   undoubtedly   have   unpredictable   results.   Add   code   only,   do   not   remove   or   modify   the   existing   code.    
   
  For   regular   DLLs   that   use   MFC   in   the   Shared   Lib,   the   module   state   should   be   set   at   the   beginning   of   any   added   code   and   restored   before   returning   from   DllMain.   Refer   to   the   sample   code   in   this   article   for   an   example   of   a   DllMain   that   handles   the   DLL_THREAD_ATTACH   and   DLL_THREAD_DETACH   notifications   and   properly   switches   the   module   state   as   necessary.    
   
  Additional   care   must   be   taken   when   relying   on   DllMain   being   called   with   DLL_THREAD_ATTACH   and   DLL_THREAD_DETACH   because   of   the   following   conditions:    
   
   
  When   a   thread   is   created   in   a   process,   the   system   calls   DllMain   with   a   value   of   DLL_THREAD_ATTACH   for   each   of   the   DLLs   mapped   into   into   the   process.   However,   if   a   process   has   several   threads   running   in   it   when   a   new   DLL   is   mapped   into   it,   DllMain   isn't   called   with   a   DLL_THREAD_ATTACH   value   for   any   of   the   existing   threads.    
  DllMain   is   not   called   with   a   value   DLL_THREAD_ATTACH   for   the   process's   primary   thread.    
  On   thread   termination   (by   a   call   to   ExitThread),   DllMain   is   called   with   a   value   of   DLL_THREAD_DETACH   for   each   of   the   DLLs.   DllMain   is   not   called   with   DLL_THREAD_DETACH   for   any   thread   unless   a   thread   terminates   by   calling   ExitThread.    
  If   a   thread   terminates   due   to   a   call   to   TerminateThread,   DllMain   isn't   called   with   a   value   DLL_THREAD_DETACH.    
  It   is   possible   for   a   thread   in   a   process   to   call   LoadLibrary   to   load   a   DLL   causing   a   call   to   DllMain   with   DLL_PROCESS_ATTACH,   and   then   on   thread   termination,   cause   a   call   to   dllMain   with   DLL_THREAD_DETACH   without   ever   calling   DLL_THREAD_ATTACH.   It   is   therefore   best   that   the   thread   that   calls   LoadLibrary   also   call   FreeLibrary.    
  NOTE:   MFC   CWnd   objects,   CDC   objects,   CMenu   objects,   GDI   objects,   and   CImageList   objects   are   restricted   to   a   per-thread,   per-module   basis.   In   other   words,   MFC   objects   created   in   one   module   or   thread   cannot   be   passed   to   and/or   used   in   a   different   module   or   thread.   This   has   special   relevance   for   any   code   added   to   handle   DLL_THREAD_ATTACH   or   DLL_THREAD_DETACH   in   DllMain   because   DllMain   is   called   for   these   reasons   with   different   threads.   CWnd   objects,   for   instance,   created   in   DllMain   during   DLL_PROCESS_ATTACH   or   in   InitInstance   will   not   be   valid   during   DLL_THREAD_ATTACH.    

Dll中显示对话框、在dll中处理消息(疑惑中):

 dll注入后,要显示一个对话框(无模式对话框)
BOOL C
进程注入DLL2App::InitInstance()
{
 CWinApp::InitInstance();
 
 ::AfxMessageBox(_T("DLL
注入成功
"));
  //
dll类的头文件中定义了
CDllDialog *pDllDialog;
//
新建一个线程用于创建窗口,直接在这里创建的话在对话框处理消息循环时这里将一直处于阻塞而不能继续执行

::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)CreateDialogBox,(LPVOID)pDllDialog,NULL,NULL);
 return TRUE;
}
BOOL C
进程注入DLL2App::ExitInstance()
{
 ::AfxMessageBox(_T("
退出DLL注入
"));
 pDllDialog->DestroyWindow();/*
运行是提示错误说pDllDialog指向NULL,不能操作,还没对pDllDialog做其它任何处理,这里确指向NULL了,不明!如果将pDllDialog定义为static的话则出现错误:错误 1 error LNK2001: 无法解析的外部符号 "public: static class CDllDialog * C进程注入DLL2App::pDllDialog" (?pDllDialog@C进程注入DLL2App@@2PAVCDllDialog@@A) 进程注入
DLL2.obj ”*/
 delete pDllDialog;
 return CWinApp::ExitInstance();
}
void CreateDialogBox(CDllDialog *pDllDialog)
{
 pDllDialog=new CDllDialog;
 pDllDialog->Create((UINT)IDD_DLL_DIALOG);//,pwnd);//
据说要加上第二个参数设置父窗口,可是试验后没任何不同

 pDllDialog->ShowWindow(SW_SHOW);
 ::AfxMessageBox(_T("
窗口出来了"));/*弹出MessageBox时确实看到要创建的对话框已经创建显示出来了,但是一旦按下确定关闭这个MessageBox后刚创建的对话框也跟着消失了,不明!如果没这一句甚至根本看不到对话框的出现,因为刚出现就消失了。为了解决这个问题,在对话框中添加消息循环*/
}

BOOL CDllDialog::OnInitDialog()
{
 CDialog::OnInitDialog();

 this->ShowWindow(SW_SHOW);
 this->UpdateWindow();

 MSG msg;
 while(::GetMessage(&msg,NULL,0,0))
 {
  TranslateMessage(&msg); //
消息进行必要的处理转换。

  DispatchMessage(&msg); /*
调用WinProc,将msg的各项信息传递给WinProc【问题:写好了LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam),但是在WinProc中就是接收不到任何的消息,不明!】*/
 }/**/

 return TRUE;  //
除非将焦点设置到控件,否则返回
TRUE
}

如果是在win32 dll中则创建线程使用
CreateDialogW(hinstDLL,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DialogProc);//
创建无模式对话框
然后在对话框处理函数DialogProc中进行消息循环。

不论是在MFC DLL还是Win32 DLL中,做了消息循环后如果是使用
TranslateMessage(&msg); //
消息进行必要的处理转换。
DispatchMessage(&msg); //
调用WinProc,将msg的各项信息传递给WinProc
则接收不到任何消息,如果是在BOOL CDllDialog::OnInitDialog()DialogProc中做消息判断并处理则对话框中的控件(如确定”“取消按钮)将失去响应。

 

原创粉丝点击