public ModulePatcher(RawModuleBytes moduleData, bool isFileLayout, IAssembly tempAssembly, TypeDef nonNestedEditedTypeOrNull, bool makeEverythingPublic) { this.moduleData = moduleData; this.isFileLayout = isFileLayout; this.tempAssembly = tempAssembly; this.nonNestedEditedTypeOrNull = nonNestedEditedTypeOrNull; this.makeEverythingPublic = makeEverythingPublic; }
public ModulePatcher(RawModuleBytes moduleData, bool isFileLayout, IAssembly tempAssembly, ModuleDef editedModule, TypeDef?nonNestedEditedType) { this.moduleData = moduleData; this.isFileLayout = isFileLayout; this.tempAssembly = tempAssembly; this.editedModule = editedModule; this.nonNestedEditedType = nonNestedEditedType; }
public unsafe bool Patch(ModuleDef module, out RawModuleBytes newModuleData) { var moduleData = this.moduleData; // NOTE: We can't remove the type from the corlib (eg. mscorlib) because the compiler // (Roslyn) won't recognize it as the corlib if it has any AssemblyRefs. // A possible fix is to add a new netmodule to the corlib assembly. bool fixTypeDefRefs = !(nonNestedEditedType is null) && MDPatcherUtils.ExistsInMetadata(nonNestedEditedType) && MDPatcherUtils.ReferencesModule(module, nonNestedEditedType?.Module) && !module.Assembly.IsCorLib(); bool addIVT = module == editedModule || MDPatcherUtils.HasModuleInternalAccess(module, editedModule); if (fixTypeDefRefs || addIVT) { DnSpyEventSource.Log.EditCodePatchModuleStart(module.Location); using (var md = MDPatcherUtils.TryCreateMetadata(moduleData, isFileLayout)) { if (md is null) { throw new InvalidOperationException("Couldn't create metadata"); } var mdEditor = new MetadataEditor(moduleData, md); var options = MDEditorPatcherOptions.None; if (fixTypeDefRefs) { options |= MDEditorPatcherOptions.UpdateTypeReferences; } if (addIVT) { options |= MDEditorPatcherOptions.AllowInternalAccess; } var patcher = new MDEditorPatcher(moduleData, mdEditor, tempAssembly, nonNestedEditedType, options); patcher.Patch(module); if (mdEditor.MustRewriteMetadata()) { var stream = new MDWriterMemoryStream(); new MDWriter(moduleData, mdEditor, stream).Write(); NativeMemoryRawModuleBytes?newRawData = null; try { newRawData = new NativeMemoryRawModuleBytes((int)stream.Length, isFileLayout: true); stream.CopyTo((IntPtr)newRawData.Pointer, newRawData.Size); moduleData = newRawData; } catch { newRawData?.Dispose(); throw; } } } DnSpyEventSource.Log.EditCodePatchModuleStop(module.Location); } newModuleData = moduleData; return(true); }
public MDEditorPatcher(RawModuleBytes moduleData, MetadataEditor mdEditor, IAssembly tempAssembly, TypeDef nonNestedEditedTypeOrNull) { this.moduleData = moduleData; peFile = (byte *)moduleData.Pointer; this.tempAssembly = tempAssembly; this.nonNestedEditedTypeOrNull = nonNestedEditedTypeOrNull; remappedTypeTokens = new Dictionary <uint, uint>(); sigBuilder = new List <byte>(); this.mdEditor = mdEditor; tempAssemblyRefRid = 0; }
public static IMetaData TryCreateMetadata(RawModuleBytes moduleData, bool isFileLayout) { try { return(MetaDataCreator.CreateMetaData(new PEImage((IntPtr)moduleData.Pointer, moduleData.Size, isFileLayout ? ImageLayout.File : ImageLayout.Memory, verify: true))); } catch (IOException) { } catch (BadImageFormatException) { } return(null); }
MDSigPatcher(List <byte> sigBuilder, RemappedTypeTokens remappedTypeTokens, RawModuleBytes moduleData, uint blobOffset, uint sigOffset) { this.sigBuilder = sigBuilder; this.remappedTypeTokens = remappedTypeTokens; currPos = (byte *)moduleData.Pointer + blobOffset + sigOffset; uint size = MDPatcherUtils.ReadCompressedUInt32(ref currPos, (byte *)moduleData.Pointer + moduleData.Size); startPos = currPos; endPos = currPos + size; usingBuilder = false; recursionCounter = 0; }
public MDEditorPatcher(RawModuleBytes moduleData, MetadataEditor mdEditor, IAssembly tempAssembly, TypeDef?nonNestedEditedType, MDEditorPatcherOptions options) { this.moduleData = moduleData; peFile = (byte *)moduleData.Pointer; this.tempAssembly = tempAssembly; this.nonNestedEditedType = nonNestedEditedType; remappedTypeTokens = new RemappedTypeTokens(nonNestedEditedType); sigBuilder = new List <byte>(); this.mdEditor = mdEditor; this.options = options; tempAssemblyRefRid = 0; }
public unsafe bool Patch(ModuleDef module, out RawModuleBytes newModuleData) { var moduleData = this.moduleData; // NOTE: We can't remove the type from the corlib (eg. mscorlib) because the compiler // (Roslyn) won't recognize it as the corlib if it has any AssemblyRefs. // A possible fix is to add a new netmodule to the corlib assembly. bool fixTypeDefRefs = nonNestedEditedTypeOrNull != null && MDPatcherUtils.ExistsInMetadata(nonNestedEditedTypeOrNull) && MDPatcherUtils.ReferencesModule(module, nonNestedEditedTypeOrNull?.Module) && !module.Assembly.IsCorLib(); if (makeEverythingPublic || fixTypeDefRefs) { using (var md = MDPatcherUtils.TryCreateMetadata(moduleData, isFileLayout)) { if (makeEverythingPublic) { new MetadataFixer(moduleData, md).MakePublic(); } if (fixTypeDefRefs) { var mdEditor = new MetadataEditor(moduleData, md); var patcher = new MDEditorPatcher(moduleData, mdEditor, tempAssembly, nonNestedEditedTypeOrNull); patcher.Patch(module); if (mdEditor.MustRewriteMetadata()) { var stream = new MDWriterMemoryStream(); new MDWriter(moduleData, mdEditor, stream).Write(); NativeMemoryRawModuleBytes newRawData = null; try { newRawData = new NativeMemoryRawModuleBytes((int)stream.Length); stream.CopyTo((IntPtr)newRawData.Pointer, newRawData.Size); moduleData = newRawData; } catch { newRawData?.Dispose(); throw; } } } } } newModuleData = moduleData; return(true); }
MDSigPatcher(List <byte> sigBuilder, RemappedTypeTokens remappedTypeTokens, RawModuleBytes moduleData, uint blobOffset, uint sigOffset) { if ((ulong)blobOffset + sigOffset > (ulong)moduleData.Size) { ThrowInvalidSignatureException(); } this.sigBuilder = sigBuilder; this.remappedTypeTokens = remappedTypeTokens; currPos = (byte *)moduleData.Pointer + blobOffset + sigOffset; uint size = MDPatcherUtils.ReadCompressedUInt32(ref currPos, (byte *)moduleData.Pointer + moduleData.Size); startPos = currPos; endPos = currPos + size; if ((ulong)(endPos - (byte *)moduleData.Pointer) > (ulong)moduleData.Size) { ThrowInvalidSignatureException(); } usingBuilder = false; recursionCounter = 0; }
public static byte[]? PatchCallingConventionSignature(List <byte> sigBuilder, RemappedTypeTokens remappedTypeTokens, RawModuleBytes moduleData, uint blobOffset, uint sigOffset) { try { var patcher = new MDSigPatcher(sigBuilder, remappedTypeTokens, moduleData, blobOffset, sigOffset); patcher.PatchCallingConventionSignature(); return(patcher.GetResult()); } catch (InvalidSignatureException) { } Debug.Fail("Failed to patch calling convention sig"); return(null); }
public ReferenceInfo(RawModuleBytes rawData, in CompilerMetadataReference mdRef)
public MetadataFixer(RawModuleBytes rawData, IMetaData md) { data = (byte *)rawData.Pointer; this.md = md; }
public static byte[] PatchTypeSignature(List <byte> sigBuilder, Dictionary <uint, uint> remappedTypeTokens, RawModuleBytes moduleData, uint blobOffset, uint sigOffset) { try { var patcher = new MDSigPatcher(sigBuilder, remappedTypeTokens, moduleData, blobOffset, sigOffset); patcher.PatchTypeSignature(); return(patcher.GetResult()); } catch (InvalidSignatureException) { } Debug.Fail("Failed to patch type sig"); return(null); }