在 Olly 或 CFF Explorer 中修补 .Net 4.0 二进制文件

逆向工程 。网 修补
2021-07-09 21:11:01

我有一个用 C# .net 4.0 编译的挑战。我可以在 Reflector 中完全正常地看到源。我想改变来源。我想我通过修补二进制文件中的一些字节来做到这一点。

我面临的问题是在 Ildasm.exe 中加载二进制文件时,我无法将这些 ID_xxxx 地址转换为 RVA 或在 CFF Explorer 中找到它们对应的字节。以这种方式修补 .net exe 的典型方法是什么?我阅读了一些 lena 的教程,所以通常我会在 Olly 中加载它,我尝试了这个,但我看不到任何有用的代码,而且大多数操作似乎发生在各种 Windows .dll 中,而不是在 .exe 本身中。

如果有人能给我建议或给我指点教程,我将不胜感激。谢谢你。

3个回答

有一个名为Reflexil for Reflector的插件,可以很容易地修补 .NET 二进制文件。

Reflexil 是一个程序集编辑器,作为 Red Gate 的 Reflector 和 Telerik 的 JustDecompile 的插件运行。Reflexil 使用由 Jb Evain 编写的 Mono.Cecil,能够操作 IL 代码并将修改后的程序集保存到磁盘。Reflexil 还支持 C#/VB.NET 代码注入。

最近用一个例子在我的博客上写了一篇文章

考虑以下 .NET 4.5 控制台应用程序:

using System;

namespace ReversingMSIL101
{
    class Program
    {
        static void Main(string[] args) {
            if (args.Length > 0 && args[0] == "Secret")
                Authenticated();
            else
                Anonymous();
        }

        private static void Authenticated() {
            Console.WriteLine("Gold for the people!");
        }

        private static void Anonymous() {
            Console.WriteLine("Give them copper ...");
        }
    }
}

编译并打开 Ildasm 。我们将首先加载可执行文件(文件->打开)。完成后:转储它(文件->转储)。Ildasm 用一个很好的对话框来响应,因为我们想要尽可能多的信息,检查一切!

现在让我们看看我们反汇编的 IL 指令,启动您喜欢的编辑器并打开之前生成的转储。我们对if语句特别感兴趣,因为它控制提供的密码是否正确;请注意,您可以使用生成的注释轻松发现它。

//000009:             if (args.Length > 0 && args[0] == "Secret")
IL_0001:  /* 02   |                  */ ldarg.0
IL_0002:  /* 8E   |                  */ ldlen
IL_0003:  /* 69   |                  */ conv.i4
IL_0004:  /* 16   |                  */ ldc.i4.0
IL_0005:  /* 31   | 12               */ ble.s      IL_0019
IL_0007:  /* 02   |                  */ ldarg.0
IL_0008:  /* 16   |                  */ ldc.i4.0
IL_0009:  /* 9A   |                  */ ldelem.ref
IL_000a:  /* 72   | (70)000001       */ ldstr      "Secret" /* 70000001 */
IL_000f:  /* 28   | (0A)000011       */ call       bool [mscorlib/*23000001*/]System.String/*01000013*/::op_Equality(string, string) /* 0A000011 */
IL_0014:  /* 16   |                  */ ldc.i4.0
IL_0015:  /* FE01 |                  */ ceq
IL_0017:  /* 2B   | 01               */ br.s       IL_001a
IL_0019:  /* 17   |                  */ ldc.i4.1
IL_001a:  /* 00   |                  */ nop
IL_001b:  /* 0A   |                  */ stloc.0
IL_001c:  /* 06   |                  */ ldloc.0
IL_001d:  /* 2D   | 08               */ brtrue.s   IL_0027

我让读者完成逆向和分析指令的任务。我们将继续看最后一个。长话短说:如果第一个参数不是字符串,"Secret"我们将采用分支并最终在IL_0027

IL_0027:  /* 28   | (06)000003       */ call       void ReversingMSIL101.Program/*02000002*/::Anonymous() /* 06000003 */

很糟糕吧?因此,我们将简单地调整最后一条指令,此外将其替换为brfalse.s

IL_001d:  /* 2B   | 08               */ brfalse.s   IL_0027

就是这样,我们完成了!保存文件并打开一个 shell,导航到包含 IL 转储和问题的文件夹,以便将转储ilasm ReversingMSIL101.il重新组装成一个可执行文件!

现在是验证我们工作的时候了:

C:\Users\dna\Documents\Visual Studio 2012\Projects\ReversingMSIL101\ReversingMSIL101\bin\Debug>ReversingMSIL101.exe IdoNotKnow
Gold for the people!

尽管 dna 答案很好并且得到了很好的解释,但这对于现实世界的可执行文件通常是不切实际的,除非它们非常简单和简短。转储某些内容、更改它并“重新编译”很容易出错,尤其是在混淆的程序集等中。

我建议您下载Reflexil,它是一个Reflector插件:您可以通过 Reflector 查看您正在查看的功能的 IL,以非常简单的方式更改您需要更改的任何内容,然后只需保存修改后的 exe。这更不容易出错,因为您不是从头开始转储和重建程序。此外,您可以通过这种方式将任何内容注入程序集,无论是类、新方法还是结构。