Tag Archives: Dotnet

Indexers as Extension Methods?

So I’ve had this nagging issue for a little while. It’s not necessarily a huge issue because I have a workaround, but that said, it still nags at me now and again. That issue is that I cannot create an indexer as an extension method. This isn’t possible for a number of reasons that make sense, but I thought I’d blog about it anyway and solicit thoughts on the idea.

First, let’s talk about what we can do. I can create an extension method for any existing class. Let’s say I have the following class already created:

public class SomeClass{
   public int SomeProperty { get; set; }
}

 

I can then extend a List of SomeClass pretty easily like this:

public static class Extensions{
   public static string SomeListExtensionProperty(this List<SomeClass> classes)   {
      //… provide implementation here …
   }
}

 

Notice that I’ve scoped my extension to only extend a generic List of SomeClass. For instance I can do this:

var sc = new List<SomeClass>();string s = sc.SomeListExtensionProperty();

 

but I cannot do this:

var soc = new List<SomeOtherClass>();
string s = soc.SomeListExtensionProperty();

 

So what would happen if I tried to extend the List of SomeClass with an indexer like this:

public static string this[int index](this List<SomeClass> classes){
 return classes[i].SomeProperty;
}

 

We wouldn’t get past compilation. First of all, the word “this” and “static” don’t mix or tend to make sense together in most cases. That is because “this” refers to an instance of a class while “static” refers to type itself. In general, mixing these two wouldn’t make sense. That said, we already mix these two keywords when we create extension methods. So that isn’t the only reason this wouldn’t work. The next reason is that the generic List class already provides an indexer. Since you can’t override existing members with extensions, you are left without the ability to create an indexer with an extension.

Our only recourse would be to provide extension methods that provide the same functionality as a method.

public static string GetSomeProperty(this List<SomeClass> classes, int index){
   return classes[index].SomeProperty;
}

 

We can then call something like this:

var sc = new List<SomeClass>();
string s = sc.GetSomeProperty(index);

 

This isn’t quite as abbreviated as an indexer and in fact doesn’t save me anything over what I would get with the out-of-the-box generic List indexer:

var sc = new List<SomeClass>();
string s = sc[index].SomeProperty;

 

That said, the “nagging issue” is more of a request for a solution looking for a problem. Obviously indexers are great shorthand that ‘can’ provide a ‘default property’ so-to-speak. However, it is very easy to get what you want without much work.

IIS 7 Logging UI For Vista – Download Now

As many of you already know, the management console for IIS 7.0 on Windows Vista does not have a UI for logging.  Since this was a pain point for several customers, I decided to test out the extensibility APIs by creating a logging UI module. 

I’ve posted a preview version of my logging UI on the newly opened IIS Download Center. I will be releasing a few updates throughout the week with changes. The module also contains the source code for my UI module under the Microsoft Permissive License. This code will also be updated in future releases.

You can find the download at: http://www.iis.net/downloads/default.aspx?tabid=34&i=1328&g=6

If you have any questions, please feel free to contact me through my blog.

SynchronizationAttribute snake-oil

I have now been asked twice why you wouldn’t just use the [Synchronization] attribute when you want to make a class thread-safe. I figured I’d share what little information I have on this topic to you since I happen to have an answer. (as opposed to “the” answer which I never have).


As the saying goes, “There is no such thing as a free lunch.” I never really understood this saying as a kid. I grew up in a poor neighborhood and got “free lunches” all the time. Being financially challenged, I used to laugh and say “well, this is free”. As I’ve gotten older, and much more financially stable, I realize that my tax dollars are paying for the lunches for other kids in other neighborhood — apparently they are eating very well.


The same holds true for this special attribute. If you may think you are getting thread-safty for free, I have some snake-oil to sell you. There are several problems with the SynchronizationAttribute. Take a look at the required signature for use of the synchronization attribute:


[Synchronization]
public class SuperSensativeClass :
System.Runtime.Remoting.Contexts.ContextBoundObject
{
// Implementation here
}


First, the attribute requires that you inherit from ContextBoundObject — wasting your single-inheritance chain. If you wanted it in your object your most primitive object in the inheritance chain would have to derive from this class, and then what if you didn’t want some other child classes to be context bound?


