Releases: Washi1337/AsmResolver
6.0.0
After 2 years of development, v6.0.0 is officially here!
This version focuses on five key milestones:
-
Expanded Architecture Support: A new
Platformabstraction enables support for more architectures, including ARM32 and ARM64. Furthermore, this version revamps the entire PE file building mechanism, and introducesTemplatedPEFileBuilderas a flexible foundation for building native Windows PEs and mixed-mode .NET modules. -
Multi-Assembly Processing: A single .NET assembly is rarely fully self-contained and typically references code in external assemblies (e.g., DLLs). This version introduces
RuntimeContext, which mimics anAppDomainorAssemblyLoadContext. It is responsible for automating assembly resolution and shared metadata caching, and significantly improves .NET cross-binary processing. -
API Simplification: The API has undergone many Quality-of-Life improvements, removing many redundant interfaces and namespaces, adding more NRT annotations, and improving AOT trimming support. Furthermore, it is no longer required to manually import metadata as AsmResolver now auto-importing references at build time.
-
Improved Portability: With the help of @MonoMod, we now support more build targets, including .NET Framework 3.5. We thereby extend compatibility to legacy environments like older versions of Unity/Mono.
-
Performance Boosts: Next to
RuntimeContext's shared caching model and more lazy evaluation, we now leverageSpan<T>, source generators, and other modern .NET features in more places, delivering significantly faster PE processing with fewer allocations and lowering memory consumption across the board.
We've seen a huge uptick in the number of contributors, bug testers and new users over this period. A huge thank you to all of you! Without you this release wouldn't have been possible!
Migrating from v5.x
Migrating from v5.x requires addressing breaking changes. See the Migration Guide for more information.
Full Changelog
Changelog is relative to v5.5.1.
General Changes
12 changes
Improvements
- Remove
System.Text.Jsonas a hard dependency for older .NET (FX) targets (#450, #538). - Remove many redundant interfaces (e.g.,
IPEFileandIPEImage) (#445, #561, #562). - Flatten many namespaces, drastically reducing the required using directives for typical use (#446, #560).
- Use
EmptyErrorListener.Instancefor reading input files by default (#472, #564). - Add
IInputFile::BaseAddress(a1af121) - Add
IReadOnlyList<T>explicitly to collection classes for better compatibility with lower .NET targets (62ed463) - Add
PatchContext::WriterBase(#653)
Performance
- Improve the internal mechanisms for lazy-initialization using source generated lazy properties, significantly reducing the number of allocations across the entire library (#683)
- Use built-in memory-mapped file APIs on newer .NET build targets (#619, thanks @teo-tsirpanis)
- Optimize
BinaryStreamWriterfor .NET 10+ targets (#695, thanks @Sergio0694). - Add
Utf8String::CreateUnsafefactory method which avoids cloning many small byte arrays (#709, thanks @Windows10CE) - Let
Utf8StringimplementISpanFormattableandIUtf8SpanFormattable(#699, thanks @Sergio0694).
AsmResolver.PE.File
8 changes
Improvements
- Change
PESection::Nameto be of typeUtf8String(#454). - Add
OptionalHeader::SetDataDirectoryhelper method (7b27c91). - Add
DataDirectory.CreateForSegmenthelper method (7b27c91). - Add support for debug data to be read from EOF / overlay segments (#583, thanks @DaZombieKiller).
- Add
BinaryStreamReader::ReadBytes(int32)(5863886)
Performance
Bug Fixes
AsmResolver.PE
40 changes
Improvements
- Add
Platformclass (#643, #653) - Add
PEImage::ToPEFile - Add
EmptyDebugDataSegment(798a4ed) - Exception data directory improvements:
- .NET metadata directories improvements:
- Add
TargetRuntimeProberto detect the target runtime of a PE image without loading it as a fullModuleDefinition(#704). - Add
MetadataDirectory::GetImpliedStreamSelection()(#704). - Metadata table model improvements:
- Add linear sweep blob enumerators for
#Blob,#Guid,#Stringsand#USstreams (b7f67d0). - Add
BlobStreamBuffer::GetBlobIndexfor .NET 9+ targets (#680). - Add missing/newly introduced metadata flags:
- Add missing
EventAttributes.None(#676, thanks @Sergio0694) - Add missing
AggressiveInlining,AggressiveOptimizationandHasSecurityMitigationsflags toMethodDefinitionandMethodImplAttributes(bf80344). - Add missing
TypeAttributes::WindowsRuntime(#710, thanks @Sergio0694). - Add new
GenericParameterAttributes::AllowByRefLikeattribute property (#623, thanks @ds5678)
- Add missing
-
- Add new
MethodImplAttributes.Asyncto reflect .NET 10 runtime changes on async methods (#687, thanks @Windows10CE)
- Add new
- Add
Performance
- Let all
IMetadataRowstructures implementIEquatable, avoiding lots of boxing and reflection calls (aaf4d6e) - Add
FastCilReassemblerfor allocationless patching of CIL method bodies (#672)
Bug Fixes
- Fix an issue where Win32 resources were inserted into a PE's root resource directory out-of-order, causing version info and icons to not be interpreted by Windows correctly (#552, #553).
- Fix an issue where the RSDS parser would incorrectly include a null terminator byte in the PDB path (#584, thanks @Windows10CE)
- Fix an issue where zero base relocation blocks were duplicated unnecessarily (fd9cbb5)
- Fix an issue where computing the offset range for a single metadata row would be incorrect (e1f3a9c)
- Fix an issue where some ReadyToRun metadata read from a file would not be assigned an offset/rva (490176a)
- Fix an issue where offsets in TLS data directories would not roundtrip properly (#706, #708).
- Fix an issue where relocation table entries would be duplicated or misaligned in some cases (#708).
- Fix an issue where debug data directories would not be read properly when files are loaded using MMIO (#718, thanks @js6pak).
- .NET metadata data directory parsing fixes:
- Fix an issue where
MetadataTable::TryGetRidByKeywould not respect the sorted flag, causing some FieldRva to not select the appropriateClassLayoutrow properly (#724, #728). - Fix a data race in caching mechanism of
StringsStreamandUserStringsStream(b1ded1f). - Fix an issue where offsets for metadata streams were not updated appropriately upon writing (008b91a)
- Fix an issue where R2R x86_64
RuntimeFunctionssections could not be read correctly for non-Windows binaries (0660ccb) - Fix the interpretation of
#Schemaand#JTDmetadata streams (#557, thanks @ElektroKill). - Fix an issue where EnC metadata streams are looked up using case insensitive name lookup (#557, thanks @ElektroKill).
- Fix an issue where ENC metadata streams would not be selected appropriately when a
#JTDstream is present (#632, thanks @ElektroKill) - Fix an issue where
FieldRvaDataReaderwould not always select the correct metadata stream in various EnC situations (#724, #728).
- Fix an issue where
AsmResolver.PE.Win32Resources
1 change
Improvements
- Rewrite
IconResourceinto a more intuitive API that also supports language-specific icons and cursors (#565).
AsmResolver.DotNet
62 changes
Improvements
Assembly resolution improvements:
- Introduce
RuntimeContexts, allowing for better multi-assembly processing. - Remove all parameterless
Resolvemethods in favor of the newResolveandTryResolvemethods taking aRuntimeContext. Additionally, all properties and methods that may have implicitly required resolution will now take aRuntimeContextas well. - Simplified and improved
DotNetCorePathProvider, addMonoPathProviderand add NIX support (#657) - Add various known corlib targets for .NET 9, 10, 11 and generic fallback support for future unsupported versions (#548, #645, #651, 8e11fef, #702, 55c847f, thanks @Sergio0694 and @ds5678).
- Add more default assembly resolvers:
NullAssemblyResolver,PathAssemblyResolverandBundleAssemblyResolver(2fc1872, #721, thanks @js6pak)
Metadata builder improvements:
- Reference importing is now done automatically at build-time. In most cases there is no need for
ReferenceImporter/ImportWithcalls any more. - Add more elaborate diagnostics to
MemberNotImportedExceptions, including the location the unimported reference was detected (#626) - Relax final nested type metadata table ordering restrictions to reflect runtime behavior (#545, #625)
- Add automatic sorting of CIL exception handlers on build (#707, thanks @Windows10CE
Metadata validation improvements:
- Add
MethodDefinition::VerifyMetadatathat checks for (accidental) inconsistencies in method metadata, including inconsistencies betweenstaticandHasThisand generic parameter counts (#642) - Add validation of standalone signature contents in `CilInstructionCollection::Insert(CilO...
6.0.0-rc.1
This is the release candidate for 6.0.0, addressing some important regressions/shortcomings found in beta.6. Note that with this release the API design will be frozen, and only improvements/bug fixes will be implemented until full release.
Improvements
- Add
NullAssemblyResolverandPathAssemblyResolver(#721, thanks @js6pak) - Optimize
CorLibTypeFactory.FromTypeto avoid many unnecessary string allocations (#717, thanks @wondercrash). - Add
ImportWithmethods with more specific return types (#720, thanks @js6pak). - Add support for
IMemberDescriptorequality checks inSignatureComparer(#722, thanks @js6pak). - Add missing NRT attributes for various
TryResolvemethods (e2bf223). - Relax restrictions on input corlib for
CorLibTypeFactory, making it easier to create one yourself (367968a) - Remove redundant factory methods and remove
paramsoverloads in favor of using more explicit collection expressions for parameter types.
Bug Fixes
- Fix an issue where
TargetRuntimeProberwould crash with anArgumentNullExceptionwhen using AsmResolver in a .NET FX host (#723). - Fix an issue where debug data directories would not be read properly when files are loaded using MMIO (#718, thanks @js6pak).
- Fix an issue where
TypeSignature::IsAssignableToand friends did not use the signature comparer of the providedRuntimeContext(0484a39) - Fix an issue where
MetadataTable::TryGetRidByKeywould not respect the sorted flag, causing someFieldRvato not select the appropriateClassLayoutrow properly (#724, #728). - Fix an issue where
FieldRvaDataReaderwould not always select the correct metadata stream in EnC situations (#724, #728).
6.0.0-beta.6
This release brings the long-needed metadata resolution revamp. The previous system often caused incorrect, duplicated, or silent failed assembly resolutions, which sometimes resulted in bad metadata to be emitted in output binaries. The new system makes RuntimeContext act more like an AppDomain/AssemblyLoadContext, centralizing assembly management and requiring all metadata resolution to go through it. Resolution is now also much more explicit, by always requiring a RuntimeContext instance. This ensures more reliable, predictable behavior when creating and processing .NET metadata.
Check out the updated documentation on RuntimeContexts on how to use the new APIs.
Full change log below:
New Features
- Breaking change: Revamp of metadata resolution system and
RuntimeContexts (#704).IAssemblyResolveris drastically simplified and is no longer responsible for caching anymore.IMetadataResolverand friends are removed.RuntimeContextconstruction is drastically simplified.RuntimeContextis now responsible for resolving and maintaining assembly and metadata caches.- Add
RuntimeContext::LoadAssemblymethods to load assemblies into the context (similar toAssemblyDefinition::FromX, but using the context for reader parameters, cache and automatic wiring of dependencies). - Remove all
Resolvemethods in favor of aResolveandTryResolvemethod taking aRuntimeContext. Additionally, all properties and methods that may have implicitly required resolution will now take aRuntimeContextas well. SignatureComparercan now take aRuntimeContextin its constructor. When none is provided, the comparer will no longer try to resolve forwarder types and compare signatures as-is.
- Add
TargetRuntimeProberto detect the target runtime of a PE image without loading it as a fullModuleDefinition(#704). - Add
MetadataDirectory::GetImpliedStreamSelection()(#704). - Add read support for
S_TRAMPOLINEandS_GTHREAD32andS_LTHREAD32PDB symbols (#711, thanks @dongle-the-gadget).
Improvements
- Breaking Change: Rename
UnmanagedPEFileBuildertoTemplatedPEFileBuilderto more accurately reflect its behavior (727c554) - Add .NET 11 support (#696, thanks @ds5678).
- Add support for (potentially unreleased) future target runtime versions not known yet to the current distribution of AsmResolver.DotNet (i.e., not explicitly added to
KnownCorLibs) (#702, 55c847f). - Optimize
BinaryStreamWriterfor .NET 10+ targets (#695, thanks @Sergio0694). - Let
Utf8StringimplementISpanFormattableandIUtf8SpanFormattable(#699, thanks @Sergio0694). - Add automatic sorting of CIL exception handlers on build (#707, thanks @Windows10CE).
- Add
Utf8String::CreateUnsafefactory method (#709, thanks @Windows10CE) - Add
TypeAttributes::WindowsRuntime(#710, thanks @Sergio0694). - Add
ModuleDefinition::CreateConstructoroverload takingCorLibTypeFactory(#712, thanks @Sergio0694). - Add missing
Class2,Structure2,Union2andInterface2PDB leaf record types (#714, thanks @ds5678).
Bug Fixes
- Fix an issue where auto-importing a type reference with a module definition as its scope would not turn into the declaring assembly (#697).
- Fix an issue where the custom attribute signature writer would incorrectly consider the context module of a type as the target module (#697).
- Fix an issue where associated metadata was duplicated even if the owner row was deduplicated (#697 ).
- Fix an issue where offsets in TLS data directories would not roundtrip properly (#706, #708).
- Fix an issue where relocation table entries would be duplicated or misaligned in some cases (#708).
6.0.0-beta.5
Version 6.0.0-beta.5 is mostly a performance upgrade that also comes with a few improvements to make AsmResolver .NET 10-ready, as well as a couple of bug fixes.
Full changelog below:
New Features
- Add
FastCilReassemblerfor allocationless patching of CIL method bodies (#672) - Add
TypeAttributes::ExtendedLayoutandTypeDefinition::IsExtendedLayoutto reflect .NET 10 runtime changes to struct layout (dcc9162) - Add
MethodImplAttributes.AsyncandMethodDefinition::IsRuntimeAsyncto reflect .NET 10 runtime changes on async methods (#687, thanks @Windows10CE) - Add automatic importing of external type/field/method definitions (#689, thanks @Windows10CE)
- Add .NET 10 build targets (8e11fef)
Improvements
- Improve the internal mechanisms for lazy-initialization using source generated lazy properties, significantly reducing the number of allocations across the entire library (#683)
- Add lazy initialized
SerializedCilMethodBodythat avoids unnecessarily fully decoding a method body where possible (#672) - Add allocation-less
HasXproperties, reducing memory footprint of roundtripping assemblies (#680) - Add
BlobStreamBuffer::GetBlobIndexfor .NET 9+ targets (#680). - Mark name parameter for
FieldDefinitionconstructor nullable (#673, thanks @ds5678) - Replace constructors of
ExportedTypeto take inUtf8Stringinstead ofstring(#675, thanks @Sergio0694) - Remove redundant
ModuleDefinitionconstructors taking instring(#674, thanks @ds5678) - Add missing
EventAttributes.None(#676, thanks @Sergio0694) - Let
GetOrCreateParameterDefinitioninsert newly generated parameter definitions at the index implied by its sequence (#677, thanks @ds5678) - Add legacy runtime infos .NETCore and .NETPortable (#682, #684, thanks @ds5678)
Bug Fixes
- Fix an issue where type signatures were not always resolved correctly (f8ee34b)
- Fix a regression where
ExpandMacrosandOptimizeMacroswould fail on some macro expanded instructions includingldc.i4andldarg(#678, #679, thanks @Windows10CE) - Fix an issue where some type references with an assembly self-reference scope would re-resolve the assembly definition and thus not return the same type definition instance (8172ad5)
6.0.0-beta.4
It's been a while since the last beta.3 release, and the main reason for this has been that beta.3 saw many more testers actively trying out v6.0.0 and pushing it to its limits. Beta.4 addresses many bugs and shortcomings found during this period. Notable changes are ARM32 and ARM64 support, auto metadata references importing, and many DX improvements that make using AsmResolver even easier than before.
A huge thanks to all the testers and contributors for their commitment to the project!
See notes below for a full changelog:
New Features
- Add ARM64 platform support, including native thunk stub codegen and exception handlers (#643)
- Add ARM32 platform support, including native thunk stub codegen (#653)
- Add Generic platform for unsupported platforms to prevent unnecessary crashes on opening/saving these types of files (#653)
- Add
Platform::GetOrGenericfactory method (#653) - Add
IRuntimeFunction::UnwindInfo(#643) - Add new
GenericParameterAttributes::AllowByRefLikeattribute and correspondingGenericParameter::HasAllowByRefLikeproperty (#623, thanks @ds5678) - Add
PatchContext::WriterBase(#653) - Add
MonoPathProvider(#657) - Add support for dotnet path resolution in Nix stores (#657)
- Add support for reading PE files from streams (#664, thanks @ds5678)
- Add
MethodDefinition::VerifyMetadatathat checks for (accidental) inconsistencies in metadata, including inconsistencies between static andHasThisand generic parameter counts (#642)
Improvements
- Remove
ownerparameter from the constructor ofCilMethodBody(#641) - Remove requirement of importing type and member references (#655)
- Let
CreateTypeReferenceandCreateMemberReferenceauto import the created members (#655) - Split
IMemberDescriptor::ModuleintoContextModuleandDeclaringModulefor references and definitions respectively (#655) - Add build targets for legacy .NET Framework 4.6.2 and 4.7.2
- Rename
IExceptionDirectory::GetEntriestoGetFunctions(#643) - Add
CustomAttribute::Typeshortcut property (#622, thanks @ds5678) - Add support for creating new modules with a
nullcorlib scope to create new corlib modules (#620, #621, thanks @ds5678) - Use built-in memory-mapped file APIs on newer .NET build targets (#619, thanks @teo-tsirpanis)
- Relax final nested type metadata table ordering restrictions to reflect runtime behavior as opposed to ECMA-335 specification (#545, #625)
- Ensure a newly created
<Module>type always has RID 1 (#625) - Add more convenience factory methods to
Constant(#627, thanks @ds5678) - Add more elaborate diagnostics to
MemberNotImportedExceptions, including the location the unimported reference was detected (#626) - Respect new Field RVA alignment requirements specified in the latest ECMA-335 augmentations (#628, thanks @Windows10CE)
- Add
MakeBoxedTypeextension method (#629, thanks @ds5678) - Add
HasCustomAttributeoverloads acceptingUtf8String(#633, thanks @Sergio0694) - Resolve some Native AOT warnings (#631, thanks @Sergio0694)
- Add validation of standalone signature contents in
CilInstructionCollection::Insert(CilOpCode, StandAloneSiganture)(#642) - Add static/instance flag checks in constructor of
MethodDefinitionand an overload to suppress this (#642) - Add .NET 10 known corlib references (#645, #651, thanks @Sergio0694 and @ds5678)
- Let
IMethodDefOrRefinherit fromICustomAttributeTypeinstead of the other way around to avoid verbose casts in user code (#658, thanks @Windows10CE) - Simplified and improved
DotNetCorePathProviderand friends (#657) - Add
HideBySigmethod flag to newly created static class constructors (#659, thanks @ds5678) - Add better type coercion while comparing
ITypeDescriptors usingSignatureComparer(#656, thanks @Windows10CE)
Bug Fixes
- Fix an issue where types parsed from a Custom Attribute signature were not resolvable (61f9115)
- Fix various Custom Attribute type name parsing problems (#647, #648, thanks @Windows10CE)
- Fix an issue where
ExportedTypes were not handled byMemberNameGeneratorappropriately (ff455e9) - Fix an issue where offsets for metadata streams were not updated appropriately upon writing (008b91a)
- Fix an issue in method and field accessibility tests in nested types (0942aba, thanks @ds5678)
- Fix an issue where ENC metadata streams would not be selected appropriately when a
#JTDstream is present (#632, thanks @ElektroKill) - Fix an issue where
System.Enumitself would incorrectly be classified as a value type (#635. #636, thanks @AndrewSav) - Fix an issue related to comparing forwarder types using
SignatureComparer(#634, thanks @js6pak) - Fix conflicting flag constants in
MetadataBuilderFlags(#642) - Fix an issue where UTF8 strings were not concatenated properly (#650, thanks @ds5678)
- Fix an issue related to patched segments not being serialized properly to the final PE file (#653)
- Fix an issue where unreachable exception handlers in a CIL method body would incorrectly still be included in max stack calculation (#652)
- Fix an issue related to nested types incorrectly being owned by both a
ModuleDefinitionand aTypeDefinition(#656, thanks @Windows10CE) - Fix an issue where assemblies with a specific culture set would be resolved correctly but not returned to the caller (##668, thanks @Meivyn)
6.0.0-beta.3
This is a maintenance release. AsmResolver is closing in on a main release with most of the public API being stable. However, similar to 6.0.0-beta.2, this is still a pre-release and some of the public APIs are still subject to change.
Improvements
- Add
IReadOnlyList<T>explicitly to collection classes for better compatibility with lower .NET targets (62ed463) - Mark
ManagedPEFileBuilderandUnmanagedPEFileBuilder's method body and field RVA data methods asvirtual(166b541) - Add
PEReaderContext::Platformthat can be reused throughout the PE parsing stage (0660ccb) - Ensure
Cultureappears beforePublicKeyTokenin assembly full names to keep Mono happy (#614, thanks @ds5678) - Rework type signature parsing in custom attribute blobs (#598, #616)
- Use built-in
RuntimeTypeHandle::FromIntPtrof .NET 7+ for resolving type handles in dynamic methods when possible (#617, thanks @teo-tsirpanis)
Bug Fixes
- Fix an issue where parsed
TypeSignatures in a Custom Attribute would not always have the correctIsValueTypeproperty set (#598, #616) - Fix an issue where R2R x86_64 RuntimeFunctions sections could not be read correctly for non-Windows binaries (0660ccb)
- Fix an off-by-one error that would result in some binaries with large amounts of methods and custom attributes to throw
BadImageFormatExceptions (#608, #609) - Fix an issue where invalid coded indices in a metadata table would result in exceptions upon resolving of the (invalid) referenced metadata member (1e1f9b9)
6.0.0-beta.2
This is a maintenance release that fixes some shortcomings and addresses various regressions introduced by the refactors in 6.0.0-beta.1.
Similar to 6.0.0-beta.1, this is an unstable release and the public API are still subject to change.
Improvements
- Add more nullable attributes (#575, #604, thanks @ds5678)
- Add
GenericParameter::Varianceproperty (#578, thanks @ds5678) SentinelTypeSignatureis now a singleton (#581, thanks @ds5678)- Add
InsertandTryGetRidByKeytoMetadataTable(0acd8ca) - Add support for debug data to be read from EOF / overlay segments (#583, thanks @DaZombieKiller).
- Add
EmptyDebugDataSegment(798a4ed) - Add
BinaryStreamReader::ReadBytes(int32)(5863886) - Let
IMetadataTableimplementISegment(9251f19) - Add linear sweep blob enumerators for
#Blob,#Guid,#Stringsand#USstreams (b7f67d0). - Let all
IMetadataRowstructures implementIEquatable(aaf4d6e) - Ensure a type's namespace is always
nullor non-empty (#602, thanks @ds5678) - Drastically increase the accuracy of
IMemberDefinition::IsAccessibleFromand add analogousCanAccessDefinitionmethods (71d345f)
Bug Fixes
- Fix an issue when cloning a method body using
MemberClonerwould not importcallioperands properly (4a02161) - Fix an issue where the RSDS parser would incorrectly include a null terminator byte in the PDB path (#584, thanks @Windows10CE)
- Fix an issue where export directories would be duplicated when using
UnmanagedPEFileBuilder(3200229) - Fix an issue where zero base relocation blocks were duplicated unnecessarily (fd9cbb5)
- Fix an issue where in some cases a non-empty import directory would be removed incorrectly if the
UnmanagedPEFileBuilderwas instructed to not trampoline the IAT (5f65621). - Fix an issue where cloned properties and events were not included in the final
ClonedMemberscollection inMemberCloneResult(#592) - Fix an issue where comparing two generic methods using
SignatureComparerwould result in a different conclusion depending on the order in which the two are passed onto the comparer (#595, thanks @ds5678). - Fix an issue when computing the offset range for a single metadata row (e1f3a9c)
- Fix an issue where some ReadyToRun metadata read from a file would not be assigned an offset/rva (490176a)
6.0.0-beta.1
This marks the second major bump of AsmResolver since the rewrite. Note that this is still a pre-release and that last-minute breaking API changes may still be introduced before full release.
Summary
Version 6.0.0 of AsmResolver focuses on achieving three very important long-awaited milestones:
-
Unmanaged PE file building: A complete revamp of the underlying PE file building mechanism has finally allowed for a long-awaited
UnmanagedPEFileBuilder: A robust yet flexible foundation for reconstructing fully native PE files as well as mixed-mode .NET modules. We are not quite there yet with integrating it into theAsmResolver.DotNetpackage, but it should pave the way for it as well as help with processing ReadyToRun- and NativeAOT-compiled files in the future. See the new documentation for details. -
.NET Framework 3.5 support: Previously, AsmResolver targeted .NET standard 2.0, allowing developers to use a .NET Framework version as low as 4.6.1. While 4.8.1 is installed by default on modern Windows machines and we are approaching the release of .NET 9, many use-cases still require older versions of .NET (in particular, game-modding and dynamic code deobfuscation). With the awesome help of the people behind the @MonoMod project, we have been finally able to make AsmResolver 6.0.0 fully compatible with .NET Framework 3.5.
-
API simplification and improvements: The existing public API also has undergone many quality-of-life improvements to ensure a better developer experience. This includes removing many of the redundant interfaces, as well as flattening a lot of namespaces to reduce the number of
usingdirectives required for typical usecases of AsmResolver. Performance has also been improved a lot in various areas, partially thanks to the new concept ofRuntimeContexts. And of course, many bug fixes have been squashed.
Important to note is that this release introduces breaking changes with respect to 5.x.x. In the following, the important changes are listed:
New Features
- Add
UnmanagedPEFileBuilder, allowing forPEImages containing only native code or both native and managed .NET code to be built with little effort (#554). - It is now much easier to customize existing PE file builders (or create your own) to get full control over the final PE file layout thanks to the new
PEFileBuilderbase class. - Add .NET 3.5 support, using MonoMod.Backports (#536, #540, #544, #450, #439, with the help of @MonoMod and @Windows10CE).
- Add the concept of
RuntimeContexts, allowing for .NET modules to be loaded under a specific .NET runtime or AppHost bundle context, which avoids many type resolution problems, drastically reduces memory footprint and also increases overall performance (#471, #537). - Add
PEImage::ToPEFile(). - Add
TrampolineTableBuffer, allowing for IAT trampolines to be built easily. - Add
TypeMemoryLayout::IsReferenceOrContainsReferencesflag, equivalent to RuntimeHelpers::IsReferenceOrContainsReferences<T> but determined statically (#530, #539). - Add
BundleAssemblyResolver(2fc1872) - Add
SetAccessorMethodstoPropertyDefinitionandEventDefinition(#555, thanks @ds5678). - Add
AggressiveInlining,AggressiveOptimizationandHasSecurityMitigationsflags toMethodDefinitionandMethodImplAttributes(bf80344). - Add
IInputFile::BaseAddress(a1af121)
Improvements
- Remove many redundant interfaces (e.g.,
IPEFileandIPEImage). Developers are expected to use their immediate implementing class (i.e.,PEFileandPEImage) (#445, #561, #562). - Flatten many namespaces, drastically reducing the required
usingdirectives for typical AsmResolver usecases (#446, #560). - Use
EmptyErrorListener.Instancefor reading input files by default (#472, #564). - Remove
System.Text.Jsonas a hard dependency requirement, making the library more portable for older .NET targets ( #450, #538). - Add .NET 9 as a known corlib (#548, thanks @ds5678).
- Add correct interpretation of
#Schemaand#JTDmetadata streams (#557, thanks @ElektroKill). - Add
FunctionPointerTypeSignaturesupport forSignatureComparer::GetHashCode(#551, thanks @BadRyuner). - Rewrite
IconResourceinto a more intuitive API that also supports language-specific icons and cursors (#565). - Let
PESection::Nameaccept arbitrary UTF8 strings (#454). - Add
OptionalHeader::SetDataDirectory(7b27c91). - Add
SetDataDirectory.CreateForSegment(7b27c91.)
Bug Fixes
- Fix an issue where EnC metadata streams are looked up using case insensitive name lookup (#557, thanks @ElektroKill).
- Fix an issue where Win32 resources were inserted into a PE's root resource directory out-of-order, causing version info and icons to not be interpreted by Windows correctly (#552, #553).
- Fix a data race in caching mechanism of
StringsStreamandUserStringsStream(b1ded1f). - Fix an issue related to reading and writing signed compressed integers for lower bounds in array type signatures (c7bc9f6).
Documentation
- Documentation on the new PE file building mechanism was added.
- The
AsmResolver.PE.Win32Resourcepackage now has its dedicated documentation section.
5.5.1
This is an incremental maintenance release that adds .NET 8.0 as an official target and fixes issues related to type signatures, CIL optimizations, as well as some rare edge cases in .NET metadata directory parsing.
New Features
- Add support for importing function pointer type signatures via reflection (#523, thanks @Windows10CE).
- Add
BinaryStreamWriter::AlignRelative(af2e49d) - Add .NET 8.0 target.
Bug Fixes
- Fix a couple issues regarding hash computation of generic instance and custom modifier type signatures in
SignatureComparer(#512, thanks @rstarkov) - Fix an issue where optimizing
ldlocaandldargaopcodes would not shorten to their shorter variants (9ab4e94) - Fix an issue where the same metadata members could be added twice to the exact same collection, resulting in ownership problems (#513)
- Fix an issue where .NET modules containing a metadata directory at an unaligned offset would read stream headers incorrectly (af2e49d).
5.5.0
This version brings rudimentary low-level .NET ReadyToRun (R2R) parsing and writing to AsmResolver, allowing you to locate and read native code of precompiled managed method bodies (see documentation). Additionally, basic Span<T> support was added to primitives like IDataSource and Utf8String for newer .NET runtime targets (netstandard 2.1 and above), and some new convenience APIs were added. Finally, some bugfixes were implemented, increasing general stability of the library.
New Features
- Add support for low level .NET ReadyToRun assembly parsing (#294, #495). See documentation.
- Add basic
Span<T>support forIDataSources andUtf8String(#483, thanks @DaZombieKiller). - Add option to suppress .NET resource data deduplication (#492).
- Add
TypeDefinition::GetConstructor,MethodDefinition::CreateConstructorand similar (#480). - Add
ReferenceTableprimitive segment class, representing structures like VTables that can be directly used as a writableISegment. - Add
BinaryStreamReader::RemainingLength. - Reduce allocations of null
SegmentReferences. - Add
netstandard2.1target.
Bug Fixes
TypeReference::IsImportedInModulenow correctly takes its resolution scope into account (#497).- Type resolution now correctly first checks whether the resolution scope refers to the current assembly (7403692).
TypeNameParsernow correctly does not return fully imported types, but they can still be resolved using.Resolve()(#497).MemberClonernow correctly fixes cross-references to includedSystem.Typearguments in Custom Attributes (#482, #493).- Fixed an issue where .NET resource data with a malformed header would crash the parser (#492).
- Fixed an issue where
ZeroesDataSourcewould clear out too much data in the buffer provided toReadBytes(thanks @DaZombieKiller) - Fixed an issue where
BitListwould incorrectly accept negative indices (#478). - Fixed an issue where duplicated members would not be added even when preserving metadata tokens (#478).
- Fixed an issue where members with manually assigned tokens would not be saved correctly when assembly had no backing .NET directory (#478)
- Fixed a race condition in the caching mechanism of assembly resolution (61b6ddf)
- Fixed a race condition in the caching mechanism of input file services (61b6ddf)
- Fixed an issue where string operands in IL pretty printed instructions were not escaped properly (6e039b9)
Minor Breaking Changes
- Remove
TlsCallbackCollection, replaced withReferenceTable. TlsDirectory::CallbackFunctionsis now of typeReferenceTable.IDotNetDirectory::ManagedNativeHeaderis now of the more specific segment typeIManagedNativeHeader.