0

Given a .NET assembly (DLL or EXE), how can I make sure it does (or does not) use unsafe code, with a command line tool?

riQQ
  • 9,878
  • 7
  • 49
  • 66
Evgeniy Berezovsky
  • 18,571
  • 13
  • 82
  • 156
  • Similar question, although it's about detecting it programatically and I'm unsure if that's exactly what you want: https://stackoverflow.com/questions/40513064/how-can-i-detect-that-a-net-assembly-i-am-loading-contains-unsafe-code – Prime Jun 08 '22 at 05:30
  • @AlphaDelta Thanks, I've clarified my question. – Evgeniy Berezovsky Jun 08 '22 at 05:40
  • @EvgeniyBerezovsky the answer is still the same **reflect on the methods in the assembly and get their LocalVariableInfos. If any have IsPinned properties = true, then the method is unsafe.** So write a Console app that does that and accepts a single or multiple Assemblies. – Jeremy Thompson Jun 08 '22 at 05:42
  • You could have incorporated this into your [prior question (asked **45** minutes earlier) about `pinvoke`](https://stackoverflow.com/questions/72540153/how-can-i-check-if-a-dll-uses-pinvoke-dllimport?noredirect=1#comment128142219_72540153) given that you can configure certain pinvoke calls to be `unsafe` say for those occasions where you wish to use an unsafe pointer. I hope that you are not just _farming for reputation_ with your single sentence questions? –  Jun 08 '22 at 09:25
  • With your recent questions, where is this heading? If your intent is to run 3rd party, potentially toxic code safely, rather than trying to _detect_ these technologies why not simply **block it** with _Code Access Security, Partially-trusted Code and child AppDomains_ creating a secure plug-in system in the process? https://learn.microsoft.com/en-us/archive/msdn-magazine/2005/november/how-to-safely-host-untrusted-add-ins-with-the-net-framework-2-0 and https://learn.microsoft.com/en-us/dotnet/api/system.security.codeaccesspermission?view=netframework-4.8; –  Jun 08 '22 at 09:47
  • ... and most likely more of interest to you _["...**Metadata is also crucial for .NET to interoperate with existing Win32® APIs and COM servers**. When managed code calls an unmanaged API such as CreateProcess or a COM interface, it uses the Platform Invoke (PInvoke) mechanism. The .NET common language runtime **needs to undertake special preparation for PInvoke calls...**"](https://learn.microsoft.com/en-us/archive/msdn-magazine/2000/october/avoiding-dll-hell-introducing-application-metadata-in-the-microsoft-net-framework)_ –  Jun 08 '22 at 09:48
  • @MickyD We had the dreaded ExecutionEngine exception (internal .Net error) in production, and as managed, safe code, that does not involve PInvoke calls and COM interop should not be involved in the problem, I want to figure out which dlls are safe, to reduce the number of potential sources of the problem I need to look into. As to the questions, "unsafe" and "pinvoke" are different things, although they may share similarities. I don't however consider myself an .Net export, so I may be wrong. – Evgeniy Berezovsky Jun 08 '22 at 10:16
  • _"unsafe and pinvoke are different things"_ - certainly but that's not what I said I said _"you can configure certain pinvoke calls to be unsafe"_ though what I probably should have said some required unsafe parameters.. e.g. way back I was upset that .NET 3.5 WCF did not support _network_ Named Pipes so I rolled my own C# wrapper around the WIN32 API "network" Named Pipes, using pinvoke to instigate async I/O operations via IOCP. When it came to specifying where the data should be written/read I again used pinvoke but this time indicating `unsafe` pointers for buffers on the C# side. –  Jun 08 '22 at 11:27

2 Answers2

1

I googled this code to help you get started:

public static IList<LocalVariableInfo> GetLocalVars(string asmPath, string typeName, string methodName) 
{
  Assembly asm = Assembly.LoadFrom(asmPath); 
  Type asmType = asm.GetType(typeName); 
  MethodInfo mi = asmType.GetMethod(methodName); 
  MethodBody mb = mi.getMethodBody(); 

  IList<LocalVariableInfo> vars = mb.LocalVariab1es; 
  // Display information about each local variable. 
  foreach (LocalVariableInfo Ivi in vars) 
  {
    Console.WriteLine("IsPinned: " + Ivi.IsPinned); 
    Console.WriteLine("Locallndex : " + Ivi.Loca1Index); 
    Console.WriteLine("LocalType.Modu1e: " + Ivi.LocalType.Module); 
  }
  return vars;
}
Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
1

Use PEVerify.

Example output for an unsafe assembly:

> peverify /quiet myapp.exe
myapp.exe FAIL (2 error(s))

Example output for a safe assembly:

> peverify /quiet myapp.exe
myapp.exe PASS

This will not only detect code marked "unsafe", but also calls to native libraries.

N.B. peverify should come installed with Visual Studio, and is easiest to call when using the Visual Studio Developer Command Prompt.

riQQ
  • 9,878
  • 7
  • 49
  • 66
Evgeniy Berezovsky
  • 18,571
  • 13
  • 82
  • 156