Second, suppose your class has several methods which don’t have thread-sensative data. What happens there? The CLR will still lock those methods since it has no idea what is thread-volatile and what isn’t. This can severely hamper performance.


If you are looking at thread-safety, you are likely trying to optimize the perceived performance of your application using multi-threading. The SynchronizationAttribute can actually have the exact opposite effect. Long story short, learn to use the synchronization primatives of System.Threading.

Throw-away projects in .NET

There are tons of new features in Whidbey. Enough so that I feel that the learning curve going from 1.1 to 2.0 can be easily 50% that of the effort going from to 2.0 (if not more). You can spend your time learning generics and predicates and partial classes and reliability contracts for threading and , well, you name it. However, sometimes its the little features that mean so much. VS.NET 2005 provides a little known feature that allows you to create projects, run them, test them, etc. However, unlike you might be currently used to, when you close the project, you can make the whole thing go away. In other words, you can open VS.NET to test a theory, run the project, do your debugging, and then dump the project so it isn’t wasting file space of virus scanner time. To impliment this feature, go to Tools | Options to display the options dialog. Under this dialog, choose the Projects and Solutions tree node.Uncheck this “save new projects when created” checkbox. Apply the changes.


Now, when you close VS.NET with an open/active project, it will ask you if you want to save it. If you click no, the folders are complete gone. Isn’t that awesome!?


Well, I liked it anyway.

Singularity

Here’s another quick post. Microsoft Research is writing an operating system in C#! I’ve been talking about wanting to do this for a while. There was even some mention of this from JasonZ when the CLR team came to Atalanta a while ago. Definitely looks like a fun project to keep up with.

.NET Code Access Security – The fast version

I spoke at this months GSP Developers Guild meeting as the “short presenter”. We typically have two presentations each month — one is a short presentation and one is a long presentation. I had to cut my Code Camp slides in half, but I managed to only overrun a 30 minute presentation by say, 15 minutes :) Glen Gordon was our “long presenter” today. He gave a great presentation on ASP.NET Mobile Controls. I knew the presentation material, but its always great to see people respond to the technology like they did. Glen is a beast — he gave a 4 hour long presentation at the Greenville MSDN event today too. From 1pm to 5pm today he discussed Web Services, SQL Server 2005 with end point registration, Infopath consumption of the web services and end points, ClickOnce deployment and more. He then took a quick drive over to the guild meeting to give another hour-long talk on mobile web development. It was a geek decathalon!

Thanks for the great day guys. I had a blast giving my presentation again. And I really enjoyed watching your presentations again Glen.

Fun with default compilation: VB.NET vs C#

I’m not a language elitist by any means. I came from a Visual Basic background and avoided C++ when I could. These days, however, I’m more of a C# guy. I feel like there is sufficient gain in using the language without much, if any development-time penalty associated with using it. While I don’t mind someone stating their reasons for using one language over the other, I will not tolerate the argument that these languages compile to the same IL and work just as well. The VB.NET and C# compilers were written by two different teams. They emitted MSIL completely different from one another by default, and with good reason on both sides. As such, there are some major differences in the IL that is output. I pointed one out the other day when talking about delegate implementation in C# vs VB.NET. Today, I’m noting another.


VB and C# Specific Language


Let’s take a look at the following scenario. I’ve created two projects in both languages and implemented the same code in both. In the form’s class, I have an array list with 100 items in it, a button control and a label control. For the button’s click event handler, I added the following code:

Private Sub Button1_Click(ByVal sender As System.Object, _
   ByVal e As System.EventArgs) _
   Handles Button1.Click

   For i As Int32 = 1 To list.Count
     Me.lblOutput.Text += list(i - 1).ToString()
   Next
End Sub

This code simply loops through all of the items in the array list and outputs them to the label. Notice that I’m not caching the results of list.Count first. Instead, I’m evaluating this each time in the loop. This raises the hairs on the backs of several people’s necks every time I talk about it. I’ll explain my decision to do this later though. In the mean time, let’s look at what the C# output looks like:

for( int i = 1; i <= list.Count ; i++ ) {
    this.lblOutput.Text += list[i-1].ToString();
}

Again, this whole section has the least optimal of coding decisions, but it is done in an attempt to make these two pieces of code do the same work.


The IL Comparison


