Releases: Washi1337/AsmResolver
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.
5.4.0
This release includes support for PE certificate tables, PE forwarder exports, as well as various quality of life improvements and bug fixes. Check out the documentation and the full change-log below:
New Features
- Add read/write support for PE certificate tables (#451).
- Add support for arbitrary symbols to be references in
NativeMethodBody(#444, #449). - Let assembly resolution mechanism respect
ModuleReaderParameters::WorkingDirectory(#438, #441). - Add read/write support for
ExportedSymbol::IsForwarder(#437, #440). - Add
ManagedPEFileBuilder::ErrorListener(#468). - Allow for
ITypeDescriptor::Scopeto benulland of typeModuleDefinition. (#466) - Add language identifiers for Version Info win32 resources (#457)
- Add support for attaching multiple listeners to the
MemberCloner(#461) - Add
DotNetRuntimeInfo::GetDefaultCorLibandKnownCorlibs::FromRuntimeInfo(#462) PEFile::CreateReaderAtFileOffsetnow supports reading from EOF data (5821428).- Add Source Link (#469, thanks @ds5678)
Bug fixes
- Fix an issue when resolution scope of a type reference set to 0 when the coded index to the current module was meant instead (#459, #466).
- Fix an issue where field RVA rows were not always correctly updated when writing unchanged serialized PEs (#468).
- Fix an issue where win32 resource VersionInfo tables were not correctly aligned to the next 4-byte boundary, resulting in some of the resource to be trimmed away when rebuilding (#456).
- Fix an issue where the
Culture=part ofAssemblyDescriptor.FullNamewas not included in the output (#458). - Fix an issue where PE section names would result in spurious "name too long" exceptions when containing unconventional UTF-8 code points (#453, #455).
- Fix an issue where
GetImpliedMemoryLayoutwould stack-overflow with unresolved generic parameter type signatures (#447, #448). - Fix an issue where
ModuleReaderParameterswere not passed along correctly inModuleDefinition::FromBytes(bbf5781)
5.3.0
This version is mostly a maintenance version with performance improvements and bug fixes. Developers of .NET obfsucators and deobfuscators will also be happy to know that ManagedPEImageBuilder now accepts any IErrorListener. This should make it easier to ignore any invalid metadata that is introduced to the assembly model (e.g., by passing in an EmptyErrorListener). Finally, a migration from readthedocs to DocFX was made, giving a new home and look to the documentation. Let us know what you think of it!
New Features
- Add support for arbitrary
IErrorListenerobjects as opposed to justDiagnosticBags inManagedPEImageBuilder(#367, thanks @ds5678 for the help!). - Add
LazyVariable<TOwner, TValue>, reducing the number of allocations made by AsmResolver's internals significantly for larger binaries (#428) - Add
Platform::Is32Bit,Platform::Is64BitandPlatform::PointerSize(#430) - Add
ZeroesSegmentandZeroesDataSourcefor creating, reading and writing memory-efficient segments containing only zero bytes (#430). - Migrate documentation to DocFX with full API reference (2545e1a).
Bug Fixes
- Fixed an issue where
SignatureComparer::GetHashCodefor assembly descriptors did not respect the configuration flags passed into the constructor (#427, #429). - Field RVA reader now correctly supports reading the data for
IntPtrandUIntPtrtyped fields (#430). - Fixed an issue where reading from a section that is empty on the disk would throw even if the section has a non-zero virtual size (#430).
- Fixed an issue where entries in an import descriptor were not read correctly if
OriginalFirstThunk= 0. This is the case for many packed executables such as UPX packed binaries (#431, #432)
Deprecations
PEImageBuildContext::DiagnosticBagis superseded byPEImageBuildContext::IErrorListener.- The constructor
PEImageBuildResulttaking aDiagnosticBagis superseded by the one taking anIErrorListener.
Minor Breaking Changes
- The signature for
IFieldRvaDataReader::ResolveFieldDatahas changed slightly. See the documentation for how to use the new interface (#430).
5.2.0
New Features
- Add
TypeSignature::IsCompatibleWithandTypeSignature::IsAssignableTomethods (#421) - Add support for patching AppHost / SingleFileHost files without requiring the original SDK template file (#420, #424)
- Add support for metadata tokens and unmanaged entry points in
DotNetDirectory(#422) - Add
Parameter::GetOrCreateDefinition()(#418, thanks @ElektroKill) - Add read support for PDB modules (#412)
- Add read support for many more PDB symbol and leaf record types (#412)
- Add basic metadata properties to
PdbImage(e28df25) - Add
OptionalHeader::SetDataDirectoryhelper method (8357a77) - Add
CallingConventionSignature::CallingConventionconvenience property that masks out the used convention fromAttributes(#414) - Add undocumented
CallingConvention::NativeVarArg(#414)
Bug Fixes
- Fix an issue related to metadata token preservation of MemberRefParents (caeef35)
- Fix an issue with
MethodSignature's sentinel parameter type preservation (#413, #414). - Fix
ParameterCollection::ThisParameter's parameter type for generic instance types (e27b6e8, thanks @ElektroKill) - Fix
MethodSignatureBase::GetTotalParameterCount()forExplicitThissignatures (dae9909, thanks @ElektroKill)
Deprecations
- All constructors of
BundlerParametersare superseded byBundlerParameters::FromTemplateandBundlerParameters::FromExistingFile. - Assignments of
DotNetDirectory::EntryPointusing anuintare obsoleted and should be replaced with a construction of aDotNetEntryPointstructure.
Minor Breaking ABI Changes
- Remove spurious
CallingConventionSignature::IsSentinel(#414) - Change property type of
DotNetDirectory::EntryPointfromuinttoDotNetEntryPointDU struct.
5.1.0
New Features
- Add fluent patching API, allowing for easy and quick binary patches on PE files as well as individual segments (#403, #405). Check out the documentation.
- Add option to preserve spurious metadata streams and their order (#394, #406)
- Add generic
ModuleDefinition::LookupMember<T>andModuleDefinition::TryLookupMember<T>methods (#392, #402) - Add
TypeDefinition::IsModuleType(#391, thanks @sunnamed434) - Add rudimentary custom attribute validation, avoiding the accidental construction of incorrect attribute signatures (#389, #407)
Bug Fixes
- Fix generic custom attributes reader errors (#397, #401)
- Fix
GetModuleType()behavior for .NET Core / .NET 5+ modules (#395, #396) - Fix .NET runtime detection when multiple corlibs references are present in the binary (a0bb1df)
Deprecations
CodeSegmentis now deprecated. Use theDataSegmentcombined with the new patching API for address fixups.
Other
- Fixed some spelling mistakes in the documentation (#398, #400, thanks @Svenskithesource)