コード例 #1
0
  //-------------------------------------------------------------------------------------
  internal static void Customize(byte[] body, DynamicILInfo ilInfo, Dictionary<int, DiscoverMemberInfo> schema)
  {
   BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.GetField |  BindingFlags.Instance | 
                                       BindingFlags.Static;
   ArrayReader ar = new ArrayReader(body);
   while(ar.CanRead)
   {
    int offset = ar.Position;
    OpCode opCode = OpCodes.Nop;
    //int token = 0;

    Byte code = ar.ReadByte();
    if(code != 0xFE)
     opCode = OneByteOpCodes[code];
    else
     opCode = TwoByteOpCodes[ar.ReadByte()];

    switch(opCode.OperandType)
    {
     #region ...
     case OperandType.InlineNone: break;
     //The operand is an 8-bit integer branch target.
     case OperandType.ShortInlineBrTarget: ar.ReadSByte(); break;
     //The operand is a 32-bit integer branch target.
     case OperandType.InlineBrTarget: ar.ReadInt32(); break;
     //The operand is an 8-bit integer: 001F  ldc.i4.s, FE12  unaligned.
     case OperandType.ShortInlineI: ar.ReadByte(); break;
     //The operand is a 32-bit integer.
     case OperandType.InlineI: ar.ReadInt32(); break;
     //The operand is a 64-bit integer.
     case OperandType.InlineI8: ar.ReadInt64(); break;
     //The operand is a 32-bit IEEE floating point number.
     case OperandType.ShortInlineR: ar.ReadSingle(); break;
     //The operand is a 64-bit IEEE floating point number.
     case OperandType.InlineR: ar.ReadDouble(); break;
     //The operand is an 8-bit integer containing the ordinal of a local variable or an argument
     case OperandType.ShortInlineVar: ar.ReadByte(); break;
     //The operand is 16-bit integer containing the ordinal of a local variable or an argument.
     case OperandType.InlineVar: ar.ReadUInt16(); break;
     #endregion ...

     //The operand is a 32-bit metadata string token.
     case OperandType.InlineString:
     {
      #region ...
      int token = ar.ReadInt32();
      string s = new String(schema[token].Name.ToCharArray());
      ar.OverwriteInt32(ilInfo.GetTokenFor(s), offset + opCode.Size); 
      #endregion ...
     }
     break;

     //The operand is a 32-bit metadata signature token.
     case OperandType.InlineSig:
     {
      #region ...
      throw new Exception("НАДО ПРОВЕРИТЬ InlineSig !!!");
      //int token = ar.ReadInt32();
      //OverwriteInt32(ilInfo.GetTokenFor(inlineSigInstruction.Signature),
      //inlineSigInstruction.Offset + inlineSigInstruction.OpCode.Size);

      #endregion ...
     }
     //break;

     //The operand is a 32-bit metadata token.
     case OperandType.InlineMethod:
     {
      #region ...
      int token = ar.ReadInt32();
      MethodBase mi;
      Type t = schema[token].DeclaringType; // ?? dstType;
      if(schema[token].Name.StartsWith(".ctor"))
       mi = t.GetConstructor(bf, null, schema[token].ParametersTypes, null);
      else
       mi = t.GetMethod(schema[token].Name, bf, null, schema[token].ParametersTypes, null);
      if(mi == null)
       throw new PulsarException("Не удалось определить MethodBase для операнда {0}:{1}", opCode, opCode.OperandType);
      ar.OverwriteInt32(ilInfo.GetTokenFor(mi.MethodHandle, t.TypeHandle), offset + opCode.Size); 
      #endregion ...
     }
     break;

     //The operand is a 32-bit metadata token.
     case OperandType.InlineField:
     {
      #region ...
      int token = ar.ReadInt32();
      FieldInfo fi = schema[token].DeclaringType.GetField(schema[token].Name, bf | BindingFlags.FlattenHierarchy);
      if(fi == null)
       throw new PulsarException("Не удалось определить FieldInfo для операнда {0}:{1}", opCode, opCode.OperandType);
      ar.OverwriteInt32(ilInfo.GetTokenFor(fi.FieldHandle), offset + opCode.Size); 
      #endregion ...
     }
     break;

     //The operand is a 32-bit metadata token.
     case OperandType.InlineType:
     {
      #region ...
      int token = ar.ReadInt32();
      Type t = schema[token].DeclaringType;
      ar.OverwriteInt32(ilInfo.GetTokenFor(t.TypeHandle), offset + opCode.Size); 
      #endregion ...
     }
     break;

     //The operand is a FieldRef, MethodRef, or TypeRef token.
     case OperandType.InlineTok:
     {
      #region ...
      throw new Exception("НАДО ПРОВЕРИТЬ InlineTok !!!");
      //int token = ar.ReadInt32();
      //     MemberInfo mi = inlineTokInstruction.Member;
      //int token = 0;
      //if(mi.MemberType == MemberTypes.TypeInfo || mi.MemberType == MemberTypes.NestedType)
      //{
      // Type type = mi as Type;
      // token = ilInfo.GetTokenFor(type.TypeHandle);
      //}
      //else if(mi.MemberType == MemberTypes.Method || mi.MemberType == MemberTypes.Constructor)
      //{
      // MethodBase m = mi as MethodBase;
      // token = ilInfo.GetTokenFor(m.MethodHandle, m.DeclaringType.TypeHandle);
      //}
      //else if(mi.MemberType == MemberTypes.Field)
      //{
      // FieldInfo f = mi as FieldInfo;
      // //CLR BUG: token = ilInfo.GetTokenFor(f.FieldHandle, f.DeclaringType.TypeHandle);
      // token = ilInfo.GetTokenFor(f.FieldHandle);
      //}

      //OverwriteInt32(token,
      //   inlineTokInstruction.Offset + inlineTokInstruction.OpCode.Size);

      #endregion ...
     }
     //break;

     //The operand is the 32-bit integer argument to a switch instruction.
     case OperandType.InlineSwitch:
     {
      #region ...
      throw new Exception("НАДО ПРОВЕРИТЬ InlineSwitch !!!");
      //Int32 cases = ar.ReadInt32();
      //Int32[] deltas = new Int32[cases];
      //for(Int32 i = 0; i < cases; i++)
      // deltas[i] = ar.ReadInt32();

      #endregion ...
     }
     //break;
     default: throw new BadImageFormatException("Unexpected OperandType " + opCode.OperandType);
    }

   }
  }
