I had a client last week in Melbourne who wanted to salvage some code from an existing SharePoint 2010 implementation. As long as it wasn't obfuscated, then I thought there would be no problems at all.
Red Gate's (previously Lutz Roeder's) Reflector is designed for just a situation - and I'd recently purchased the awesome VS PRO version (which is phenomenal lets you step and debug through other people's applications!).
However, when I tried to open up the assemblies in Reflector or on ILDASM, it appeared to indeed be obfuscated - by the Smart Assembly tool from Red Gate.
Typically, the obfuscated code will be shown with an error or garbled characters. e.g. "This item is obfuscated and can not be translated." - as below:
If you try and open it in ILDASM, it throws an exception as below:
This is because the Assembly has the CompilerServices "SuppressIldasmAttribute" applied to it.
However, if you open up the assembly with the new tool JetBrains dotPeek (the makers of Resharper), then you will be able to see the source code - even of those allegedly obfuscated methods and properties.
I'm not sure whether Red Gate deliberately set a flag inside Reflector when they purchased it from Lutz Roeder - but it seems like a few shortcuts were taken with the obfuscation engine.
So be warned - not all Reflectors and not all Obfuscation methods are created equal.
DDK
The Musings and Findings of Software Consultant David Klein (Sydney, Australia)
Showing posts with label Reflection. Show all posts
Showing posts with label Reflection. Show all posts
Thursday, 7 July 2011
Tuesday, 31 March 2009
Rendering Different Colors for each row in an ASP.NET Gridview
This is simple as handling the MyGridViewName_RowDataBound event. The following code sample is used in the following scenario:
NB. An alternative (and preferred) to using relection to get the nested property is using LINQ projection - which is how I did it when I checked the code into source. control. However, the code sample above still illustrates the topic of this post.
- The grid is bound to a LINQDataSource (the e.Row.DataItem has a type of "DynamicClass" and so cannot be cast directly)
- Consequently uses reflection to get a nested property inside the e.Row.DataItem, then casts that to a known LINQ2SQL class.
- From this reflected information, grabs the display colour HEX value (e.g. #CCFFCC and converts it to a System.Drawing.Color colour (by using System.Drawing.ColorTranslator).
protected void proposalListGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
DoPBusiness.PlanningProposalTracking.PP_LIST_Status status =
(DoPBusiness.PlanningProposalTracking.PP_LIST_Status)
e.Row.DataItem.GetType()
.GetProperty("PP_LIST_Status")
.GetValue(e.Row.DataItem, null);
e.Row.BackColor = System.Drawing.ColorTranslator.FromHtml(status.DisplayColour);
}
}
NB. An alternative (and preferred) to using relection to get the nested property is using LINQ projection - which is how I did it when I checked the code into source. control. However, the code sample above still illustrates the topic of this post.
Tuesday, 28 October 2008
How do I get the underlying type of a Generic List?
The Type.GetGenericArguments() method will let you determine the underlying type of the elements of a list object at runtime. See this article for more information.
http://msdn.microsoft.com/en-us/library/system.type.getgenericarguments.aspx
For example:
http://msdn.microsoft.com/en-us/library/system.type.getgenericarguments.aspx
For example:
if (t.IsGenericType){
// If this is a generic type, display the type arguments.
//
Type[] typeArguments = t.GetGenericArguments();
Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);foreach (Type tParam in typeArguments)
{
// If this is a type parameter, display its
// position.
//
if (tParam.IsGenericParameter)
{
Console.WriteLine("\t\t{0}\t(unassigned - parameter position {1})",tParam,
tParam.GenericParameterPosition);
}
else
{
Console.WriteLine("\t\t{0}", tParam);
}
}
}
Monday, 19 May 2008
Simple Auditing with LINQ to SQL - Date, Time and User Stamps
My previous post was on automatically generating basic auditing fields on SQL Server tables via SQL scripts. Today, I examine the other side of the coin - using the LINQ data context to stamp records with audit fields such as "Modified","ModifiedBy", "Created" and "CreatedBy". These stamps are similar to the functionality provided by the windows file system.
There are many ways you can populate application audit tables or audit fields. These include:
There are many ways you can populate application audit tables or audit fields. These include:
- With Triggers (but this relies on the SQL authenication mechanism for accurate user data);
- With stored procedures (this also relies on the accuracy of SQL authentication information or you need to append the user name to the parameters of the procedure.)
- On the Application Side - Manually coding all service/database calls to append this information.
- Use a SQL Server log auditing tool like LogExplorer that tracks the SQL Server transaction log.
- Leveraging your data access layer's update point to append this information before the update takes place.
Below you can find my code which takes the last approach - and uses reflection to stamp records with when a record was created/updated and who did the insert/update. This is a simplified alternative to an audit solution (such as http://blog.matthidinger.com/2008/05/09/LINQToSQLAuditTrail.aspx) which has a full audit table and where requirements are just to display who last modified or created a particular record in your application:
/// <summary>
/// Basic Audit User and Date Stamp Functionality
/// </summary>
/// <param name="failureMode"></param>
public override void SubmitChanges(ConflictMode failureMode)
{
//Updates
for (int changeCounter = 0; changeCounter < this.GetChangeSet().Updates.Count; changeCounter++)
{
object modifiedEntity = this.GetChangeSet().Updates[changeCounter];
SetAuditStamp(this, modifiedEntity, ChangeType.Update);
}
//Inserts
for (int changeCounter = 0; changeCounter < this.GetChangeSet().Inserts.Count; changeCounter++)
{
object modifiedEntity = this.GetChangeSet().Inserts[changeCounter];
SetAuditStamp(this, modifiedEntity, ChangeType.Insert);
}
base.SubmitChanges(failureMode);
}
/// <summary>
/// For Inserts or Updates - set the user and date stamps
/// </summary>
/// <param name="context"></param>
/// <param name="modifiedEntity"></param>
private void SetAuditStamp(DataContext context, object modifiedEntity, ChangeType changeType)
{
string userName = System.Threading.Thread.CurrentPrincipal.Identity.Name;
const string Created = "Created", CreatedBy = "CreatedBy",
Modified = "Modified", ModifiedBy = "ModifiedBy";
if (changeType == ChangeType.Insert)
{
SetAuditValue(modifiedEntity, Created, System.DateTime.Now);
SetAuditValue(modifiedEntity, CreatedBy, userName);
}
else if (changeType == ChangeType.Update)
{
SetAuditValue(modifiedEntity, Modified, System.DateTime.Now);
SetAuditValue(modifiedEntity, ModifiedBy, userName);
}
}
/// <summary>
/// The type of modifications
/// </summary>
private enum ChangeType
{
Update,
Insert
}
/// <summary>
/// Set target value if it exists on the object
/// </summary>
/// <param name="modifiedEntity"></param>
/// <param name="fieldName"></param>
/// <param name="propertyValue"></param>
private void SetAuditValue(object modifiedEntity, string fieldName, object propertyValue)
{
if (modifiedEntity.GetType().GetProperty(fieldName) != null) //Set current user and time stamp
{
modifiedEntity.GetType().GetProperty(fieldName).SetValue(modifiedEntity, propertyValue, null);
}
}
Wednesday, 19 March 2008
Reflection - using GetType(string) to create an instance of a type is returning null
My colleague "CS" today had issues with resolving types in our Lookup Service. The problem: he was trying to use GetType(string) to resolve a type that was in another assembly. e.g. Type sourceType = GetType(string.Format("DDK.Common.Lookups{0}",lookupTypeName))
Problem was that it couldn't resolve the name - even though the dll was referenced and the calling assembly could resolve the name if it needed to.
This article is much better than MSDN in explaning the issue http://blogs.msdn.com/haibo_luo/archive/2005/08/21/454213.aspx. In attempting to resolve the type, GetType() will first look in the current calling assembly, then in mscorlib. It will NOT trawl through all your references in the bin directory for you like it does with normal type resolution - it will just give up if it is not in mscorlib or the current assembly and return a whopping great null.
Instead, you have to give the .NET runtime a hand and tell it which assembly to look in. This is why you have to do the same thing when specifying dynamically loaded types in the web.config - you have to put the fully qualified names so the runtime it can resolve the type with the same GetType(string) mechanism. The simplest way to find this out is to just look at the project properties to find the name of the output assembly name. Alternatively, you can make an instance of your object e.g. new DDK.Common.Lookups.Country().GetType().AssemblyQualifiedName to get the full name that the runtime uses to uniquely identify the type.
In our case, changing the code to include the red (ie the AssemblyQualifiedName minus any version numbers did the trick). ie
Type sourceType = GetType(string.Format("DDK.Common.Lookups.{0}, DDK.Common.Lookups",lookupTypeName))
Problem was that it couldn't resolve the name - even though the dll was referenced and the calling assembly could resolve the name if it needed to.
This article is much better than MSDN in explaning the issue http://blogs.msdn.com/haibo_luo/archive/2005/08/21/454213.aspx. In attempting to resolve the type, GetType() will first look in the current calling assembly, then in mscorlib. It will NOT trawl through all your references in the bin directory for you like it does with normal type resolution - it will just give up if it is not in mscorlib or the current assembly and return a whopping great null.
Instead, you have to give the .NET runtime a hand and tell it which assembly to look in. This is why you have to do the same thing when specifying dynamically loaded types in the web.config - you have to put the fully qualified names so the runtime it can resolve the type with the same GetType(string) mechanism. The simplest way to find this out is to just look at the project properties to find the name of the output assembly name. Alternatively, you can make an instance of your object e.g. new DDK.Common.Lookups.Country().GetType().AssemblyQualifiedName to get the full name that the runtime uses to uniquely identify the type.
In our case, changing the code to include the red (ie the AssemblyQualifiedName minus any version numbers did the trick). ie
Type sourceType = GetType(string.Format("DDK.Common.Lookups.{0}, DDK.Common.Lookups",lookupTypeName))
Subscribe to:
Posts (Atom)