Search code examples
c#.netdllcilunsafe

How can I detect that a .NET assembly I am loading contains unsafe code?


I'm writing a plug-in system that requires me to load .net DLLs into an environment. I need to know whether or not they contain any pointer usage or any other usage of the "unsafe" keyword. I have a good reflection browswer running so that I can look up all the types in the assembly, all the methods, all the external references and even all the CIL instructions in the DLL. To my knowledge however, the unsafe keyword is not kept around after it's been used to determine whether or not the DLL may be compiled.

Is there a place in the meta data where the unsafe tag persists? Are there specific CIL instructions that are unsafe? Is there another way to determine that a random DLL has unsafe code?

Of course unsafe code is not the only security concern, but it's the one I'm trying to deal with right now.


Solution

  • I would use this heuristic to detect unsafe code: check for fixed blocks where objects are pinned to take their address.

    To do this, reflect on the methods in the assembly and get their LocalVariableInfos. If any of their IsPinned properties is true, then the method is unsafe.

    The only unsafe operation that will be missed by doing this is stackalloc because it does not require pinning. You can catch that by checking the method body for the presence of the Localloc opcode that is used for allocating space on the stack.

    Do both of these checks and the only unsafe methods you should miss are ones that manipulate value types on the stack via pointers into the local variable. Unfortunately taking the address of local variables is a normal compiler operation used for many normal tasks, and you cannot filter that out.

    Note that compilers other than C# are free to use these as part of normal compilation of safe methods, however, for C# this heuristic should work perfectly.