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 ReadyToRun (R2R) Format #294

Closed
Washi1337 opened this issue Apr 10, 2022 · 6 comments
Closed

Support for ReadyToRun (R2R) Format #294

Washi1337 opened this issue Apr 10, 2022 · 6 comments
Labels
enhancement pe Issues related to AsmResolver.PE

Comments

@Washi1337
Copy link
Owner

Washi1337 commented Apr 10, 2022

Problem Description

ReadyToRun (R2R) is one of the native executable code formats that was introduced in .NET Core 3.1. It is used to store precompiled CIL code to avoid overhead introduced by the JIT compiler, thus improving startup times of applications. Since support for self-contained application bundles got recently added to AsmResolver (#279), and assemblies within these bundles often contain R2R content, this is probably something we should add first-class support for in AsmResolver as well.

Proposal

Add read/write support for the R2R file format, by changing the IDotNetDirectory.ManagedNativeHeader to something that exposes the R2R structures stored in the PE image. AsmResolver should then expose the native code within these structures as byte[], ISegment or even CodeSegment. Note that AsmResolver should not be responsible for actually generating native code; its only task is to expose it and make it possible add/modify/remove pieces.

Additional context

Since we probably want to support other types of native headers (e.g. NGEN images) we should keep this in mind when deciding the type of IDotNetDirectory.ManagedNativeHeader. Since the type of header is identified by a signature at the very beginning, we can probably adopt a similar structure that was used in e.g. CodeViewDataSegment, where we define one base ISegment class with a Signature property used to distinguish between different implementations of the native header.

@Washi1337 Washi1337 added enhancement pe Issues related to AsmResolver.PE labels Apr 10, 2022
@0x410c
Copy link

0x410c commented May 15, 2022

any update on this? as with single file host binaries, now we can read the bundle, but if the binaries inside are r2r we cant modify then and repackage the bundle.

@Washi1337
Copy link
Owner Author

Washi1337 commented May 15, 2022

any update on this? as with single file host binaries, now we can read the bundle, but if the binaries inside are r2r we cant modify then and repackage the bundle.

No updates yet. I hope to get this done in 5.0.

However, as far as I am aware, r2r binaries are just normal binaries with some extra metadata holding the prejitted code. The original is still present, and it should be possible to read, modify and repackage them by normal means. You might just have to update a few flags in the headers of the PE to make the executable runnable.

Also, keep in mind that AsmResolver will not do a rerun of the r2r compiler to regen native code, even if this feature is in place.

@0x410c
Copy link

0x410c commented May 15, 2022

can u point out to the flags, as of now if just reading and writing them back results in unusable binary.

@Washi1337
Copy link
Owner Author

Washi1337 commented May 16, 2022

You would probably want to make sure the ILOnly flag is set and the ILLibrary flag is unset in the .NET data directory. One way of doing that would be the following:

using AsmResolver.DotNet;
using AsmResolver.DotNet.Bundles;
using AsmResolver.PE.DotNet;

var manifest = BundleManifest.FromFile(...);
var file = manifest.Files.First(x => ...);
var module = ModuleDefinition.FromBytes(file.GetData());

module.Attributes &= ~DotNetDirectoryFlags.ILLibrary;
module.Attributes |= DotNetDirectoryFlags.ILOnly;

module.Write("modified.dll");

Keep in mind that this will strip out any r2r metadata. Related: #267

@0x410c
Copy link

0x410c commented May 16, 2022

exactly it makes the file run, but as r2r metadata is not there, it will not run directly but by using the jit

@Washi1337
Copy link
Owner Author

Initial prototypes for first-class R2R metadata support can be found in #495.

Turns out, the file format specification/documentation has a lot of gaps (flashbacks to PDBv7). Especially for some of the important internal data structures like NativeArray are not documented well. We will have to resort in some cases to the dotnet/runtime source code itself, and/or maybe even "borrow" some code every now and then.

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

No branches or pull requests

2 participants