コード例 #2
0
  //-------------------------------------------------------------------------------------
  internal static Dictionary<int, DiscoverMemberInfo> Discover(byte[] body, MethodInfo mi, Type dstType)
  {
   Dictionary<int, DiscoverMemberInfo> res = new Dictionary<int, DiscoverMemberInfo>();

   ArrayReader ar = new ArrayReader(body);
   while(ar.CanRead)
   {
    int offset = ar.Position;
    OpCode opCode = OpCodes.Nop;
    //int token = 0;

    Byte code = ar.ReadByte();
    if(code != 0xFE)
     opCode = OneByteOpCodes[code];
    else
     opCode = TwoByteOpCodes[ar.ReadByte()];

    switch(opCode.OperandType)
    {
     #region ...
     case OperandType.InlineNone: break;
     //The operand is an 8-bit integer branch target.
     case OperandType.ShortInlineBrTarget: ar.ReadSByte(); break;
     //The operand is a 32-bit integer branch target.
     case OperandType.InlineBrTarget: ar.ReadInt32(); break;
     //The operand is an 8-bit integer: 001F  ldc.i4.s, FE12  unaligned.
     case OperandType.ShortInlineI: ar.ReadByte(); break;
     //The operand is a 32-bit integer.
     case OperandType.InlineI: ar.ReadInt32(); break;
     //The operand is a 64-bit integer.
     case OperandType.InlineI8: ar.ReadInt64(); break;
     //The operand is a 32-bit IEEE floating point number.
     case OperandType.ShortInlineR: ar.ReadSingle(); break;
     //The operand is a 64-bit IEEE floating point number.
     case OperandType.InlineR: ar.ReadDouble(); break;
     //The operand is an 8-bit integer containing the ordinal of a local variable or an argument
     case OperandType.ShortInlineVar: ar.ReadByte(); break;
     //The operand is 16-bit integer containing the ordinal of a local variable or an argument.
     case OperandType.InlineVar: ar.ReadUInt16(); break;
     #endregion ...

     //The operand is a 32-bit metadata string token.
     case OperandType.InlineString:
     {
      #region ...
      int token = ar.ReadInt32();
      if(res.ContainsKey(token))
       break;
      string s = mi.Module.ResolveString(token);
      res.Add(token, new DiscoverMemberInfo(s)); 
      #endregion ...
     }
     break;

     //The operand is a 32-bit metadata signature token.
     case OperandType.InlineSig:
     {
      #region ...
      throw new Exception("НАДО ПРОВЕРИТЬ InlineSig !!!");
      //int token = ar.ReadInt32();
      //if(res.ContainsKey(token))
      // break;

      #endregion ...
     }
     //break;

     //The operand is a 32-bit metadata token.
     case OperandType.InlineMethod:
     {
      #region ...
      int token = ar.ReadInt32();
      if(res.ContainsKey(token))
       break;
      MethodBase mb = mi.Module.ResolveMethod(token);
      if(mb == null)
       throw new PulsarException("Не удалось определить MethodBase для операнда {0}:{1}", opCode, opCode.OperandType);

      DiscoverMemberInfo dmi = new DiscoverMemberInfo();
      dmi.Name = mb.Name;
      dmi.GenericArguments = (mb.IsConstructor) ? null : mb.GetGenericArguments();
      //dmi.DeclaringTypeGenericArguments = (mb.DeclaringType ?? typeof(Type)).GetGenericArguments();
      dmi.ParametersTypes = dmi.GetParametesTypes(mb.GetParameters());
      if(mi.DeclaringType.Equals(mb.DeclaringType))
       dmi.DeclaringType = dstType;
      else
       dmi.DeclaringType = mb.DeclaringType;
      res.Add(token, dmi); 
      #endregion ...
     }
     break;

     //The operand is a 32-bit metadata token.
     case OperandType.InlineField:
     {
      #region ...
      int token = ar.ReadInt32();
      if(res.ContainsKey(token))
       break;
      FieldInfo fi = mi.Module.ResolveField(token);
      if(fi == null)
       throw new PulsarException("Не удалось определить FieldInfo для операнда {0}:{1}", opCode, opCode.OperandType);

      DiscoverMemberInfo dmi = new DiscoverMemberInfo();
      dmi.Name = fi.Name;
      if(mi.DeclaringType.Equals(fi.DeclaringType))
       dmi.DeclaringType = dstType;
      else
       dmi.DeclaringType = fi.DeclaringType;
      res.Add(token, dmi); 
      #endregion ...
     }
     break;

     //The operand is a 32-bit metadata token.
     case OperandType.InlineType:
     {
      #region ...
      int token = ar.ReadInt32();
      if(res.ContainsKey(token))
       break;
      Type t = mi.Module.ResolveType(token, null, null);
      if(t == null)
       throw new PulsarException("Не удалось определить Type для операнда {0}:{1}", opCode, opCode.OperandType);

      DiscoverMemberInfo dmi = new DiscoverMemberInfo();
      dmi.Name = t.FullName;
      dmi.DeclaringType = t;
      dmi.GenericArguments = t.GetGenericArguments();
      res.Add(token, dmi); 
      #endregion ...
     }
     break;

     //The operand is a FieldRef, MethodRef, or TypeRef token.
     case OperandType.InlineTok:
     {
      #region ...
      throw new Exception("НАДО ПРОВЕРИТЬ InlineTok !!!");
      //int token = ar.ReadInt32();
      //if(res.ContainsKey(token))
      // break;
      //     MemberInfo mi = inlineTokInstruction.Member;
      //int token = 0;
      //if(mi.MemberType == MemberTypes.TypeInfo || mi.MemberType == MemberTypes.NestedType)
      //{
      // Type type = mi as Type;
      // token = ilInfo.GetTokenFor(type.TypeHandle);
      //}
      //else if(mi.MemberType == MemberTypes.Method || mi.MemberType == MemberTypes.Constructor)
      //{
      // MethodBase m = mi as MethodBase;
      // token = ilInfo.GetTokenFor(m.MethodHandle, m.DeclaringType.TypeHandle);
      //}
      //else if(mi.MemberType == MemberTypes.Field)
      //{
      // FieldInfo f = mi as FieldInfo;
      // //CLR BUG: token = ilInfo.GetTokenFor(f.FieldHandle, f.DeclaringType.TypeHandle);
      // token = ilInfo.GetTokenFor(f.FieldHandle);
      //}

      //OverwriteInt32(token,
      //   inlineTokInstruction.Offset + inlineTokInstruction.OpCode.Size);

      #endregion ...
     }
     // break;

     //The operand is the 32-bit integer argument to a switch instruction.
     case OperandType.InlineSwitch:
     {
      #region ...
      throw new Exception("НАДО ПРОВЕРИТЬ InlineSwitch !!!");
      //Int32 cases = ar.ReadInt32();
      //Int32[] deltas = new Int32[cases];
      //for(Int32 i = 0; i < cases; i++)
      // deltas[i] = ar.ReadInt32();

      #endregion ...
     }
     //break;
     default:
     throw new BadImageFormatException("Unexpected OperandType " + opCode.OperandType);
    }
   }
   return res;
  }