VC提前注入.net软件的方法
在之前几节介绍了各种注入方法,但是这些方法存在一些缺陷——对.net程序注入无效。(转载请指明出处) 这个可以理解,.net程序的代码不是汇编,而是微软自定义的IL中间语言。.net CLR如同虚拟机,解析并执行这些中间语言。 于是我们之前所说的修改文件入口点的方法在此是一点都不奏效的,谁知道E8(Call)在IL中是啥! 远线...
在之前几节介绍了各种注入方法,但是这些方法存在一些缺陷——对.net程序注入无效。(转载请指明出处)
这个可以理解,.net程序的代码不是汇编,而是微软自定义的IL中间语言。.net CLR如同虚拟机,解析并执行这些中间语言。
于是我们之前所说的修改文件入口点的方法在此是一点都不奏效的,谁知道E8(Call)在IL中是啥!
远线程方法也存在问题。因为我们要提前注入,所以创建进程时使用了CREATE_SUSPENDED以挂起方式启动进程,但是当我们CreateRemoteThread后,会惊人的发现远线程没有执行,更惊人的是傀儡进程(.net程序进程)的主线程复活了。我汇编级调试CreateRemoteThread发现,对于win32程序,远线程创建时挂起,执行了一些操作后,ResumeThread然远线程执行。而对于.net程序,ResumeThread后主线程复活。
那么怎么解决呢?我们可以注入.net CLR。如果全局注入.nt CLR可行,那么结果也不是我们预期的,因为我们只要监控我们关心的进程,其他的进程我们不想关心。因为我是VC程序员,对C#等一窍不通,所以搞这个问题等于是跨界。还好感谢Code Project和Daniel Pistelli,找到.NET Internals and Code Injection 这篇文章。该文中介绍了一种办法,该方法的大致思路是模拟一个.net CLR,该CLR可以运行.net程序。于是我们可以确定我们要注入的.net程序的“边界”。这点非常重要,其实如果.net程序已经运行起来后,我们使用远线程注入还是成功的。只是我们要做的是提前注入,什么是“前”?多少是“前”?这个“边界”就在此起到非常重要的角色。因为我们模拟.net CLR的程序在准备模拟傀儡.net程序前,.net环境肯定是准备好了的。于是我们只要在模拟之前,让我们的模拟程序自己加载我们准备注入的DLL——变相注入。这是个令人激动的方案。
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace rbloader
{
static class Program
{
[DllImport("HookDll.dll")]
static extern void ExportFun();
[STAThread]
static void Main(string[] args)
{
ExportFun();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Exe Files (*.exe)|*.exe|Dll Files (*.dll)| *.dll|All Files (*.*)|*.*";
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
AppDomain ad = AppDomain.CreateDomain("subAppDomain");
ad.ExecuteAssembly(openFileDialog.FileName);
}
}
}
}
其中HookDll.dll是我前几篇文章中用到注入DLL文件,前篇文章的最后面提供了该文件工程下载地址。ExportFun是HookDll.dll中的导出函数,其拦截了CreateProcessW等函数。
其实这个方案也是存在缺陷的,因为它是模拟。我用模拟这个词,是因为真正的执行体是它自己而不是傀儡进程。傀儡进程文件只是模拟进程的输入信息。最直接的表现是:我们模拟进程叫A.exe,傀儡进程是B.exe,我们用A.exe运行B.exe,会发现进程列表中只存在A.exe而不存在B.exe。于是可以想到很多问题,比如我们在B.exe中获取当前进程的路径或者当前文件名,当A.exe运行B.exe后,相关逻辑获得是A.exe的路径和文件名。
虽然这是个很棒的东东,可惜其存在的缺陷也是很明显的。所以想提前注入所有进程(win32,.net,java),只在ring3层去做还是很困难的。有些问题还是要切入驱动去做。
工程代码。
更多推荐
所有评论(0)