Hi,

I've tried to load many assemblies with Cecil. It works perfect for
standard assemblies.
But for some "non-standard" assemblies, such as obfuscated by
Spices.net (http://www.9rays.net/Products/Spices.Net/),
there are some problems.

Here are ny findings and patches for sharing:

ReflectionReader.cs:
public TypeDefinition GetTypeDefAt (uint rid)
{
            //wicky.start
            //rid is 0 for some obfuscated assemblies
            if (rid < 1 || rid > m_typeDefs.Length)
                return null;
            //wicky.end
        return m_typeDefs [rid - 1];
}

CodeReader.cs:
void ReadCilBody (MethodBody body, BinaryReader br, out IDictionary
instructions)
{
        ...........
        case OperandType.InlineMethod :
          MetadataToken meth = new MetadataToken (br.ReadInt32 ());
          switch (meth.TokenType) {
            case TokenType.Method:
            instr.Operand = m_reflectReader.GetMethodDefAt (meth.RID);
            break;
          case TokenType.MemberRef:
            instr.Operand = m_reflectReader.GetMemberRefAt (meth.RID,
context);
            break;
          case TokenType.MethodSpec:
            instr.Operand = m_reflectReader.GetMethodSpecAt (meth.RID,
context);
            break;
                    //wicky.start
                    //operand is Field?
                   case TokenType.Field:
                     instr.Operand =
m_reflectReader.GetFieldDefAt(meth.RID);
                     break;
                    //wicky.end
           default:
            throw new ReflectionException ("Wrong token for InlineMethod
Operand: " + meth);
        }
        break;
 ..........
 }

public override void VisitInstructionCollection (InstructionCollection
instructions)
{
............
        case OperandType.InlineMethod :
          if (instr.Operand is GenericInstanceMethod)
          WriteToken (m_reflectWriter.GetMethodSpecToken (instr.Operand as
GenericInstanceMethod));
          else if (instr.Operand is MethodReference)
          WriteToken ((instr.Operand as MethodReference).MetadataToken);
                    //wicky.start
                    //Operand is Field?
                    else if (instr.Operand is FieldReference)
                        WriteToken((instr.Operand as
FieldReference).MetadataToken);
                    //wicky.end
        else
        throw new ReflectionException ("Wrong operand for InlineMethod:
{0}",            instr.Operand.GetType ().FullName);
        break;
.............
}

UserStringsHeap.cs:
string ReadStringAt (int offset)
{
 int length = Utilities.ReadCompressedInteger (this.Data, offset, out
offset);
 if (length == 0)
        return string.Empty;

           //wicky.comment.start
            //for obfuscated string, .Net 2.0's Unicode may not get
correct string
            //however, .Net 1.0 handle same string properly
            //reason is .Net 2.0 has more checking
            //solution is use my own Unicode class with same logic
as .Net 1.0
        return Encoding.Unicode.GetString (this.Data, offset, length - 1);
            //wicky.comment.end
}

AggressiveReflectionReader.cs:
void ReadProperties ()
{
.............
int start = (int) pmapRow.PropertyList, end;
if (i < pmapTable.Rows.Count - 1)
  end = (int) pmapTable [i + 1].PropertyList;
else
  end = propsTable.Rows.Count + 1;

                //wicky.start
                //for some obfuscated assemblies, PropertyList is
65535?
                if (end > propsTable.Rows.Count + 1) end =
propsTable.Rows.Count + 1;
                //wicky.end
.............
}

Regards
wicky


--~--~---------~--~----~------------~-------~--~----~
--
mono-cecil
-~----------~----~----~----~------~----~------~--~---

Reply via email to