setting CilBody.KeepOldMaxStack or MetadataOptions.Flags

4.4k Views Asked by At

While decompiling .net assembly using de4dot I am getting following message in console:

Error calculating max stack value. If the method's obfuscated, set CilBody.KeepOldMaxStack or MetadataOptions.Flags (KeepOldMaxStack, global option) to ignore this error

How do I set CilBody.KeepOldMaxStack or MetadataOptions.Flags?

1

There are 1 best solutions below

0
On

Maybe a bit late, but I ran into the same problem today, finding your open question while looking for a solution, and this is how I solved it - I hope it works for you, too:

// Working with an assembly definition
var ass = AssemblyDef.Load("filename.dll");

// Do whatever you want to do with dnLib here

// Create global module writer options
var options = new ModuleWriterOptions(ass.Modules[0]);
options.MetadataOptions.Flags |= MetadataFlags.KeepOldMaxStack;

// Write the new assembly using the global writer options
ass.Write("newfilename.dll", options);

If you want to set the flag only for a selection of methods that produce the problem before writing, just for example:

// Find the type in the first module, then find the method to set the flag for
ass.Modules[0]
    .Types.First((type) => type.Name == nameof(TypeToFind))
    .FindMethod(nameof(MethodToFind))
    .KeepOldMaxStack = true;

CilBody is maybe a bit confusing, if you're not too deep into the internal .NET assembly structures: It simply means the body object of the method that produces the problem, when writing the modified assembly. Obfuscators often try to confuse disassemblers by producing invalid structures, what may cause a problem when calculating the maxstack value before writing the assembly with dnLib. By keeping the original maxstack value, you can step over those invalid method structures.

In the context of de4dot it seems to be a bug, or the application is simply not designed to solve invalid method structures of obfuscated assemblies - in this case there's no solution for you, if the de4net developer won't fix/implement it, and you don't want to write a patch using the source code from GitHub.