These look about the same, but the problem is evident when you look at the IL. Yesterday I posted an example where the IL in VB.NET was using virtual dispatch for delegates whereas C# was using instance dispatch. Virtual dispatches are much more expensive. So what is the problem here? Let’s start by looking at the IL for the C# and VB.NET versions of this code. In C# we have a cool 34 lines of IL:

.method private hidebysig instance void button1_Click(object sender,
       class [mscorlib]System.EventArgs e) cil managed
{
  // Code size  64 (0x40)
  .maxstack  5
  .locals init ([0] int32 i)
  IL_0000:  ldc.i4.1
  IL_0001:  stloc.0
  IL_0002:  br.s  IL_0031
  IL_0004:  ldarg.0
  IL_0005:  ldfld class [System.Windows.Forms]System.Windows.Forms.Label CSharpLoop.Form1::lblOutput
  IL_000a:  dup
  IL_000b:  callvirt
            instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Text()
  IL_0010:  ldarg.0
  IL_0011:  ldfld class [mscorlib]System.Collections.ArrayList CSharpLoop.Form1::list
  IL_0016:  ldloc.0
  IL_0017:  ldc.i4.1
  IL_0018:  sub
  IL_0019:  callvirt instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
  IL_001e:  callvirt instance string [mscorlib]System.Object::ToString()
  IL_0023:  call  string [mscorlib]System.String::Concat(string, string)
  IL_0028:  callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)
  IL_002d:  ldloc.0
  IL_002e:  ldc.i4.1
  IL_002f:  add
  IL_0030:  stloc.0
  IL_0031:  ldloc.0
  IL_0032:  ldarg.0
  IL_0033:  ldfld  class [mscorlib]System.Collections.ArrayList CSharpLoop.Form1::list
  IL_0038:  callvirt  instance int32 [mscorlib]System.Collections.ArrayList::get_Count()
  IL_003d:  ble.s  IL_0004
  IL_003f:  ret
} // end of method Form1::button1_Click

But in VB.NET, take a look at the IL hit here — 44 lines of code.

.method private instance void  Button1_Click(object sender,
          class [mscorlib]System.EventArgs e) cil managed
{
  // Code size  72 (0x48)
  .maxstack  5
  .locals init ([0] int32 i,
      [1] class [System.Windows.Forms]System.Windows.Forms.Label _Vb_t_ref_0,
      [2] int32 _Vb_t_i4_0)
  IL_0000:  nop
  IL_0001:  ldc.i4.1
  IL_0002:  ldarg.0
  IL_0003:  ldfld  class [mscorlib]System.Collections.ArrayList VBLoop.Form1::list
  IL_0008:  callvirt  instance int32 [mscorlib]System.Collections.ArrayList::get_Count()
  IL_000d:  stloc.2
  IL_000e:  stloc.0
  IL_000f:  br.s  IL_0042
  IL_0011:  ldarg.0
  IL_0012:  callvirt instance class [System.Windows.Forms]System.Windows.Forms.Label VBLoop.Form1::get_lblOutput()
  IL_0017:  stloc.1
  IL_0018:  ldloc.1
  IL_0019:  ldloc.1
  IL_001a:  callvirt instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Text()
  IL_001f:  ldarg.0
  IL_0020:  ldfld  class [mscorlib]System.Collections.ArrayList VBLoop.Form1::list
  IL_0025:  ldloc.0
  IL_0026:  ldc.i4.1
  IL_0027:  sub.ovf
  IL_0028:  callvirt instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
  IL_002d:  callvirt  instance string [mscorlib]System.Object::ToString()
  IL_0032:  call  string [mscorlib]System.String::Concat(string,string)
  IL_0037:  callvirt  instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)
  IL_003c:  nop
  IL_003d:  nop
  IL_003e:  ldloc.0
  IL_003f:  ldc.i4.1
  IL_0040:  add.ovf
  IL_0041:  stloc.0
  IL_0042:  ldloc.0
  IL_0043:  ldloc.2
  IL_0044:  ble.s  IL_0011<
  IL_0046:  nop
  IL_0047:  ret
} // end of method Form1::Button1_Click

