【问题标题】:Post compilation, manipulate a string in a .net exe?编译后,在 .net exe 中操作字符串?
【发布时间】:2014-11-28 21:57:45
【问题描述】:

我知道这个问题的任何答案都可能非常老套。我完全赞成,我喜欢稍微突破界限,看看有什么可能并在此过程中学习。

我想编写一个程序来操纵已知的 exe 以更改其中的字符串。我目前有一个非常简单的 C# 程序,即已知的 exe:

using System;

namespace Target {
    class Program {

        public static String str = "TESTSTRING";

        static void Main(string[] args) {
            Console.WriteLine(str);
        }
    }
}

编译后,在十六进制编辑器中,我看到字符串的第一个字母位于字节 1898。它似乎从那里以 Unicode 存储。

一点编译器优化将字符串直接放在Console.WriteLine 调用中,并且似乎在调用一些构造函数(至少我认为.cctor 是这样)。我玩弄过其他相同长度的琴弦,以确保我知道一切是什么。我编写了一个应用程序,成功地将TESTSTRING 替换为XXXXXXXXXX(注意它们的长度相同)并运行修改后的exe。效果很好。

但是,如果我尝试用不同长度的字符串替换该字符串,则输出 exe 将无法运行。我发现字符串之前的字节似乎包含长度。它似乎是 unicode 字符串 + 1 的字节数(我不知道 +1 的用途,可能是空终止符?)。但是,如果我用适当的更新值替换该长度,它仍然不会运行。字符串结尾之后似乎有几个字节对于不同长度的字符串是不同的。我的猜测是构造函数类似于new String(...),而那些其他字节是构造函数的其他参数(第一个参数是char[]byte[],前面是它的长度),但我不能来解释一下其他参数具体是什么。

我知道我通常会破坏一些东西,但我很好奇这种可能性。关于 .Net exe 的结构,我不知道什么能让我做到这一点?用另一个不同长度的字符串替换已编译的 EXE 中的一个字符串?另外我如何解释长度超过 127 的字符串?任何超过此长度的内容都会影响存储字符串长度所需的字节数。

我希望能够使用任意替换字符串来做到这一点。因此,预编译一个特定的字符串,然后用该预编译的字符串修补 exe,它的元数据不是一种选择。我应该能够在没有反编译器/编译器的情况下做到这一点。我绝对想以编程方式执行此操作,因此反射器不是一个选项。这可以可靠地完成吗?

【问题讨论】:

  • 正如 Lucas 在他的回答中所写,操作 .Net exe 的方法是使用 ILDasm.exe,修改 IL 代码,然后使用 ILAsm.exe 重新组装。这有时被称为“往返”。我自己使用它来对我的 C# 程序进行各种后期构建操作。你能解释一下为什么你不想使用反编译器/编译器吗?
  • 例如,我以这种方式所做的修改之一是混淆(非常简单和原始地)我程序中的所有字符串。如果您希望我写更多详细信息作为答案,我可以这样做。
  • 可能没有一个。上帝禁止这种黑客将其用于生产代码类型的环境或客户端机器,不能保证任何类型的编译器或汇编器的存在,并且在项目中下载或包含一个似乎有很多额外的资源。我可以整天操纵源代码字符串。这是关于我自己设定的低级别挑战。
  • 当我想在客户端机器上执行此操作时,我想到的一个可怕的例子是在 C# 中使用某种解释器时。 Javascript .Net 可以在 C# 运行时(AT 运行时,而不是某种 javascript 编译器)期间在上下文中运行 javascript 代码,我想知道是否可以将 javascript 注入使用 Javascript .Net 运行它的 exe 中。它没有提供太多好处,但似乎没有什么是不可能的。为了克服挑战而挑战。我目前的珠穆朗玛峰。
  • 嗯,但您意识到在生产环境中尝试在客户端计算机上操作 exe 可能会涉及文件访问授权问题和/或被常驻防病毒程序标记为病毒。无论如何,祝你好运。

标签: .net executable


【解决方案1】:

您可以使用ildasm 执行此操作。它不是反编译器,而是反汇编器。它将生成一个 MSIL 文本输出,您可以更改然后使用 ilasm 重新编译。

编辑:我怎么会忘记? Mono.Cecil 应该是您非常感兴趣的。


一些备注:

  • .cctor类构造函数 又名 静态构造函数 的缩写,而不是 实例构造函数
  • 字符串的内部表示仍然以空值结尾,这就是您在文件中看到长度 + 1 的原因。这仅用于更轻松的互操作性 (P/Invoke)
  • 更改长度和偏移字节不起作用,因为我猜它会破坏文件中存储偏移量的其他一些数据。您必须更新存储在 exe 中的每个偏移量才能使其正常工作。这可能意味着...拆卸它。这就是 ildasm 的用途。

【讨论】:

  • 什么样的偏移量会被搞砸?
  • 我不知道 PE 文件格式和 MSIL 二进制格式,但是在二进制文件中通常可以有很多偏移量。至少有一个非常重要的偏移量:程序入口点的偏移量。然后,代码和元数据之间存在偏移。您必须找到 PE 格式、CLR 元数据格式和 MSIL 格式的描述才能了解它们。
  • @Corey 我完全忘记了 Mono.Cecil - 看看吧!
  • 提示: 使用 ilasm 重新组装可能无法{{需要引用}} 编写源代码VC++(我记得几年前在非托管代码上失败了!我完全离开了 .net,所以不确定它是否仍然一样!)顺便说一句,我确实注意到 OP 专门针对 C#,因此是“提示” . :)
  • @Fr0zenFyr 是的,它不适用于 混合模式 程序集。如果你用/clr:pure 编译 VC++,它应该可以工作,但是在这种模式下使用 C++/CLI 并没有多大意义。
猜你喜欢
  • 2011-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-20
  • 2018-10-25
  • 1970-01-01
  • 2010-10-23
相关资源
最近更新 更多