0

My understanding is that .NET (C#) code compiles to Common Intermediate Language (CIL) code, which then (usually) gets Just-In-Time compiled to native machine code at run-time on the deployment machine in conjunction with the common language runtime.

My question is, how does the actual work that gets done on the deployment machine at runtime relate with standard native WinAPI calls, assuming we're talking about a Win NT deployment machine? If I were to open a .NET file in OllyDbg for example, am I going to still see system calls to ntdll and or Kernel32 showing up, coming from the JITC'd code? .NET is also occasionally said to be "running in a virtual machine" similar to Java Bytecode. But still, at the end of the day, must the program still leave a signature of system calls in memory, even though the binary itself may not be able to be viewed properly by IDA?

I've been doing research into this and for example, I found this article on CryptGenRandom which is used by .NET's RNGCryptoServiceProvider . However, I've never heard of anyone using a native debugger to try to view these calls from JIT'd/interpreted/VM code.

6
  • Using a 'normal' debugger in .NET code is possible, but tedious: You would have to debug the highly optimized virtual environment executing (interpreting) the given CIL code. It is very(!) complex
    – Nordwald
    Mar 15, 2017 at 7:53
  • Maybe I'll just have to take a look, but are there any recognizable functions that could be traced back to actual behavior patterns in the program or is it basically extremely cluttered with random calls from the VM such that recognizing any behavioral patterns is very obfuscated?
    – the_endian
    Mar 15, 2017 at 8:21
  • Of course. Think about gargabe collection, JIT compiling, memory management and other functionalities of the vm. With smart heuristics, it could be possible, but still boils down to a tremendous amount of work
    – Nordwald
    Mar 15, 2017 at 9:15
  • What's the real question here? "How is .NET related to Windows system calls?" is way too broad and the answer is "it (.NET) sometimes makes them (system calls)." Does that help you? The answer to "But still, at the end of the day, must the program still leave a signature of system calls in memory, even though the binary itself may not be able to be viewed properly by IDA?" is "yes, obviously (except for the leave part)." Does that help you?
    – conio
    Mar 18, 2017 at 21:24
  • If you really "ever heard of anyone using a native debugger to try to view these calls from JIT'd/interpreted/VM code" it just means that you didn't really look. The .NET Framework even comes with an extension for WinDbg to help debug managed code. Googling "windbg .net" finds stuff like Intro to WinDBG for .NET Developers and Debugging .NET with WinDbg.
    – conio
    Mar 18, 2017 at 21:24

1 Answer 1

1

You can debug .NET code with an assembly debugger of your choice, it's fun, and sometimes, the only way to spot rare and nasty issues. However you'll end up on having a lot of noise since you'll debug the virtual machine of the .NET runtime, losing what the original .NET code was intended to do.

To debug .NET code and assembly at the very same time you can use Visual Studio (provided you disable Just My Code and enable Allow .NET source stepping (or similar)).

Alternatively, you can use WinDBG with sos (my personal choice). This way you can see the native calls of your code, and you can also inspect the .NET code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.