There are 10 additional IL lines for the same exact code — four of which appear to be unnecessary “nop” fields. The MSDN help for nop states: “Fills space if opcodes are patched. No meaningful operation is performed although a processing cycle can be consumed.” So despite the fact that these instructions do nothing, they can be wasting important processing cycles, which, if executed in a loop such as ours can be quite expensive over the long run.

Let’s break this down a bit further to see exactly what’s happening in these functions. Let’s evaluate the C# side first so I can pick on VB.NET’s IL later and show you where it’s going, well, wrong :)


C# IL Code Analysis


First off, the C# header is pretty standard.

.method private hidebysig instance void button1_Click(object sender,
        class [mscorlib]System.EventArgs e) cil managed
{
  // Code size  64 (0x40)
  .maxstack   5

Next we see our locally scoped declarations. In this instance, we only have one variable that is initialized as an int32. This will be the variable that we use in our loop counter.

  .locals init ([0] int32 i)

We then push an int32 value of 1 onto the evaluation stack and immediately pop it back off into the local variable we declared above.

  IL_0000:  ldc.i4.1
  IL_0001:  stloc.0

The next step is fairly interesting for anyone that hasn’t seen IL before. We are transferring control to the instruction at the IL_0031 label. We’ll cover this in a minute.

  IL_0002:  br.s  IL_0031

We are now going to load the first argument onto the evaluation stack (stack size +1). This happens to be the “sender” parameter of the click event. We use the ldfld call to push the label on the stack. The IL is just preparing the text value to be concatenated in the loop.

  IL_0004:  ldarg.0
  IL_0005:  ldfld  class [System.Windows.Forms]System.Windows.Forms.Label CSharpLoop.Form1::lblOutput

Having fun so far? Good, let’s keep on trucking. Next, we are doing something fairly interesting. We are going to duplicate topmost item on the evaluation stack and push it onto the stack as well. The way this happens is fairly complicated for such a small field name. First, the value is pushed onto the stack, popped off the stack and duplicated, then pushed back onto the stack. Once we’ve performed three operations to get that done, we perform one more to push the duplicated value on the stack. Remember out += operator in the code? Sound like something a += operator might want to do? I hope so :). Next, we are going to use callvirt to push the return value of the label’s Text property onto the evaluation stack.

  IL_000a:  dup
  IL_000b:  callvirt  instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Text()

We’ve seen the next series before so I’ll spare you the detailed explaination. We are pushing our array list onto the stack. We need this so we can get our count later.

  IL_0010:  ldarg.0
  IL_0011:  ldfld  class [mscorlib]System.Collections.ArrayList CSharpLoop.Form1::list

Remember way back at the start of this method, we initialized a local variable? Well now we are going to load it. We then pushes an int32 value of 1 onto the evaluation stack again.

  IL_0016:  ldloc.0
  IL_0017:  ldc.i4.1

We do our subtraction that is done in the array indexer (“i-1″).

  IL_0018:  sub

Next we use callvirt again to get the item at the index provided by the result of the sub field’s return value. Without delay, we call that object’s ToString method and store the return value on the stack.

  IL_0019:  callvirt  instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
  IL_001e:  callvirt  instance string [mscorlib]System.Object::ToString()

Of course, our call is concatenating strings so we call the String.Concat method using our Control’s text value again. Notice when we called concat we are using “call” instead of callvirt? This is because we know the object is a native type, String. We used callvirt against our controls because these objects can be recast at run-time. Therefore the callvirt method is used to call the method against the runtime type of the object, not the compile time type.

  IL_0023:  call  string [mscorlib]System.String::Concat(string,string)
  IL_0028:  callvirt  instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)

Here we go again with this sequence! This time we are loading the values from our first parameter so we can increment the value with the “add” field. This adds the value 1 to the value stored at location 0. Make sense? Good, because we then have to call stloc again to store the value back into location 0.

  IL_002d:  ldloc.0
  IL_002e:  ldc.i4.1
  IL_002f:  add
  IL_0030:  stloc.0

Now we have to load the value stored in our first initialized value again so we can do our “for(;;)” comparison. We compare this value against the value returned from the ArrayList’s Count method.

  IL_0031:  ldloc.0
  IL_0032:  ldarg.0
  IL_0033:  ldfld  class [mscorlib]System.Collections.ArrayList CSharpLoop.Form1::list
  IL_0038:  callvirt  instance int32 [mscorlib]System.Collections.ArrayList::get_Count()

