我可以更改 C# 中的常量值吗?

问题描述 投票:0回答:6

我需要针对无法重新编译的遗留 .NET dll 进行此破解。一些黑客例如使用反射等

c# reflection
6个回答
17
投票

如果程序集未签名,那么您可以反汇编并修改 IL 并重新编译,或者反汇编到源代码并修改并重新编译。我会找到合适的链接......

要反汇编到源代码,您可以使用reflector(警告-不再免费)和Dennis Bauers插件,或者您可以使用reflexil,这是反射器的另一个插件,它带有完整的VB / C#编辑器和智能感知允许代码直接从 Reflector 注入。

要反汇编为 IL,您可以使用 ILSpy 反汇编器或 MSILDissasembler

正如其他人指出的那样,尽管您要仔细考虑这样做的含义。您可能意识到它可能有更多的连锁反应。

另一件非常重要的事情是,如果常量被引用您正在重新编译的 dll 的其他 dll 使用,这些 dll 在不重新编译的情况下将看不到常量的新值

这是因为当某些东西被定义为常量时,“常量”值会作为优化被烘焙到引用的 dll 中(因此不需要每次使用时都在引用的 dll 中查找)AT BUILD TIME,因此在任何引用“常量”的库中实际上从未看到对“常量”值的更改。有关更多详细信息,请参阅此问题和答案。


11
投票

添加 Stecya 的答案:
const 变量的值将插入到使用它的任何地方。这意味着引用旧程序集并使用该常量的所有程序集也需要重新编译,以反映 const 变量的更新值。顺便说一句,这就是为什么始终通过公共接口中的普通属性公开常量值是个好主意的原因。


3
投票

您无法更改 const,因为它是编译时计算的。唯一的方法是更改 const 文件,即修改旧程序集


3
投票

反射不起作用,因为该值以反射无法修改的方式硬编码到应用程序的字节代码中。

如果没有代码签名,请使用十六进制编辑器或ILDasm修改常量的值。

如果是代码签名的,那么如果不进行代码签名,您就无法解决此问题。

如果您正在编辑已编译的程序集,请小心。可能有法律原因您也不能这样做。


1
投票

const 值在编译时被替换为文字,因此您不太可能在不重新编译的情况下更改它


0
投票

使用传统方法无法更改常量值,但可以使用指针

将该方法标记为

unsafe
,使用
fixed
关键字将字符串固定在内存中并获取指向字符数据的指针:

static unsafe void Main(string[] args)
{
    // Get the string from an external .NET DLL or for simplicity
    // from a local variable and change it.
    string text = ClassLibrary.Class1.ConstValue;
    // string text = "xyz";
    fixed (char* ptrText = text)
    {
        // Print initial state
        Console.WriteLine($"Text: {text}");
        Console.WriteLine($"The address of text is: {(IntPtr)ptrText}");

        // Modify the string
        char* p = ptrText;
        for (var i = 0; i < text.Length; i++)
        {
            *p = '?';
            p++;
        }

        // Print final state
        Console.WriteLine($"Text: {text}");
        Console.WriteLine($"The address of text is: {(IntPtr)ptrText}");
    }
}

注意修改前后内存地址是一样的。 不要忘记选中 Project Properties > Build > General 部分中的 Unsafe code 复选框。

© www.soinside.com 2019 - 2024. All rights reserved.