Browse Source

Decompile security declarations. Closes #189.

pull/194/merge
Daniel Grunwald 14 years ago
parent
commit
32081feb1b
  1. 64
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 139
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

64
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -126,6 +126,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -126,6 +126,7 @@ namespace ICSharpCode.Decompiler.Ast
public void AddAssembly(AssemblyDefinition assemblyDefinition, bool onlyAssemblyLevel = false)
{
ConvertCustomAttributes(astCompileUnit, assemblyDefinition, "assembly");
ConvertSecurityAttributes(astCompileUnit, assemblyDefinition, "assembly");
ConvertCustomAttributes(astCompileUnit, assemblyDefinition.MainModule, "module");
if (!onlyAssemblyLevel) {
@ -990,6 +991,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -990,6 +991,7 @@ namespace ICSharpCode.Decompiler.Ast
void ConvertAttributes(AttributedNode attributedNode, TypeDefinition typeDefinition)
{
ConvertCustomAttributes(attributedNode, typeDefinition);
ConvertSecurityAttributes(attributedNode, typeDefinition);
// Handle the non-custom attributes:
#region SerializableAttribute
@ -1040,6 +1042,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -1040,6 +1042,7 @@ namespace ICSharpCode.Decompiler.Ast
void ConvertAttributes(AttributedNode attributedNode, MethodDefinition methodDefinition)
{
ConvertCustomAttributes(attributedNode, methodDefinition);
ConvertSecurityAttributes(attributedNode, methodDefinition);
MethodImplAttributes implAttributes = methodDefinition.ImplAttributes & ~MethodImplAttributes.CodeTypeMask;
@ -1194,7 +1197,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -1194,7 +1197,7 @@ namespace ICSharpCode.Decompiler.Ast
attr.AddNamedArgument("ArraySubType", MakePrimitive((int)ami.ElementType, unmanagedType));
if (ami.Size >= 0)
attr.AddNamedArgument("SizeConst", new PrimitiveExpression(ami.Size));
if (ami.SizeParameterMultiplier != 0)
if (ami.SizeParameterMultiplier != 0 && ami.SizeParameterIndex >= 0)
attr.AddNamedArgument("SizeParamIndex", new PrimitiveExpression(ami.SizeParameterIndex));
}
CustomMarshalInfo cmi = marshalInfo as CustomMarshalInfo;
@ -1296,6 +1299,65 @@ namespace ICSharpCode.Decompiler.Ast @@ -1296,6 +1299,65 @@ namespace ICSharpCode.Decompiler.Ast
}
}
static void ConvertSecurityAttributes(AstNode attributedNode, ISecurityDeclarationProvider secDeclProvider, string attributeTarget = null)
{
if (!secDeclProvider.HasSecurityDeclarations)
return;
var attributes = new List<ICSharpCode.NRefactory.CSharp.Attribute>();
foreach (var secDecl in secDeclProvider.SecurityDeclarations) {
foreach (var secAttribute in secDecl.SecurityAttributes) {
var attribute = new ICSharpCode.NRefactory.CSharp.Attribute();
attribute.AddAnnotation(secAttribute);
attribute.Type = ConvertType(secAttribute.AttributeType);
attributes.Add(attribute);
SimpleType st = attribute.Type as SimpleType;
if (st != null && st.Identifier.EndsWith("Attribute", StringComparison.Ordinal)) {
st.Identifier = st.Identifier.Substring(0, st.Identifier.Length - "Attribute".Length);
}
var module = secAttribute.AttributeType.Module;
var securityActionType = new TypeReference("System.Security.Permissions", "SecurityAction", module, module.TypeSystem.Corlib);
attribute.Arguments.Add(MakePrimitive((int)secDecl.Action, securityActionType));
if (secAttribute.HasProperties) {
TypeDefinition resolvedAttributeType = secAttribute.AttributeType.Resolve();
foreach (var propertyNamedArg in secAttribute.Properties) {
var propertyReference = resolvedAttributeType != null ? resolvedAttributeType.Properties.FirstOrDefault(pr => pr.Name == propertyNamedArg.Name) : null;
var propertyName = new IdentifierExpression(propertyNamedArg.Name).WithAnnotation(propertyReference);
var argumentValue = ConvertArgumentValue(propertyNamedArg.Argument);
attribute.Arguments.Add(new AssignmentExpression(propertyName, argumentValue));
}
}
if (secAttribute.HasFields) {
TypeDefinition resolvedAttributeType = secAttribute.AttributeType.Resolve();
foreach (var fieldNamedArg in secAttribute.Fields) {
var fieldReference = resolvedAttributeType != null ? resolvedAttributeType.Fields.FirstOrDefault(f => f.Name == fieldNamedArg.Name) : null;
var fieldName = new IdentifierExpression(fieldNamedArg.Name).WithAnnotation(fieldReference);
var argumentValue = ConvertArgumentValue(fieldNamedArg.Argument);
attribute.Arguments.Add(new AssignmentExpression(fieldName, argumentValue));
}
}
}
}
if (attributeTarget == "module" || attributeTarget == "assembly") {
// use separate section for each attribute
foreach (var attribute in attributes) {
var section = new AttributeSection();
section.AttributeTarget = attributeTarget;
section.Attributes.Add(attribute);
attributedNode.AddChild(section, AttributedNode.AttributeRole);
}
} else if (attributes.Count > 0) {
// use single section for all attributes
var section = new AttributeSection();
section.AttributeTarget = attributeTarget;
section.Attributes.AddRange(attributes);
attributedNode.AddChild(section, AttributedNode.AttributeRole);
}
}
private static Expression ConvertArgumentValue(CustomAttributeArgument argument)
{
if (argument.Value is CustomAttributeArgument[]) {

139
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -18,7 +18,9 @@ @@ -18,7 +18,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Mono.Cecil;
using Mono.Collections.Generic;
@ -198,6 +200,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -198,6 +200,7 @@ namespace ICSharpCode.Decompiler.Disassembler
foreach (var p in method.Parameters) {
WriteParameterAttributes(p);
}
WriteSecurityDeclarations(method);
if (method.HasBody) {
// create IL code mappings - used in debugger
@ -208,6 +211,140 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -208,6 +211,140 @@ namespace ICSharpCode.Decompiler.Disassembler
CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name));
}
#region Write Security Declarations
void WriteSecurityDeclarations(ISecurityDeclarationProvider secDeclProvider)
{
if (!secDeclProvider.HasSecurityDeclarations)
return;
foreach (var secdecl in secDeclProvider.SecurityDeclarations) {
output.Write(".permissionset ");
switch (secdecl.Action) {
case SecurityAction.Request:
output.Write("request");
break;
case SecurityAction.Demand:
output.Write("demand");
break;
case SecurityAction.Assert:
output.Write("assert");
break;
case SecurityAction.Deny:
output.Write("deny");
break;
case SecurityAction.PermitOnly:
output.Write("permitonly");
break;
case SecurityAction.LinkDemand:
output.Write("linkcheck");
break;
case SecurityAction.InheritDemand:
output.Write("inheritcheck");
break;
case SecurityAction.RequestMinimum:
output.Write("reqmin");
break;
case SecurityAction.RequestOptional:
output.Write("reqopt");
break;
case SecurityAction.RequestRefuse:
output.Write("reqrefuse");
break;
case SecurityAction.PreJitGrant:
output.Write("prejitgrant");
break;
case SecurityAction.PreJitDeny:
output.Write("prejitdeny");
break;
case SecurityAction.NonCasDemand:
output.Write("noncasdemand");
break;
case SecurityAction.NonCasLinkDemand:
output.Write("noncaslinkdemand");
break;
case SecurityAction.NonCasInheritance:
output.Write("noncasinheritance");
break;
default:
output.Write(secdecl.Action.ToString());
break;
}
output.WriteLine(" = {");
output.Indent();
for (int i = 0; i < secdecl.SecurityAttributes.Count; i++) {
SecurityAttribute sa = secdecl.SecurityAttributes[i];
if (sa.AttributeType.Scope == sa.AttributeType.Module) {
output.Write("class ");
output.Write(DisassemblerHelpers.Escape(GetAssemblyQualifiedName(sa.AttributeType)));
} else {
sa.AttributeType.WriteTo(output, ILNameSyntax.TypeName);
}
output.Write(" = {");
if (sa.HasFields || sa.HasProperties) {
output.WriteLine();
output.Indent();
foreach (CustomAttributeNamedArgument na in sa.Fields) {
output.Write("field ");
WriteSecurityDeclarationArgument(na);
output.WriteLine();
}
foreach (CustomAttributeNamedArgument na in sa.Properties) {
output.Write("property ");
WriteSecurityDeclarationArgument(na);
output.WriteLine();
}
output.Unindent();
}
output.Write('}');
if (i + 1< secdecl.SecurityAttributes.Count)
output.Write(',');
output.WriteLine();
}
output.Unindent();
output.WriteLine("}");
}
}
void WriteSecurityDeclarationArgument(CustomAttributeNamedArgument na)
{
TypeReference type = na.Argument.Type;
if (type.MetadataType == MetadataType.Class || type.MetadataType == MetadataType.ValueType) {
output.Write("enum ");
if (type.Scope != type.Module) {
output.Write("class ");
output.Write(DisassemblerHelpers.Escape(GetAssemblyQualifiedName(type)));
} else {
type.WriteTo(output, ILNameSyntax.TypeName);
}
} else {
type.WriteTo(output);
}
output.Write(' ');
output.Write(DisassemblerHelpers.Escape(na.Name));
output.Write(" = ");
WriteConstant(na.Argument.Value);
}
string GetAssemblyQualifiedName(TypeReference type)
{
AssemblyNameReference anr = type.Scope as AssemblyNameReference;
if (anr == null) {
ModuleDefinition md = type.Scope as ModuleDefinition;
if (md != null) {
anr = md.Assembly.Name;
}
}
if (anr != null) {
return type.FullName + ", " + anr.FullName;
} else {
return type.FullName;
}
}
#endregion
#region WriteMarshalInfo
void WriteMarshalInfo(MarshalInfo marshalInfo)
{
@ -698,6 +835,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -698,6 +835,7 @@ namespace ICSharpCode.Decompiler.Disassembler
bool oldIsInType = isInType;
isInType = true;
WriteAttributes(type.CustomAttributes);
WriteSecurityDeclarations(type);
if (type.HasLayoutInfo) {
output.WriteLine(".pack {0}", type.PackingSize);
output.WriteLine(".size {0}", type.ClassSize);
@ -917,6 +1055,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -917,6 +1055,7 @@ namespace ICSharpCode.Decompiler.Disassembler
output.Write(".assembly " + DisassemblerHelpers.Escape(asm.Name.Name));
OpenBlock(false);
WriteAttributes(asm.CustomAttributes);
WriteSecurityDeclarations(asm);
if (asm.Name.PublicKey != null && asm.Name.PublicKey.Length > 0) {
output.Write(".publickey = ");
WriteBlob(asm.Name.PublicKey);

Loading…
Cancel
Save