Edit 2/5/2023
- This bug was fixed in dnSpyEx 6.3.0 after 1 week after the post, see commit.
- Source code with bug fix of dnSpyEx 6.3.0, see here, fixes were marked with comments.
What’s the plan
- Crash dnSpy while analyzing types same as BitMono do
Compability
- This bug was tested only on Mono Windows x64 5.10.1
- Works before dnSpyEx 6.3.0
Summary
You could say, there are plenty of ways how to crash the dnSpy, I agree with you, but I’ll show you one more way, I don’t know, fortunately, or unfortunately, most likely fortunately or maybe not, and maybe yes.
I asked ElektroKill to leave a star on BitMono to reveal the secret of the Dark Magic to him, I just wanted to agree on a good, but he rejected me, here’s what you did, ElektroKill, you brought me on it. Probably after this post this will be fixed in new versions of dnSpyEx, but, anyway this will take plenty of time to do this, because dnSpy is a very huge app, to fix something you need to fix everything :D, so, use it while this is alive, btw this is always useful in old versions of dnSpy. A bit later after the this post he agreed to leave a star to reveal the secret.
How it works?
- When we add the nested type to dont set any of the nested type accessibility attributes according to ECMA CIL standard nested types should always have one of them applied.
- According to dnSpy sources, this bug worked well because of the circumstances not suggested, see code.
Crash the dnSpy
First of all, create new NestedType and important to DO NOT specify the Public attributes, etc, somehow someone decided to decompile your precious app (this could be your ad: use BitMono to prevent such things), so continuing, and habitually trying to analyze where your things was used, there we will catch the hare.
As an example I’ll use AsmResolver and implementation from actual BitMono, which will crash the dnSpy, you could do the same with dnlib, nothing really changes between the code, but with AsmResolver try to write the Module with Advanced PE Image Building
to bypass possible errors while writing the module (I’m sure, everything is ok, you can write by default).
Create your own NestedType in Module
- This code adds new nested in Module
1 2
var moduleType = module.GetOrCreateModuleType(); moduleType.NestedTypes.Add(new TypeDefinition(string.Empty, "CrashdnSpy", TypeAttributes.Sealed | TypeAttributes.ExplicitLayout));
Prepare the all Module nested types
- This code changes the Attributes of all nested types inside a Module
1 2 3 4 5 6 7 8
var moduleType = module.GetOrCreateModuleType(); foreach (var type in module.GetAllTypes()) { if (type.DeclaringType == moduleType && type.IsNested) { type.Attributes = TypeAttributes.Sealed | TypeAttributes.ExplicitLayout; } }
Let’s catch the first hare
Write the module and drag-and-drop/specify the output file into dnSpy, search for the NestedType in Module type, then try to analyze it, and boom! Magic!
Congrats! You’ve catched the hare :)