前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >VC提前注入.net软件的方法

VC提前注入.net软件的方法

作者头像
方亮
发布2019-01-16 09:48:53
7410
发布2019-01-16 09:48:53
举报
文章被收录于专栏:方亮方亮

        在之前几节介绍了各种注入方法,但是这些方法存在一些缺陷——对.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——变相注入。这是个令人激动的方案。

代码语言:javascript
复制
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层去做还是很困难的。有些问题还是要切入驱动去做。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2012年04月18日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档