We run our .NET binaries through an obfuscator (with at least string obfuscation enabled), and later in the build process make some basic checks to validate this. I was surprised to notice that by changing strings from static readonly string
to const string
, the changed strings were now visible in plain text when viewing the disassembled code (via ildasm
output).
With regards to string obfuscation, what is the difference between const string
and static readonly string
?
EDIT: For the sake of example, here's a small program:
class Program
{
private const string MyConstString = "MyConstString";
private static readonly string MyStaticReadonlyString = "MyStaticReadonlyString";
static void Main(string[] args)
{
string myLocalString = "myLocalString";
Console.WriteLine(MyConstString);
Console.WriteLine(MyStaticReadonlyString);
Console.WriteLine(myLocalString);
Console.WriteLine("Hit <ENTER> to exit");
Console.ReadLine();
}
}
After looking at the .il code, the only value in plain text is for the const string
. This is true for two different obfuscation tools:
.field private static literal string a = "MyConstString" // using Dotfuscator
.field private static literal string '[SOH]' = "MyConstString" // using RedGate SmartAssembly
The first, const, is initialized during compile-time and the latter, readonly, initialized is by the latest run-time. The second difference is that readonly can only be initialized at the class-level. Another important difference is that const variables can be referenced through "ClassName.
readonly is a constant defined at runtime. const is used to create a constant at compile time. readonly field value can be changed after declaration. const field value cannot be changed after declaration.
const is a constant value, and cannot be changed. It is compiled into the assembly. static means that it is a value not related to an instance, and it can be changed at run-time (since it isn't readonly ). So if the values are never changed, use consts.
Static ReadOnly: A Static Readonly type variable's value can be assigned at runtime or assigned at compile time and changed at runtime. But this variable's value can only be changed in the static constructor. And cannot be changed further.
For const
fields, their value simply has to be included directly in the assembly, there is no way around that. That's because the compiler has to be able to get the value of such field, without executing any of your custom code.
With static readonly
fields, an obfuscator can use the static constructor to execute any code it wants, which means they can be obfuscated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With