Remember back near the beginning of all of this, we transferred control to an instruction at IL_0031 ? Well now we are transferring control back to IL_0004. If this sounds like loop control instructions to you, you’d be right. Lastly, this method ends with a return call. Since this method is void, we don’t return any values.

  IL_003d:  ble.s  IL_0004
  IL_003f:  ret
  } // end of method Form1::button1_Click

Was this code really necessary for a simple loop!? Sadly, yes. But before you get upset, lets remember that we have 10 extra lines in our VB.NET compiled IL! I wont rehash all of the VB.NET code like we did with C#, but I will concentrate on the differences because that’s what causes our performance hit in VB.NET.


VB.NET IL Code Analysis


Take a look at the first difference — the initialized variables.Notice that we have 3 variables declared here instead of 1. The first is the variable that we use in the loop, and the second is a reference to the label that we will use in the loop. The third is used to cache the value of the Count() method later on. Rather than evaluate this within the loop, we will cache this value in a local variable and use this value in our loop comparison.

 .locals init ([0] int32 i,
      [1] class [System.Windows.Forms]System.Windows.Forms.Label _Vb_t_ref_0,
      [2] int32 _Vb_t_i4_0)

The next thing I’ll touch on is those nasty nop calls. These are annoying but are there for debugging support. These allow you to place break points in code that have no execution. These are just placeholders, but as said, they do waste instructions. Try compiling these in release mode instead of debug mode to get rid of these. You should be doing this anyway when you are testing the performance of your code.

The IL that follows is representative of what we’ve already said. The label will be loaded as a local variable along with a cached value of the variable. These values are obtained and stored in location 0 and 2 respectively. (stloc.0 and stloc.2 fields)

  L_0001: ldc.i4.1
  L_0002: ldarg.0
  L_0003: ldfld [mscorlib]System.Collections.ArrayList VBLoop.Form1::list
  L_0008: callvirt instance int32 [mscorlib]System.Collections.ArrayList::get_Count()
  L_000d: stloc.2
  L_000e: stloc.0

We do the same loop control we had before with the br.s call and then move in to load the first argument (our label) and put it on the stack. We load the value stored in the local variable stored in location 1 twice (ldloc.1). Notice this is different than the C# version of “dup”.

  L_0011: ldarg.0
  L_0012: callvirt instance [System.Windows.Forms]System.Windows.Forms.Label VBLoop.Form1::get_lblOutput()
  L_0017: stloc.1
  L_0018: ldloc.1
  L_0019: ldloc.1

Moving forward we get our text value of the output label and start our loop through the array list.

  L_001a: callvirt instance string [System.Windows.Forms]System.Windows.Forms.Control::get_Text()
  L_001f: ldarg.0
  L_0020: ldfld [mscorlib]System.Collections.ArrayList VBLoop.Form1::list

We load our first local variable and do our subtraction again. But notice our subtraction call is different.

  L_0025: ldloc.0
  L_0026: ldc.i4.1
  L_0027: sub.ovf

This version of sub.ovf is used to do overflow checking on the subtraction operation. This is turned on by default in VB.NET compilation, but turned off in C# compilation.

We take the same steps to load the item in our array list, get the result of the ToString call, concatenate the value, and then set the text value of our label that we did in the C# version.

  L_0028: callvirt instance object [mscorlib]System.Collections.ArrayList::get_Item(int32)
  L_002d: callvirt instance string object::ToString()
  L_0032: call string string::Concat(string, string)
  L_0037: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)

As we draw near the end of our IL, again go through the steps to increment our loop counter. After we put some more of those annoying little nop calls. Just as the subtraction call did overflow checking, the add method does overflow checking, hence the change from add to add.ovf.

  L_003c: nop
  L_003d: nop
  L_003e: ldloc.0
  L_003f: ldc.i4.1
  L_0040: add.ovf
  L_0041: stloc.0

We end our IL nicely by reloading our variables in position 0 and 2 before returning to the front of our loop.

  L_0042: ldloc.0
  L_0043: ldloc.2
  L_0044: ble.s L_0011
  L_0046: nop
  L_0047: ret
}

Summary


