public static void Serialize(Assembly assembly, System.IO.Stream stream) { CultureInfo prevCulture = SwapCulture(); try { OpCodeList.LoadOpCodes(); Package package = new Package(); foreach (MethodBase mb in FindMethods(assembly)) { MethodBody body = new MethodBody(mb); String procName = Helper.GetFullMethodName(mb, assembly); Procedure p = new Procedure(procName); foreach (Instruction ili in body.GetInstructions()) { ILInstr i = new ILInstr(ili, assembly); p.AddInstruction(i); } package.AddProcedure(p); } package.Prepare(); XmlSerializer s = new XmlSerializer(typeof(Package)); System.IO.MemoryStream ms = new System.IO.MemoryStream(); using (System.IO.StreamWriter wr = new System.IO.StreamWriter(stream, Encoding.UTF8, 8192, true)) { s.Serialize(wr, package); } } finally { SwapCulture(prevCulture); } }
private void BuildInstructions(Module module) { byte[] il = this.iarr; int position = 0; while (position < il.Length) { Instruction instruction = new Instruction(); // get the operation code of the current instruction OpCode code = OpCodes.Nop; ushort value = il[position++]; if (value != 0xfe) { code = OpCodeList.GetSingleByteOpCode((ushort)value); } else { value = il[position++]; code = OpCodeList.GetMultiByteOpCode((ushort)value); value = (ushort)(value | 0xfe00); } instruction.Code = code; instruction.Offset = position - 1; int metadataToken = 0; // get the operand of the current operation switch (code.OperandType) { case OperandType.InlineBrTarget: metadataToken = ReadInt32(il, ref position); metadataToken += position; instruction.Operand = metadataToken; break; case OperandType.InlineField: metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveField(metadataToken); break; case OperandType.InlineMethod: metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveMethod(metadataToken); break; case OperandType.InlineSig: metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveSignature(metadataToken); break; case OperandType.InlineTok: metadataToken = ReadInt32(il, ref position); try { instruction.Operand = module.ResolveType(metadataToken); } catch { try { instruction.Operand = module.ResolveField(metadataToken); } catch { throw new Exception("token cant be resolved"); } } break; case OperandType.InlineType: metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveType(metadataToken, this.mb.DeclaringType.GetGenericArguments(), this.mb.GetGenericArguments()); break; case OperandType.InlineI: { instruction.Operand = ReadInt32(il, ref position); break; } case OperandType.InlineI8: { instruction.Operand = ReadInt64(il, ref position); break; } case OperandType.InlineNone: { instruction.Operand = null; break; } case OperandType.InlineR: { instruction.Operand = ReadDouble(il, ref position); break; } case OperandType.InlineString: { metadataToken = ReadInt32(il, ref position); instruction.Operand = module.ResolveString(metadataToken); break; } case OperandType.InlineSwitch: { int count = ReadInt32(il, ref position); int[] casesAddresses = new int[count + 1]; for (int i = 1; i <= count; i++) { casesAddresses[i] = ReadInt32(il, ref position); } int[] cases = new int[count + 1]; cases[0] = count; for (int i = 1; i <= count; i++) { cases[i] = position + casesAddresses[i]; } instruction.Operand = cases; break; } case OperandType.InlineVar: { instruction.Operand = ReadUInt16(il, ref position); break; } case OperandType.ShortInlineBrTarget: { instruction.Operand = ReadSByte(il, ref position) + position; break; } case OperandType.ShortInlineI: { instruction.Operand = ReadSByte(il, ref position); break; } case OperandType.ShortInlineR: { instruction.Operand = ReadSingle(il, ref position); break; } case OperandType.ShortInlineVar: { instruction.Operand = ReadByte(il, ref position); break; } default: { throw new Exception("Unknown operand type."); } } instructions.Add(instruction); } }