This is the twelfth part of the .NET Internals Cookbook series. For your convenience you can find other parts in the table of contents in Part 0 – Table of contents

82. What is a bit-mapped attribute? Custom attribute? Pseudo-custom attribute?

There are three types of attributes:

  1. Bit-mapped — for instance public
  2. Custom — the “normal” attributes like [MyCustom]
  3. Pseudo-custom — look like custom attributes but behave like bit-mapped ones, for instance Serializable

Let’s take this code:

Which you can decompile to:

So you can see that the Serializable attribute is applied in the class signature:

Custom attribute is initialized this way:

See also this post.

83. What is a handle-recycling attack?

SafeHandle identifies a native handle assigned by operating system. Handles are just numbers in a handle table which can be reused. Imagine a situation that you push a handle on the stack and then the thread is paused. Other thread closes the handle, opens something new and gets the same integer value. Now our thread is resumed and continues with the handle it already pushed on the stack but now the handle identifies different resource.

84. What handle types do we have in .NET?
  • Strong handle – like a normal reference
  • Short weak handle – doesn’t stop the object from cleaning up, does not track the object if it is resurrected
  • Long weak handle – like short weak handle but tracks the object after it gets resurrected
  • Pinned handle – strong handle which doesn’t allow the object to be moved
  • Async pinned handle – like pinned handle but GC knows that it can be unpinned after async (typically I/O) operation is completed
  • Ref count handle – handle counting references, used for COM interop
  • Dependent handle – used by ConditionalWeakTable, connects two objects by strong handle, but from the outside is like a weak handle

You can see those by running !gchandles in WinDBG:

85. What is a ref local?

.NET has a concept of managed pointers — pointers not necessarily pointing to the beginning of the object. They can point to local variables, parameters and parts of an object (including array elements).

ref local is a variable storing a managed pointer. You can use it like this:

The output is:

So you can see that both of the variables point to the same memory location. When you decompile the code, you get:

So you can see that the type of b is int32&.

You can also use ref return to return something from a function:

This prints:

As a sidenote, dotnetfiddle gives this:

86. What is an interior pointer?

Interior pointer is a managed pointer which points to the inside of an object. See this:

This outputs:

You may ask: how does GC know that interior pointer needs to keep an object alive? GC uses brick table which partitions the heap into multiple blocks. It contains an offset to the first object inside such a block so then it can traverse the chunk of memory and find the object which should be held by the interior pointer. Since this algorithm is very expensive there are limitations what you can do. For instance you cannot have a “ref field” in an object.

87. What is a ref struct?

It is a structure which cannot be moved to the heap. It is always stored on the stack and because of that cannot be accessed by multiple threads. You declare it like this:

If you try to use Foo as a field or property of a class, box it or create an array of it – you will get a compilation error.

88. What is an unsafe struct?

If you put an array inside a structure, only the reference to the array is stored. If you want to store whole array inside a structure you need to create so called “fixed size buffer”. It is a fixed array of primitives which you can use in unsafe structures only:

89. What is a readonly struct?

It is a structure which cannot be modified after creation. It differs from normal structure with readonly fields that you cannot modify this:

90. What is an unsafe type?

This is easy, it is just a class in which you can use unsafe code. Just like an unsafe method.

91. What is a blittable type?

It is a type which has the same binary representation in managed an unmanaged code. Integer, pointers and floating point values are blittable. Oddly enough, bool is not blittable as it can be stored as 1, 2 or 4-byte value, char and DateTime are non-blittable as well. See more here.

92. How is unmanaged class compiled in C++/CLI?

You can create both managed and unmanaged classes and methods, see this:

When you decompile it, you can find class Foo:

You can also find method main:

And method Baz:

Class Bar and method Taz are unmanaged.