This has really just been an informational look at how the compilers differ by default. Its entirely possible to change a few parameters in the compilers to get the output to look a bit more alike. Its important to know these differences, though, so that you can make educated decisions on how you should optimize your code based on what language you are working with. Happy hacking.

Pro .NET 1.1 Remoting, Reflection and Threading

I received 10 shiny copies of my new book that is now available at BarnesAndNoble.com (or amazon.com if you really must buy through them). Its a pretty interesting mix of technologies from .NET that helps bring a novice programmer up to date. While I’m much more of a C# programmer these days, based on my VB background this book was necessary. My reasoning can be found on the back cover of the book:

“Dear Reader,

Rapid Application Development has long been the purpose and strong point of a Visual Basic Developer. In the past VB versions, we had to solve more complex problems than the language designers ever intended. Of course, this fed the flames of those language elitists that said VB was an inferior language. With the introduction of .NET, many VB developers were overwhelmed with the task of learning programming in the object-oriented paradigm that was, perhaps, completely new to them; couple that with learning the .NET libraries, the CLR, and changes in the language we had been using for years, and many developers initially found it hard to shoulder the burden.

Coming from a VB background, I see firsthand how many developers barely have the time to grasp these concepts, let alone the additional intricacies of some of the more powerful features newly available to VB developers in the .NET world. Those powerful topics, as the book title suggests, are Remoting, Reflection and Threading. This book is compiled to help VB developers reinvigorate their learning by adding these powerful new skills to their tool belts. The topics in this book can help you take a standard application from satisfactory to out-standing. By adding background processing through threading, scalability with remoting, and extensibility with reflection, you can give your applications a uniquely professional touch. The details in this book will show you how to add these powerful features to your applications and will prepare you to compete head to head with other language developers.”

Anyway, I’m excited because this is my first hard cover book. Bill has already had his say on that topic. Donbt worry Bill, Ibm writing another book now in my spare time that will probably be written on tissue paper and covered with newspaper and finger-paint.

Exploit using System.String? Not Really

I’ve been playing around in the CLR for some time just playing with quirks and oddities.  I  noted some time ago that non-printable characters were easily stored in strings.  This really wasn’t a suprise except that a null character (“”) could be stored and appropriately retrieved from a string.  If I embedded a null character in a string, it didn’t cause the string to truncate when I read it back.  This made me wonder just how the string class knew how large its buffer was. How did it know which null character was it’s terminator?

Since my upcoming book deals, in part, with Reflection, I decided to try some playing around with the string object using MemberInfo. I found something rather interesting.  The string class keeps track of how large its buffer is in a member variable called m_stringLength.  So I started to wonder, what would happen if I created a string and then used reflection to change the length?

I decided to make this interesting.  I first created an example class that would represent a class handling sensitive data.  My code was simple and was as follows:

using System;

namespace CodeWithSecrets {

  // Lets assume this is a class that handles connection strings
  // or other sensative data.
  class ConnectionStringGuardian {
     public ConnectionStringGuardian() {
        connect = "uid=sa;pwd=LoveSexSecretGod";
     }
  }
}

I put this class in its own class library assembly named “CodeWithSecrets”. Then came the code that I would use to exploit the “ConnectionStringGuardian” class. 

using System;
using System.Reflection; 
using CodeWithSecrets;

namespace MalCode{ 
  class Malware {
    [STAThread]
    static void Main(string[] args) {
      ReadPastBuffer();
    }
    private static void ReadPastBuffer() {
      // Storing some variable
        String stringObj = "12345"; 
      // Store an object with private data in it
        ConnectionStringGuardian obj = new ConnectionStringGuardian();
      // Getting the String Type
        Type stringType = Type.GetType("System.String");
      // Getting a reference to the private field in System.String 
        FieldInfo fi = stringType.GetField( "m_stringLength", 
          BindingFlags.Instance|BindingFlags.NonPublic);
      // Read the string object 
        Console.WriteLine( "Reflected String: '{0}'", stringObj );
      // Set the private variable that keeps track of string length;
        Object parameter = 255;
        fi.SetValue( stringObj, parameter );
      // Read the reflected string  
      Console.WriteLine( "Expanded Buffer: '{0}'", stringObj );
      Console.ReadLine();
    }
  }
}

