<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      將托管dll注入到非托管進程中

      Binhua Liu

      Demo源代碼 457K

       

      為什么要寫這篇文章

      1,如果你想注入帶窗體的dll,C#寫界面比C++容易的多;

      2,或許你想利用.net的某些功能,比如利用.Net Remoting從外部控制被注入的dll;

      3,或許你是一個C#程序員,使用C#的時候總感覺更舒適些,比如筆者。同時,你希望必要時也能在宿主中調用C++函數,提供更大的靈活性,本文的方法也能做到。

       

      注入托管dll的不同之處

      首先,為什么托管dll 不能像非托管dll那樣用LoadLibrary注入? 我們知道,.net語言,如C#,VB.net等,都是運行在CLR(公共語言運行時)上的,也就是我們通常所說的虛擬機,而我們所說的非托管進程是沒有加載虛擬機的。那為什么托管dll一定要在CLR上運行?托管dll雖然符合windows的PE格式規范,但是代碼是以IL的形式保存在.Text 區的,而不是機器碼,CLR會在運行時JIT編譯成機器碼再交給操作系統執行,這也就為什么托管代碼稱之為”托管”的意義。

      所以,要想注入托管dll,首先需要在目標進程中啟動CLR,然后讓CLR來加載managed dll。

       

      注入的方式

      首先,我們注入一個非托管的dll,再通過它加載CLR并加載托管dll。所以工程需要3個模塊:注入器,一個注入的非托管dll和注入的托管dll。

      我們首先看如何注入非托管dll,這里是通過遠程線程來實現的,如果你已經熟悉這個技術,可以跳過:

      InjectDemo.cpp:

      int _tmain(int argc, _TCHAR* argv[])
      {
      	int pid;
      	void *pNativeDllRemote;
      	FARPROC pLoadLibrary;
      	TCHAR szNativeDllPath[_MAX_PATH]=_T("D:\\Code\\InjectDemo\\Debug\\NativeDll.dll");
      
      	cout<<"input the process id to inject"<<endl;
      	cin>>pid;
      	
      	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,0,pid);
      	if(hProcess==0)
      		return 1;
      	
      	HMODULE hKernel32 = ::GetModuleHandle(_T("Kernel32"));
      	if(sizeof(TCHAR)==2)
      		pLoadLibrary= ::GetProcAddress(hKernel32,"LoadLibraryW"); //if path is unicode, use "LoadLibraryW"
      	else
      		pLoadLibrary= ::GetProcAddress(hKernel32,"LoadLibraryA");
      	pNativeDllRemote=VirtualAllocEx(hProcess,NULL,sizeof(szNativeDllPath),MEM_COMMIT,PAGE_READWRITE);
      	::WriteProcessMemory(hProcess,pNativeDllRemote,(void*)szNativeDllPath,sizeof(szNativeDllPath),NULL);
      	HANDLE hThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pLoadLibrary,pNativeDllRemote,0,NULL);
      	::WaitForSingleObject(hThread,INFINITE);
      	//DWORD exitcode;
      	//GetExitCodeThread(hThread,&exitcode);
      	::CloseHandle(hThread);
      	return 0;
      }

      這段代碼通過遠程線程注入Native.dll,網上這方面文章很多,也可以根據不同的需要采用服務輸入法或者Hook等方式注入。需要注意的是,我們通過GetProcAddress獲取LoadLibrary的函數地址,事實上獲取的是注入器中該函數的虛擬地址,而不是宿主的。由于LoadLibrary函數位于系統dll中,在每個進程中都被加載到相同的虛擬地址上,所以我們才能這么做。LoadLibrary函數的參數,dll的路徑字符串需要通過VirtualAllocEx和WriteProcessMemory在宿主進程上創建,而不能把注入器上的字符串地址傳給LoadLibrary。總之,必須記住的一點是,遠程線程是在另一個虛擬地址空間上執行的,遠程執行的函數體本身或者他引用的虛擬地址都不能是注入器進程中的虛擬地址,而必須是宿主進程的虛擬地址。

       

      再來看被注入的非托管的NativeDll.dll的代碼:

      NativeDll.cpp:

      #include <windows.h>
      #include "stdafx.h"
      #include "NativeDll.h"
      #include "MSCorEE.h"
      #include "metahost.h"
      
      DWORD CALLBACK StartTheDotNetRuntime(LPVOID lp)
      {
      
      	HRESULT hr = S_OK;
      	ICLRMetaHost    *m_pMetaHost = NULL;
      	ICLRRuntimeInfo *m_pRuntimeInfo = NULL;
      	ICLRRuntimeHost    *pClrHost = NULL;
             
      	hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*) &m_pMetaHost);
      	if (hr != S_OK) 
      		return hr;
      	hr = m_pMetaHost->GetRuntime (L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*) &m_pRuntimeInfo);
      	if (hr != S_OK)
      		return hr;
      	hr = m_pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*) &pClrHost );
      		   if (FAILED(hr)) return hr;
      	HRESULT hrStart = pClrHost->Start();
      
          DWORD dwRet = 0;
          hr = pClrHost->ExecuteInDefaultAppDomain(
              L"d:\\Code\\InjectDemo\\Debug\\ManagedDll.dll",
              L"ManagedDll.Class1", L"Start", L"nothing to post", &dwRet);
      
          hr = pClrHost->Stop();
      
          pClrHost->Release();
      
      	return S_OK;
      }
      
      
      BOOL WINAPI DllMain(
        HINSTANCE hinstDLL,
        DWORD fdwReason,
        LPVOID lpvReserved
      )
      {
      switch(fdwReason)
          {
            case DLL_PROCESS_ATTACH:
      		 CreateThread(0,0,StartTheDotNetRuntime,0,0,0);
      		  break;
      	  case DLL_THREAD_ATTACH:
      		 break;
      	  case DLL_THREAD_DETACH:
      		 break;
            case DLL_PROCESS_DETACH:
              break;
            default:
              break;
          }
      	return true;
      }

       

      這段代碼是本文的重點,我們在NativeDll.dll的DllMain函數中創建一個線程來加載加載CLR,CLR事實上是一組COM服務器,為了可以調用它們,我們需要引用頭文件 "MSCorEE.h"和"metahost.h",并在鏈接器中添加對MSCorEE.lib的鏈接。 GetRuntime函數用于指定加載的CLR的版本,需要填寫完整的版本號,根據我的測試,2.0和4.0可以成功加載,但是3.5似乎不行。在成功啟動CLR后,執行ExecuteInDefaultAppDomain加載指定的托管dll并執行它的靜態方法。執行結束后,停止并釋放CLR。

       

      然后,在托管的ManagedDll.dll中,我們可以打開一個窗口:

      Class1.cs:

      using System.Windows.Forms;
      
      namespace ManagedDll
      {
          public class Class1
          {
              public static int Start(string argument)
              {
                  Application.Run(new MainForm());
                  return 0;
              }
          }
      }

      或者開啟一個.net Remoting服務,這樣注入器就可以在外部控制該進程了:

      using System.Threading;
      using System.Runtime.Remoting; 
      
      namespace ManagedDll
      {
          public class Class1
          {
              public static int Start(string argument)
              {
                  RemotingConfiguration.Configure("ManagedDll.dll.config");
                  while (true)
                  {
                      Thread.Sleep(1000);
                  }
              }
          }
      }

       

      需要注意的是,使用.net Remoting,你必須把托管dll放在和宿主同一個目錄下,否則反射機制會失敗。這種注入方式提供了很大的靈活性,你可以把邏輯代碼寫在ManagedDll.dll中,也可以寫在NativeDll.dll中并導出,在ManagedDll.dll中引用,再通過窗口或者.net Remoting調用。

      參考

      http://www.codingthewheel.com/archives/how-to-inject-a-managed-assembly-dll

      http://windows-internals.blogspot.com/2009/02/injecting-code-using-createremotethread.html

       

      Binhua Liu原創,寫于2011/8/4。

      posted @ 2011-08-04 16:03  Binhua Liu  閱讀(20299)  評論(11)    收藏  舉報
      主站蜘蛛池模板: 国产亚洲欧美精品久久久| 伊人久久大香线蕉av色婷婷色| 狼色精品人妻在线视频| 国产精品香港三级国产av| 国外av片免费看一区二区三区| 亚洲人成小说网站色在线| brazzers欧美巨大| 动漫AV纯肉无码AV电影网| 国产一区二区日韩在线| 成人网站网址导航| 精品久久人人妻人人做精品| 东方四虎av在线观看| 丁香婷婷在线观看| 亚洲精品一区二区妖精| 国内精品久久人妻无码妲| 日韩有码中文字幕国产| 国产亚洲精品岁国产精品| 性色av一区二区三区精品| 老熟妇乱子交视频一区| 亚洲精品无码久久久影院相关影片| 亚洲欧美日韩人成在线播放| 成人一区二区人妻不卡视频| 亚洲av永久无码精品成人| 广灵县| 亚洲精品香蕉一区二区| 九九热在线免费视频精品| 国产精品视频全国免费观看| 色爱综合激情五月激情| 国产办公室秘书无码精品99| 国产精品一区在线蜜臀| 777米奇色狠狠888俺也去乱| 男女啪啪高清无遮挡免费| 在线播放国产精品三级网| 无码专区 人妻系列 在线| 天天澡日日澡狠狠欧美老妇 | 亚洲男人电影天堂无码| 国内自拍视频一区二区三区| 极品人妻videosss人妻| 日韩精品中文字幕国产一| 国产一区二区在线有码| 少妇被多人c夜夜爽爽av|