我知道对此的任何答案都可能非常黑客。我全力以赴,我喜欢一点点地去看看有什么可能并且一路上学习。
我想编写一个程序来操作已知的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,它的元数据不是一个选项。我应该能够在没有反编译器/编译器的情况下做到这一点。我绝对想以编程方式执行此操作,因此Reflector不是一个选项。这可以可靠地完成吗?
答案 0 :(得分:3)
您可以使用ildasm执行此操作。它不是反编译器,而是反汇编程序。它将生成一个MSIL文本输出,您可以更改,然后使用ilasm重新编译。
编辑:我怎么能忘记? Mono.Cecil应该是伟大感兴趣的。
一些评论:
.cctor
是类构造函数的缩写,也就是静态构造函数,而不是实例构造函数。