To explain what I’ve done here, I created a typical string holding an arbitrary value.  I then create an instance of my class that holds secret data.  Using reflection, I then access the private m_stringLength member to increase the size of the string’s buffer to 255. Finally, I output my string to the console to see if I can read past my buffer in a managed string. As you’ll notice, I write the string’s value to the console before increasing the buffer size, and then I write the strings value to the console again after modifying the buffer size.  The following screen shot depicts the results:

Malicious Code

Notice that I was able to read past the buffer and into the memory where the sensitive data was stored.  (First person to name the movie the sample password comes from gets a free Apress t-shirt if you send me your address.)

Now this is not really an exploit other than the fact that I can read memory to possibly sensitive data.  I tried to do other things to the memory such as stomp on it by calling the private “NullTerminate()” method that I found using reflection as well.  NullTerminate writes a null terminator at the end of a buffer using the m_stringLength value to determine just where to put that value.  This, unfortunately, did not overwrite the data in memory as I was expecting.  Ultimately, I was thinking that I might be able to break the type safety of an assembly by stomping on memory belonging to an instance. 

The problem with this code (or perhaps the good thing to note if you are an MS security expert) is that I have to use reflection to pull this off. I wouldn’t be able to execute this in a partial trust environment. If I downloaded this code in the internet zone, the reflection permission is not permitted by default. This severely cripples my attempts to make this tidbit worthwhile.  As Michael Howard responded to me: “fully trusted code is fully trusted code.”  True enough.

In any case, I hope this serves as some sort of education in some more internals of the string class. Let me know what you think. 

(P.S. No need to make the obvious statement that sensitive data shouldn’t be stored in classes.)

Old News, But Blog-worthy

There was an old article posted some time ago by James Gosling at Sun. I’ve been meaning to post about it but every time I had a spare moment, someone yanked it from me. In any case, in this article Gosling was shouting some ideas that Microsoft was breaking their Trustworty Computing Initiative’s rules by allowing C++ and C into the .NET family of developer products. Gosling was quoted as saying:

“If you look at the security model in Java and the reliability model, and a lot of things in the exception handling, they depend really critically on the fact that there is some integrity to the properties of objects. So if somebody gives you an object and says ‘This is an image’, then it is an image. It’s not like a pointer to a stream, where it just casts an image,”

Basically, Gosling wants people to feel that as soon as these products were made a part of the .NET product line, they made all other .NET code insecure due to violations of type safety.

Mr Gosling evidently hasn’t studied code access security 101. When an assembly is loaded in .NET it is verified by the CLR before it is allowed to execute. Verification is pretty extensive.

In brief, let’s consider what all happens when an assembly is loaded and executed. First off, the portable executable is validated to make sure it conforms to the PE/COEFF standard. Secondly, all the metadata is validated , making sure that all pointers have valid destinations. A symantec check looks for any sort of shinanigins such as circular inheritance. Next, the IL is verified to be valid and well-formed. As each method is JITed the code is verified to be memory type safe — looking for unsafe casts and attempts to access array indexes that are out of bounds. It probes for buffer overruns and underruns.

There is one caveat to all of this. C++ indeed cannot generally be verified. There is (currently) no way to verify type safety of code written in C++. So does this make Mr Gosling right about his statements? NO. He’s absolutely wrong — and I don’t just say that because I like pretending I know more than the CTO of a multi-national corporation. I say this because security policy in .NET by default rejects any code that cannot pass all of these verifications. To get .NET to run assemblies compiled in C++, it must have the permission to skip verification. If we look at the permission viewere in the .NET configuration tool, we can view any permission set that has the security permission selected. If we double click on the Security permission, there are several sub-permissions available to us. The one we are concerned with is the Skip verification permission. The diagram below depicts this setting in case you don’t feel like looking at this yourself.

This isn’t to say that Mr Gosling wasn’t right at all, but it does put a rather large kink in his argument that there is a HUGE security hole in .NET. Code that executes on the local machine will have this permission because by default all code running in the MyComputer zone runs with FullTrust. Full Trust includes all permissions — including the SkipVerification permission. Yes, if I’m honest with myself I have to say that is a problem, but not in the sense that someone will download code or execute something from the internet that will automatically wreck havoc on the entire type safety system. If I had one wish from he security team at Microsoft it would be to turn this feature off by default.