The MSDN documentation on Object.GetHashCode() describes 3 contradicting rules for how the method should work.
I can't know for sure how Object.GetHashCode is implemented in real .NET Framework, but in Rotor it uses SyncBlock index for the object as hashcode. There are some blog posts about it on the web, however most of them are from 2005.