Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for .NET bundled / self-contained applications #246

Closed
Washi1337 opened this issue Feb 8, 2022 · 6 comments
Closed

Support for .NET bundled / self-contained applications #246

Washi1337 opened this issue Feb 8, 2022 · 6 comments
Labels
dotnet Issues related to AsmResolver.DotNet enhancement
Milestone

Comments

@Washi1337
Copy link
Owner

Washi1337 commented Feb 8, 2022

Problem Description

Latest .NET compilers (.NET Core 3.1 and up) can produce self-contained applications that statically link multiple .NET modules and its dependencies together into a single native binary. AsmResolver currently can only interpret this as a native binary, and individual modules need to be extracted manually.

Proposal

Add support for reading and writing self-contained .NET executables.

Alternatives

It could be argued whether this is a task that AsmResolver should solve, or an end-user of AsmResolver instead. However, it is expected that more applications will be using this model in the future, which may warrant first-class support for it regardless.

Additional context

This issue may split up in smaller issues.

@Washi1337 Washi1337 added enhancement dotnet Issues related to AsmResolver.DotNet labels Feb 8, 2022
@0x410c
Copy link

0x410c commented Mar 11, 2022

any update regarding this?

@Washi1337
Copy link
Owner Author

Some initial research (links included in the references), the file format does not seem to be too complex and this seems doable yes. Furthermore, since .NET is open source, we can probably borrow many of the definitions used by the host app template itself.

One potential issue is that actually finding the start of the relevant headers might be complicated. The header is indicated by a signature (a hash code), and existing tooling (including the official one provided by MS) seems to just do a linear sweep on the binary to find this hash, and use the first occurrence that matches this signature. However, the CLR does not seem to be verifying this signature. This means that adversaries could replace/remove it, or inject additional fake signatures in the binary to throw off the linear sweep search. I verified this and the binary still works, even with these mods applied. AsmResolver will probably not support these cases fully then, but I am thinking of adding the possibility to let the user be able to provide a starting offset if such a situation arises.

@0x410c
Copy link

0x410c commented Mar 11, 2022

yes that will be great, later on user based on heuristics can provide input.

@0x410c
Copy link

0x410c commented Mar 14, 2022

also may be a little, not on topic, but when bundling the application there is also an option for ready to run, which i think is aot compilation, i observed assemblies aot conpiled are a little diffrent, which is not handled by dnlib, if u open the assembly and save it using dnlib it omits the aot compiled native code, and it fails to run or loaded. does asmresolver supports that? if not do u think it should be a seperate issue?

@Washi1337
Copy link
Owner Author

Washi1337 commented Mar 14, 2022

ReadyToRun header parsing and writing is indeed something that I have thought about including in AsmResolver. However, what is not currently considered in scope for the AsmResolver project is full disassembly and reassembly of native code, mainly due to the complexity of these architectures and the number of different architectures that PE supports. AsmResolver's main goal is to provide access to PE structures and build new PEs, not to add an interpretation of native code. This is also the reason why the NativeMethodBody class exposes the native code as bytes and not as instruction objects.

As far as I know, ReadyToRun is similar to ngen / crossgen in the sense that the binary still includes the original CIL code that was used to generate the native code. This is done in case the binary gets executed on an unsupported platform, then the runtime can fall back to "classical" execution using JIT. Removing the AOT native code upon building should therefore not impact the execution of the program itself, so I am not sure what caused your binary to break. That being said, I have very limited experience with other .NET inspection libraries such as dnlib, so my view on your case may be narrow. AsmResolver should construct proper binaries, even for ReadyToRun binaries, but this has not really been tested thoroughly given the novelty of this feature in .NET.

Regardless, I think ReadyToRun does warrant a separate issue since this feature is independent of whether the binary was bundled into one or not.

@0x410c
Copy link

0x410c commented Mar 14, 2022

last comment as it is irrelevant to this issue, i will create a test case to test if rtr binaries are supported and run after editing with asmresolver also it is obvious that the native code interpretation is not the forte of asmresolver but it should not mangle it if it is present. thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dotnet Issues related to AsmResolver.DotNet enhancement
Projects
None yet
Development

No branches or pull requests

2 participants