Last month I decided to play a bit with C++. I needed some real project to practice writing on this language and implement the learned features and functionality. So I decided to totally rewrite my .NETDebuggingEnabler tool, built on .NET, which weren't good enough and didn't recognized modules in case of WOW64 processes.
.NET optimization overview
As you might know, .NET has a few ways to speed up execution of code. One of them is NGEN approach, which allows to pre-compile the assemblies and don't spent time in future for code jitting. But if the assembly isn't NGENed, then optimization is performed by JIT compiler in runtime. JIT compiler does a lot of tricks trying to speed up the execution. For instance, it inlines method calls, reduces number of redundant memory accesses, performs aggressive registry caching, doesn't call empty constructors etc. All this is well, but the problem become when we want to debug the foreign code.In order to debug foreign .NET assemblies we may use the Reflector Pro tool, which allows to recreate sources from assembly and generate symbol file (PDB) to bind sources to code. We can even use the WinDBG tool to debug directly the native code (an approach I prefer very often :-) ). In any case JIT optimization causes a lot of problems, because it confuses Visual Studio so VS cannot track the code execution and current line pointer randomly jumps. Also optimized output can confuse directly us if we use WinDBG tool, because it's hard to understand the native code, a lot of methods are inlined (in .NET 4.5 even instance method may be inlined). It would be much easier debug application if optimization is disabled. And runtime JIT optimization is something that is under our control.
Tool overview
The main aim of this tool is optimization disabling for particular modules. The tool doesn't do anything special, it just discovers the place where assembly is located and places special .ini file near the assembly. We may perform this even by ourselves (use this article for more info). The main problem here is that we should somehow locate where the assembly is actually placed. Easy enough? In case of regular application yes, but in case of ASP.NET it isn't so. The assemblies are copied deeply to the C:\Windows\Microsoft.NET\... folder and it's tricky a bit to find out the exact location. Usually, I use the Process Explorer tool for such purpose because it allows to see loaded modules pathes.The tool perform all this work automatically, you should just pick a process and choose assemblies for which optimization should be disabled.
Main tool features
- Full support for both x86 (WOW64) and x64 processes.
- Processes name filter (e.g. display only w3wp processes).
- Modules path filter (e.g. display only user assemblies for w3wp processes).
- Hints for w3wp processes (it displays application pool name, which is enough to choose the proper w3wp process).
- UI state saving across sessions (position, size, checkbox/textbox values).
Administrator privileges
Tool requires administrator privileges for execution. This is because tool process is unable to read memory (and therefore loaded modules list) of service processes if it doesn't have SeDebug privilege, which may be obtained by process only if it has already administrator privileges. All ASP.NET applications fall in this category, so they are unreachable for my tool. This tool is mostly targeted on ASP.NET applications, so without this functionality it's useless for me personally.
If you don't trust the tool and afraid that it may hurt your PC, you may refer to source code and check that everything is clear :)
Download link and sources
The download link: https://dl.dropboxusercontent.com/u/19876160/MyTools/NETDebuggingEnabler.exeAll the sources are located on GitHub. You may find them here: https://github.com/Zvirja/NETDebuggingEnabler
If you find any issues, please register them on GitHub.
Appendix
-------------------------------------------------
Tool internal details
- In order to get list of loaded modules I use two different approaches. The first approach is regular WINAPI usage. It works well for x64 processes, but doesn't work for WOW64. The output is exactly what I observed in my .NET tool. So I scan the entire target process memory (allocated regions) to identify all the memory mapped files. I get only files mapped as images, which returns me user .NET assemblies for WOW64 processes.
- I use wxWidgets to build UI part. I cannot say that this framework is bad, it allowed me to build everything I wanted, so am satisfied with it.
- In order to get ASP.NET hints I fetch the w3wp process command line parameters. Application pool name is passed as parameter to w3wp process, so it isn't a big overhead to extract it.
- I use registry to save UI parameters between sessions.
- I embed std library, so tool doesn't require Visual C++ Redistributable package for its work.
- I packed tool by UPX to reduce executable size (4.5MB -> 1.3MB).
- Process needs SeDebugPrivilege to be able to access services memory. This privilege may be assigned by foreign process or process may assign it by itself, if he has already administrator privileges. I decided to not play with privileges on demand so tool requires admin during startup.
- I used Process Hacker sources to understand how it works and how it extracts certain peaces of data (e.g. user assemblies for WOW64 processes).
No comments:
Post a Comment