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
-~----------~----~----~----~------~----~------~--~---