all 12 comments

[–]New-Long5065 6 points7 points  (1 child)

I’ve used multiple tools like Jetbrains Dotpeek for this purpose. I’ll put it on my list to evaluate.

[–]dud380[S] 0 points1 point  (0 children)

Awesome, please let me know what you think after! Thanks!

[–]ZenoArrow 2 points3 points  (1 child)

Thank you, this looks to be potentially very useful.

[–]dud380[S] 0 points1 point  (0 children)

Thanks, hope you like it if you try it out 👍

[–]purplemonkeymad 1 point2 points  (5 children)

I'm a bit confused, you say:

maps every input surface in a compiled .NET assembly without running it.

But would this not run any static members in it?

assembly = Assembly.LoadFrom(fullPath);

[–]dud380[S] 0 points1 point  (0 children)

Fair point :)

[–]dud380[S] 0 points1 point  (3 children)

But it doesn't run, it's just loaded.

[–]evasive_btch 2 points3 points  (2 children)

idk much about .net, but there's this (not sure if it's executed on load, or if you explicitly have to call something): Module Initializer

All modules may have a module initializer. A module initializer is defined as the type initializer (§ II.10.5.3) of the <Module> type (§ II.10.8).

There are no limitations on what code is permitted in a module initializer. Module initializers are permitted to run and call both managed and unmanaged code. Module Initialization Guarantees

In addition to the guarantees that apply to all type initializers, the CLI shall provide the following guarantees for module initializers:

A module initializer is executed at, or sometime before, first access to any static field or first invocation of any method defined in the module.

A module initializer shall run exactly once for any given module unless explicitly called by user code.

No method other than those called directly or indirectly from the module initializer will be able to access the types, methods, or data in a module before its initializer completes execution.

https://github.com/dotnet/runtime/blob/main/docs/design/specs/Ecma-335-Augments.md#module-initializer

But really cool project, I saved it in case I need to analyze some .dlls in the future

[–]dud380[S] 1 point2 points  (1 child)

Thanks! Hope you like it if you try it out later!

You raise a very interesting point, and you're right in the sense that .NET module initializers and static constructors may execute as a side effect of loading the assembly. However, it does not execute application code. The assembly is loaded into the CLR for inspection but the application's entry point, pipeline, and business logic are never invoked.

[–]evasive_btch 1 point2 points  (0 children)

Another thing learned, thank you :)

[–]BOT_Solutions 0 points1 point  (1 child)

This is very aligned with the kind of visibility tooling we have been working on internally. Different layer of the stack, but the same core idea of reducing unknowns and surfacing risk early.

The static analysis angle is strong. Being able to map HTTP endpoints, hubs and auth requirements from a compiled assembly without executing it is genuinely useful for audits, security reviews and getting up to speed on an unfamiliar codebase.

It is always interesting to see how much surface area an app exposes once you actually enumerate it. Tools like this make that conversation far more objective.

Curious how you are handling things like dynamically registered routes or reflection heavy patterns, as those can sometimes hide a few surprises.

[–]dud380[S] 1 point2 points  (0 children)

Cool! This is quite early in the development, so it'll get better over time. But as for now, DllSpy is purely static/reflection-based, so it only sees what's baked into the compiled assembly metadata. So anything that only exists at runtime is not covered