将托管dll注入到非托管进程中
为什么要写这篇文章
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:
view sourceprint?01 int _tmain(int argc, _TCHAR* argv[])
02 {
03 int pid;
04 void *pNativeDllRemote;
05 FARPROC pLoadLibrary;
06 TCHAR szNativeDllPath[_MAX_PATH]=_T("D:\\Code\\InjectDemo\\Debug\\NativeDll.dll");
07
08 cout<<"input the process id to inject"<<endl;
09 cin>>pid;
10
11 HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,0,pid);
12 if(hProcess==0)
13 return 1;
14
15 HMODULE hKernel32 = ::GetModuleHandle(_T("Kernel32"));
16 if(sizeof(TCHAR)==2)
17 pLoadLibrary= ::GetProcAddress(hKernel32,"LoadLibraryW"); //if path is unicode, use "LoadLibraryW"
18 else
19 pLoadLibrary= ::GetProcAddress(hKernel32,"LoadLibraryA");
20 pNativeDllRemote=VirtualAllocEx(hProcess,NULL,sizeof(szNativeDllPath),MEM_COMMIT,PAGE_READWRITE);
21 ::WriteProcessMemory(hProcess,pNativeDllRemote,(void*)szNativeDllPath,sizeof(szNativeDllPath),NULL);
22 HANDLE hThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)pLoadLibrary,pNativeDllRemote,0,NULL);
23 ::WaitForSingleObject(hThread,INFINITE);
24 //DWORD exitcode;
25 //GetExitCodeThread(hThread,&exitcode);
26 ::CloseHandle(hThread);
27 return 0;
28 }
相关新闻>>
- 发表评论
-
- 最新评论 更多>>