void AddInternalsVisibleToAttribute() { bool b = GetCorLibToken(out var corlibToken); Debug.Assert(b, "No corlib assembly found"); if (!b) { return; } b = CodedToken.ResolutionScope.Encode(corlibToken, out uint corlibEncodedToken); Debug.Assert(b); if (!b) { return; } uint ivtTypeRefRid = mdEditor.TablesHeap.TypeRefTable.Create(); var ivtTypeRefRow = new RawTypeRefRow(corlibEncodedToken, mdEditor.StringsHeap.Create("InternalsVisibleToAttribute"), mdEditor.StringsHeap.Create("System.Runtime.CompilerServices")); mdEditor.TablesHeap.TypeRefTable.Set(ivtTypeRefRid, ref ivtTypeRefRow); uint ivtCtorRid = mdEditor.TablesHeap.MemberRefTable.Create(); var ivtCtorRow = new RawMemberRefRow(CodedToken.MemberRefParent.Encode(new MDToken(Table.TypeRef, ivtTypeRefRid)), mdEditor.StringsHeap.Create(".ctor"), mdEditor.BlobHeap.Create(ivtCtorSigBlob)); mdEditor.TablesHeap.MemberRefTable.Set(ivtCtorRid, ref ivtCtorRow); uint ivtCARid = mdEditor.TablesHeap.CustomAttributeTable.Create(); var ivtCARow = new RawCustomAttributeRow(CodedToken.HasCustomAttribute.Encode(new MDToken(Table.Assembly, 1)), CodedToken.CustomAttributeType.Encode(new MDToken(Table.MemberRef, ivtCtorRid)), mdEditor.BlobHeap.Create(MDPatcherUtils.CreateIVTBlob(tempAssembly))); mdEditor.TablesHeap.CustomAttributeTable.Set(ivtCARid, ref ivtCARow); }
void ReadTypeDefOrRef() { var start = currPos; uint codedToken = ReadCompressedUInt32(); uint compressedLen = (uint)(currPos - start); if (!CodedToken.TypeDefOrRef.Decode(codedToken, out MDToken token)) { ThrowInvalidSignatureException(); } if (!remappedTypeTokens.TryGetValue(token.Raw, out uint newToken)) { return; } uint newCodedToken = CodedToken.TypeDefOrRef.Encode(newToken); uint newCodedTokenLen = (uint)MDPatcherUtils.GetCompressedUInt32Length(newCodedToken); if (usingBuilder || newCodedTokenLen != compressedLen) { SwitchToBuilder(compressedLen); WriteCompressedUInt32(newCodedToken); } else { currPos = start; WriteCompressedUInt32(newCodedToken); } }
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); }
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; }
MDSigPatcher(List <byte> sigBuilder, Dictionary <uint, uint> remappedTypeTokens, byte[] moduleData, uint blobOffset, uint sigOffset) { this.sigBuilder = sigBuilder; this.remappedTypeTokens = remappedTypeTokens; this.moduleData = moduleData; startOffset = blobOffset + sigOffset; uint size = MDPatcherUtils.ReadCompressedUInt32(moduleData, ref startOffset); endOffset = startOffset + size; currOffset = startOffset; usingBuilder = false; recursionCounter = 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); }
void DeleteTypeDef(MetadataEditor mdEditor, TypeDef nonNestedTypeDef) { Debug.Assert(nonNestedTypeDef.DeclaringType == null); var dict = new Dictionary <TypeDef, (TypeDef Type, uint TypeRefRid, RawTypeRefRow TypeRefRow)>(); foreach (var type in MDPatcherUtils.GetMetadataTypes(nonNestedTypeDef)) { var typeRefRid = mdEditor.TablesHeap.TypeRefTable.Create(); remappedTypeTokens.Add(type.MDToken.Raw, new MDToken(Table.TypeRef, typeRefRid).Raw); // Remove the type by renaming it and making it private/internal var tdRow = mdEditor.TablesHeap.TypeDefTable.Get(type.Rid); var flags = tdRow.Flags; if ((flags & 7) <= 1) { flags = flags & ~7U; // NotPublic } else { flags = (flags & ~7U) | 3; // NestedPrivate } var deletedType = (Type : type, TypeRefRid : typeRefRid, TypeRefRow : new RawTypeRefRow(0, tdRow.Name, tdRow.Namespace)); tdRow = new RawTypeDefRow(flags, mdEditor.StringsHeap.Create(Guid.NewGuid().ToString()), mdEditor.StringsHeap.Create(string.Empty), tdRow.Extends, tdRow.FieldList, tdRow.MethodList); mdEditor.TablesHeap.TypeDefTable.Set(type.Rid, ref tdRow); dict.Add(type, deletedType); } remappedTypeTokens.SetReadOnly(); foreach (var kv in dict) { var deletedType = kv.Value; uint resolutionScope; if (deletedType.Type.DeclaringType != null) { var declType = dict[deletedType.Type.DeclaringType]; resolutionScope = CodedToken.ResolutionScope.Encode(new MDToken(Table.TypeRef, declType.TypeRefRid)); } else { resolutionScope = CodedToken.ResolutionScope.Encode(new MDToken(Table.AssemblyRef, GetOrCreateTempAssemblyRid())); } deletedType.TypeRefRow = new RawTypeRefRow(resolutionScope, deletedType.TypeRefRow.Name, deletedType.TypeRefRow.Namespace); mdEditor.TablesHeap.TypeRefTable.Set(deletedType.TypeRefRid, ref deletedType.TypeRefRow); } }
static bool HasInternalsVisibleToAttribute(ModuleDef targetModule, ModuleDef sourceModule) { var targetAssembly = targetModule.Assembly; if (targetAssembly == null) { return(false); } var sourceAssembly = sourceModule.Assembly; if (sourceAssembly == null) { return(false); } foreach (var ca in targetAssembly.CustomAttributes) { if (ca.ConstructorArguments.Count != 1) { continue; } if (!MDPatcherUtils.CheckTypeDefOrTypeRefName(ca.Constructor?.DeclaringType, nameSystem_Runtime_CompilerServices, nameInternalsVisibleToAttribute)) { continue; } var asmName = (ca.ConstructorArguments[0].Value as UTF8String)?.String; if (asmName == null) { continue; } int index = asmName.IndexOf(','); if (index >= 0) { asmName = asmName.Substring(0, index); } asmName = asmName.Trim(); if (!StringComparer.OrdinalIgnoreCase.Equals(sourceAssembly.Name.String, asmName)) { continue; } return(true); } return(false); }
public bool Patch(ModuleDef module, out byte[] 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)) { if (makeEverythingPublic) { bool success = new MetadataFixer(moduleData, md).MakePublic(); if (!success) { newModuleData = null; return(false); } } 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(); moduleData = stream.ToArray(); } } } } 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; }