List <Local> ReadLocals(MethodDef cilMethod, CsvmMethodData csvmMethod) { var locals = new List <Local>(); var reader = new BinaryReader(new MemoryStream(csvmMethod.Locals)); if (csvmMethod.Locals.Length == 0) { return(locals); } // v6.0.0.5 sometimes duplicates the last two locals so only check for a negative value. int numLocals = reader.ReadInt32(); if (numLocals < 0) { throw new ApplicationException("Invalid number of locals"); } var gpContext = GenericParamContext.Create(cilMethod); for (int i = 0; i < numLocals; i++) { locals.Add(new Local(ReadTypeRef(reader, gpContext))); } return(locals); }
public void Read(MethodDef method) { gpContext = GenericParamContext.Create(method); flags = (MethodFlags)reader.ReadByte(); if (HasDelegateType) { delegateType = Resolve <TypeDef>(ReadTypeToken()); if (!DotNetUtils.DerivesFromDelegate(delegateType)) { throw new ApplicationException("Invalid delegate type"); } } if (HasLocals) { ReadLocals((int)reader.Read7BitEncodedUInt32()); } if (HasInstructions) { ReadInstructions((int)reader.Read7BitEncodedUInt32()); } if (HasExceptionHandlers) { ReadExceptionHandlers((int)reader.Read7BitEncodedUInt32()); } }
internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, IList <PdbCustomDebugInfo> customDebugInfos) { if (reader == null) { return; } SymbolMethod method; #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif method = reader.GetMethod(ownerMethod, 1); if (method != null) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); // Read the custom debug info last so eg. local names have been initialized method.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); body.PdbMethod = pdbMethod; } #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif }
protected bool FixProxyCalls(MethodDef method, Dictionary <Block, List <RemoveInfo> > removeInfos) { var gpContext = GenericParamContext.Create(method); foreach (var block in removeInfos.Keys) { var list = removeInfos[block]; var removeIndexes = new List <int>(list.Count); foreach (var info in list) { if (info.IsCall) { var opcode = info.DelegateInfo.callOpcode; var newInstr = Instruction.Create(opcode, ReResolve(info.DelegateInfo.methodRef, gpContext)); block.Replace(info.Index, 1, newInstr); } else { removeIndexes.Add(info.Index); } } if (removeIndexes.Count > 0) { block.Remove(removeIndexes); } } return(removeInfos.Count > 0); }
internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList <PdbCustomDebugInfo> result) { Debug.Assert(method.Module == module); PdbAsyncMethodSteppingInformationCustomDebugInfo asyncStepInfo; GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body, out asyncStepInfo); if (asyncStepInfo != null) { var asyncMethod = TryCreateAsyncMethod(module, symMethod.KickoffMethod, asyncStepInfo.AsyncStepInfos, asyncStepInfo.CatchHandler); Debug.Assert(asyncMethod != null); if (asyncMethod != null) { result.Add(asyncMethod); } } else if (symMethod.KickoffMethod != 0) { var iteratorMethod = TryCreateIteratorMethod(module, symMethod.KickoffMethod); Debug.Assert(iteratorMethod != null); if (iteratorMethod != null) { result.Add(iteratorMethod); } } }
static GenericParamContext GetGenericParamContext(ITypeOrMethodDef tmOwner) { if (tmOwner is MethodDef md) { return(GenericParamContext.Create(md)); } return(new GenericParamContext(tmOwner as TypeDef)); }
PdbCustomDebugInfoReader(MethodDef method, CilBody body, ref DataReader reader) { module = method.Module; typeOpt = method.DeclaringType; bodyOpt = body; gpContext = GenericParamContext.Create(method); this.reader = reader; }
unsafe protected override ITypeDefOrRef GetBaseType_NoLock() { var mdi = readerModule.MetaDataImport; uint token = OriginalToken.Raw; uint tkExtends = MDAPI.GetTypeDefExtends(mdi, token); return(readerModule.ResolveTypeDefOrRefInternal(tkExtends, GenericParamContext.Create(this))); }
unsafe void InitSignature_NoLock() { var mdi = readerModule.MetaDataImport; uint token = OriginalToken.Raw; var data = MDAPI.GetFieldSignatureBlob(mdi, token); this.Signature = readerModule.ReadSignature(data, GenericParamContext.Create(ownerType)); }
public Importer GetImporter(TypeDef type) { var mapper = new Mapper(this); var importer = new Importer(TargetModule, ImporterOptions.TryToUseDefs, GenericParamContext.Create(type), mapper); mapper.Init(importer); return(importer); }
public void Read(MethodDef method) { this.gpContext = GenericParamContext.Create(method); this.parameters = method.Parameters; SetLocals(GetLocals(method)); maxStackSize = (ushort)reader.ReadInt32(); ReadInstructionsNumBytes(reader.ReadUInt32()); ReadExceptionHandlers(); }
static GenericParamContext GetGenericParamContext(ITypeOrMethodDef tmOwner) { var md = tmOwner as MethodDef; if (md != null) { return(GenericParamContext.Create(md)); } return(new GenericParamContext(tmOwner as TypeDef)); }
internal void GetCustomDebugInfos(SymbolMethodImpl symMethod, MethodDef method, CilBody body, IList <PdbCustomDebugInfo> result) { Debug.Assert(method.Module == module); GetCustomDebugInfos(method.MDToken.ToInt32(), GenericParamContext.Create(method), result, method, body, out var asyncStepInfo); if (!(asyncStepInfo is null)) { var asyncMethod = TryCreateAsyncMethod(module, symMethod.KickoffMethod, asyncStepInfo.AsyncStepInfos, asyncStepInfo.CatchHandler); Debug.Assert(!(asyncMethod is null)); if (!(asyncMethod is null)) { result.Add(asyncMethod); } }
public void Deobfuscate(Blocks blocks) { if (type == null) { return; } var gpContext = GenericParamContext.Create(blocks.Method); foreach (var block in blocks.MethodBlocks.GetAllBlocks()) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count - 1; i++) { var instr = instrs[i]; if (instr.OpCode.Code != Code.Ldc_I4) { continue; } var call = instrs[i + 1]; if (call.OpCode.Code != Code.Call) { continue; } var method = call.Operand as IMethod; if (method == null) { continue; } if (!new SigComparer().Equals(type, method.DeclaringType)) { continue; } var methodDef = DotNetUtils.GetMethod(module, method); if (methodDef == null) { continue; } if (methodDef != typeMethod && methodDef != fieldMethod) { continue; } uint token = (uint)(int)instrs[i].Operand; instrs[i] = new Instr(OpCodes.Nop.ToInstruction()); instrs[i + 1] = new Instr(new Instruction(OpCodes.Ldtoken, module.ResolveToken(token, gpContext) as ITokenOperand)); } } }
internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body) { if (reader == null) { return; } var method = reader.GetMethod(ownerMethod, 1); if (method != null) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); body.PdbMethod = pdbMethod; } }
protected override List <Instruction> ReadInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) { var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions)); var instrs = new List <Instruction>(); var gpContext = GenericParamContext.Create(cilMethod); var handlerInfoReader = new OpCodeHandlerInfoReader(module, gpContext); int numVmInstrs = reader.ReadInt32(); var vmInstrs = new ushort[numVmInstrs]; for (int i = 0; i < numVmInstrs; i++) { vmInstrs[i] = reader.ReadUInt16(); } uint offset = 0; for (int vmInstrIndex = 0; vmInstrIndex < numVmInstrs; vmInstrIndex++) { var composite = opCodeDetector.Handlers[vmInstrs[vmInstrIndex]]; IList <HandlerTypeCode> handlerInfos = composite.HandlerTypeCodes; if (handlerInfos.Count == 0) { handlerInfos = new HandlerTypeCode[] { HandlerTypeCode.Nop } } ; for (int hi = 0; hi < handlerInfos.Count; hi++) { var instr = handlerInfoReader.Read(handlerInfos[hi], reader); instr.Offset = offset; offset += (uint)GetInstructionSize(instr); SetCilToVmIndex(instr, vmInstrIndex); if (hi == 0) { SetVmIndexToCil(instr, vmInstrIndex); } instrs.Add(instr); } } return(instrs); } }
protected override List <Instruction> ReadInstructions(MethodDef cilMethod, CsvmMethodData csvmMethod) { var gpContext = GenericParamContext.Create(cilMethod); var reader = new BinaryReader(new MemoryStream(csvmMethod.Instructions)); var instrs = new List <Instruction>(); uint offset = 0; while (reader.BaseStream.Position < reader.BaseStream.Length) { int vmOpCode = reader.ReadUInt16(); var instr = opCodeDetector.Handlers[vmOpCode].Read(reader, module, gpContext); instr.Offset = offset; offset += (uint)GetInstructionSize(instr); SetCilToVmIndex(instr, instrs.Count); SetVmIndexToCil(instr, instrs.Count); instrs.Add(instr); } return(instrs); }
public override SymbolMethod GetMethod(MethodDef method, int version) { var mdTable = pdbMetadata.TablesStream.MethodDebugInformationTable; uint methodRid = method.Rid; if (!mdTable.IsValidRID(methodRid)) { return(null); } var sequencePoints = ReadSequencePoints(methodRid) ?? Array2.Empty <SymbolSequencePoint>(); var gpContext = GenericParamContext.Create(method); var rootScope = ReadScope(methodRid, gpContext); var kickoffMethod = GetKickoffMethod(methodRid); var symbolMethod = new SymbolMethodImpl(this, method.MDToken.ToInt32(), rootScope, sequencePoints, kickoffMethod); rootScope.method = symbolMethod; return(symbolMethod); }
List <ExceptionHandler> ReadExceptions(MethodDef cilMethod, CsvmMethodData csvmMethod) { var reader = new BinaryReader(new MemoryStream(csvmMethod.Exceptions)); var ehs = new List <ExceptionHandler>(); if (reader.BaseStream.Length == 0) { return(ehs); } int numExceptions = reader.ReadInt32(); if (numExceptions < 0) { throw new ApplicationException("Invalid number of exception handlers"); } var gpContext = GenericParamContext.Create(cilMethod); for (int i = 0; i < numExceptions; i++) { var eh = new ExceptionHandler((ExceptionHandlerType)reader.ReadInt32()); eh.TryStart = GetInstruction(reader.ReadInt32()); eh.TryEnd = GetInstructionEnd(reader.ReadInt32()); eh.HandlerStart = GetInstruction(reader.ReadInt32()); eh.HandlerEnd = GetInstructionEnd(reader.ReadInt32()); if (eh.HandlerType == ExceptionHandlerType.Catch) { eh.CatchType = module.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef; } else if (eh.HandlerType == ExceptionHandlerType.Filter) { eh.FilterStart = GetInstruction(reader.ReadInt32()); } ehs.Add(eh); } return(ehs); }
protected override void InitializeCustomAttributes() => readerModule.InitCustomAttributes(this, ref customAttributes, GenericParamContext.Create(ownerType));
PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, long recPosEnd) { IMethodDefOrRef method; byte[] data; Local local; int count; int localIndex; switch (recKind) { case PdbCustomDebugInfoKind.UsingGroups: count = reader.ReadUInt16(); if (count < 0) { return(null); } var usingCountRec = new PdbUsingGroupsCustomDebugInfo(count); for (int i = 0; i < count; i++) { usingCountRec.UsingCounts.Add(reader.ReadUInt16()); } return(usingCountRec); case PdbCustomDebugInfoKind.ForwardMethodInfo: method = this.method.Module.ResolveToken(reader.ReadUInt32(), GenericParamContext.Create(this.method)) as IMethodDefOrRef; if (method == null) { return(null); } return(new PdbForwardMethodInfoCustomDebugInfo(method)); case PdbCustomDebugInfoKind.ForwardModuleInfo: method = this.method.Module.ResolveToken(reader.ReadUInt32(), GenericParamContext.Create(this.method)) as IMethodDefOrRef; if (method == null) { return(null); } return(new PdbForwardModuleInfoCustomDebugInfo(method)); case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: count = reader.ReadInt32(); if (count < 0) { return(null); } var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count); for (int i = 0; i < count; i++) { uint startOffset = reader.ReadUInt32(); uint endOffset = reader.ReadUInt32(); if (startOffset > endOffset) { return(null); } // Try to detect synthesized locals, whose start==end==0. The problem is that endOffset // read from the PDB is inclusive (add 1 to get 'end'), so a synthesized local and a // local at [0, 1) will be encoded the same {0, 0}. if (endOffset == 0) { smScope.Scopes.Add(new StateMachineHoistedLocalScope()); } else { var start = GetInstruction(startOffset); var end = GetInstruction(endOffset + 1); if (start == null) { return(null); } smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); } } return(smScope); case PdbCustomDebugInfoKind.StateMachineTypeName: var name = ReadUnicodeZ(recPosEnd, needZeroChar: true); if (name == null) { return(null); } var type = GetNestedType(name); if (type == null) { return(null); } return(new PdbStateMachineTypeNameCustomDebugInfo(type)); case PdbCustomDebugInfoKind.DynamicLocals: count = reader.ReadInt32(); const int dynLocalRecSize = 64 + 4 + 4 + 2 * 64; if (reader.Position + (long)(uint)count * dynLocalRecSize > recPosEnd) { return(null); } var dynLocListRec = new PdbDynamicLocalsCustomDebugInfo(count); for (int i = 0; i < count; i++) { reader.Position += 64; int flagsCount = reader.ReadInt32(); if ((uint)flagsCount > 64) { return(null); } var dynLocRec = new PdbDynamicLocal(flagsCount); var afterPos = reader.Position; reader.Position -= 64 + 4; for (int j = 0; j < flagsCount; j++) { dynLocRec.Flags.Add(reader.ReadByte()); } reader.Position = afterPos; localIndex = reader.ReadInt32(); // 'const' locals have index -1 but they're encoded as 0 by Roslyn if (localIndex != 0 && (uint)localIndex >= (uint)body.Variables.Count) { return(null); } var nameEndPos = reader.Position + 2 * 64; name = ReadUnicodeZ(nameEndPos, needZeroChar: false); reader.Position = nameEndPos; local = localIndex < body.Variables.Count ? body.Variables[localIndex] : null; // Roslyn writes 0 to localIndex if it's a 'const' local, try to undo that now if (localIndex == 0 && local != null && local.Name != name) { local = null; } if (local != null && local.Name == name) { name = null; } dynLocRec.Name = name; dynLocRec.Local = local; dynLocListRec.Locals.Add(dynLocRec); } return(dynLocListRec); case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: data = reader.ReadBytes((int)(recPosEnd - reader.Position)); return(new PdbEditAndContinueLocalSlotMapCustomDebugInfo(data)); case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: data = reader.ReadBytes((int)(recPosEnd - reader.Position)); return(new PdbEditAndContinueLambdaMapCustomDebugInfo(data)); case PdbCustomDebugInfoKind.TupleElementNames: count = reader.ReadInt32(); if (count < 0) { return(null); } var tupleListRec = new PdbTupleElementNamesCustomDebugInfo(count); for (int i = 0; i < count; i++) { int nameCount = reader.ReadInt32(); if ((uint)nameCount >= 10000) { return(null); } var tupleInfo = new PdbTupleElementNames(nameCount); for (int j = 0; j < nameCount; j++) { var s = ReadUTF8Z(recPosEnd); if (s == null) { return(null); } tupleInfo.TupleElementNames.Add(s); } localIndex = reader.ReadInt32(); uint scopeStart = reader.ReadUInt32(); uint scopeEnd = reader.ReadUInt32(); name = ReadUTF8Z(recPosEnd); if (name == null) { return(null); } Debug.Assert(localIndex >= -1); // -1 = 'const' local. Only 'const' locals have a scope Debug.Assert((localIndex == -1) ^ (scopeStart == 0 && scopeEnd == 0)); if (localIndex == -1) { local = null; tupleInfo.ScopeStart = GetInstruction(scopeStart); tupleInfo.ScopeEnd = GetInstruction(scopeEnd); if (tupleInfo.ScopeStart == null) { return(null); } } else { if ((uint)localIndex >= (uint)body.Variables.Count) { return(null); } local = body.Variables[localIndex]; } if (local != null && local.Name == name) { name = null; } tupleInfo.Local = local; tupleInfo.Name = name; tupleListRec.Names.Add(tupleInfo); } return(tupleListRec); default: Debug.Fail("Unknown custom debug info kind: 0x" + ((int)recKind).ToString("X")); data = reader.ReadBytes((int)(recPosEnd - reader.Position)); return(new PdbUnknownCustomDebugInfo(recKind, data)); } }
protected override MarshalType GetMarshalType_NoLock() => readerModule.ReadMarshalType(this, GenericParamContext.Create(ownerType));
internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body, uint methodRid) { Debug.Assert((module == null) == (ownerMethod == null)); if (reader == null || body == null) { return; } var token = new SymbolToken((int)(0x06000000 + methodRid)); ISymbolMethod method; #if THREAD_SAFE theLock.EnterWriteLock(); try { #endif method = reader.GetMethod(token); if (method != null) { var pdbMethod = new PdbMethod(); pdbMethod.Scope = CreateScope(module, ownerMethod == null ? new GenericParamContext() : GenericParamContext.Create(ownerMethod), body, method.RootScope); AddSequencePoints(body, method); var method2 = method as ISymbolMethod2; Debug.Assert(method2 != null); if (module != null && method2 != null && method2.IsAsyncMethod) { pdbMethod.AsyncMethod = CreateAsyncMethod(module, ownerMethod, body, method2); } if (ownerMethod != null) { // Read the custom debug info last so eg. local names have been initialized var cdiData = reader.GetSymAttribute(token, "MD2"); if (cdiData != null && cdiData.Length != 0) { PdbCustomDebugInfoReader.Read(ownerMethod, body, pdbMethod.CustomDebugInfos, cdiData); } } body.PdbMethod = pdbMethod; } #if THREAD_SAFE } finally { theLock.ExitWriteLock(); } #endif }