Changing generic type parameters to "T1", "T2", etc.

This is the last article (for the time being - I may someday take a look at anonymizing event and interface names) where I modify Roslyn to (optionally) "anonymize" (obfuscate) various things in a C# program. This is fairly simple, the advantage being that generic type parameters names are not visible from other modules so there is no need to persist the modified parameter names or numbers. (And even if these names were visible externally the renaming scheme is so simple that the new names could be deduced externally anyway.)

However, in making this modification and testing it on a larger test program than I'd previously used I discovered that much of the code I've previously displayed in these blog articles was too simplistic to handle many real world situations. So I had to rewrite and expand most of the code, and this implies that most of what I've previously shown is junk.

Anyway, here's the code that I've changed and added to Roslyn to anonymize the generic type parameters.

src\Compilers\Core\Portable\PEWriter\MetadataWriter.cs

This source file is part of the CodeAnalysis project in Roslyn. In the Visual Studio Solution Explorer it can be found under CodeAnalysis - PEWriter.

Compared with the previous steps one more method has been modified.

private void PopulateGenericParameters( ImmutableArray<IGenericParameter> sortedGenericParameters) { foreach (IGenericParameter genericParameter in sortedGenericParameters) { // CONSIDER: The CLI spec doesn't mention a restriction on the Name column of the GenericParam table, // but they go in the same string heap as all the other declaration names, so it stands to reason that // they should be restricted in the same way. //Yacks13: Change all generic type parameter names to "T1", "T2", etc. if creating // an anonymized output module StringHandle parameterNameHandle = AnonymizeGenericTypeParameter(genericParameter); var genericParameterHandle = metadata.AddGenericParameter( parent: GetDeclaringTypeOrMethodHandle(genericParameter), attributes: GetGenericParameterAttributes(genericParameter), //name: GetStringHandleForNameAndCheckLength(genericParameter.Name, genericParameter), name: parameterNameHandle, index: genericParameter.Index); foreach (var refWithAttributes in genericParameter.GetConstraints(Context)) { var genericConstraintHandle = metadata.AddGenericParameterConstraint( genericParameter: genericParameterHandle, constraint: GetTypeHandle(refWithAttributes.TypeRef)); AddCustomAttributesToTable(genericConstraintHandle, refWithAttributes.Attributes); } } }

src\Compilers\Core\Portable\PEWriter\MetadataWriter.Yacks.cs

This is a source file which has been added to the CodeAnalysis project. One additional method has been added.

/// <summary> /// Method to either "anonymize" a C# generic type parameter name if applicable, or else to do /// standard processing to emit the parameter name. (Some of the code in this method is copied /// from original code in the MetadataWriter.PopulateGenericParameters() method.) /// </summary> private StringHandle AnonymizeGenericTypeParameter(IGenericParameter genericParameter) { if (EmittingAnonymized()) return metadata.GetOrAddString("T" + (genericParameter.Index + 1)); return GetStringHandleForNameAndCheckLength(genericParameter.Name, genericParameter); }

Testing

As mentioned in the introduction, when testing these modifications I made some temporary changes to a different C# library program than I'd previously been using and used the modified Roslyn compiler to compile it. Here are a couple of screen shots (with highlighting added) to show the generic type parameter metadata for the non-anonymized and the anonymized versions of the MCollections assembly, as displayed by JetBrains dotPeek. (Incidentally, JetBrains dotPeek is an amazing program, and has been invaluable in helping me develop my Roslyn modifications.)

ModRos 13 Snap1

ModRos 13 Snap2

You must login to post a comment.
Loading comment... The comment will be refreshed after 00:00.

Be the first to comment.