views:

221

answers:

3

Hello. I need to write a relatively small program to parse .net executables and generate the list of calls to external methods. For example if System.Console.WriteLine is called inside the file the tool should print that System.Console.WriteLine is called somewhere. I cannot (limited brain and time) and need not (all I need is a list of calls) implement a real disassembly. I want a grep friendly perl friendly relatively short solution that writes the names of the functions called and the offset where the call happened.

Things I already tried:

  1. Downloading specs from MSDN. Now I know that static call is translated to 0x28 in bytecode. :) It is followed by method descriptor but understanding what method descriptor means will probably require reading the entire spec.

  2. Opening simple exe in Reflector. Reflector precisely reproduced the code of my original application yet I can not see the bytecode for the calls.

Is it possible to implement the desired limited functionality with limited time and knowledge?

If so what do I know to implement it? Is there any "CIL assembly for dummies" guide?

+4  A: 

The Cecil project is a library to do exactly what you want.

VirtualBlackFox
+2  A: 

If you want something grep/perl-friendly, use ildasm (in its command line mode i.e. with /out or /text) to disassemble the byte code to textual IL. You can then use grep, perl or the language of your choice to locate call instructions. (grep probably wouldn't suffice to identify which methods the call instructions were located in, but perl should be able to.)

itowlson
Thanks, ildasm generated CIL helps locate and identify all interesting calls.Is there any way to easily detect try-catch blocks?
Muxecoid
Try blocks begin with .try { and end with }. Catch blocks begin with catch [mscorlib]System.Exception (or whatever the exception is), then a {, and end with }. (Best way to see this is to write a test assembly in C# and ildasm it. See also Jason's comment on handler/label form.) So locating these blocks shouldn't be too hard. However, it may be a pain using a line-oriented processor like perl to identify whether a given line is part of a try-catch block or not: you may instead want to investigate the Cecil and CCI projects mentioned by VirtualBlackFox and Jason.
itowlson
+1  A: 

The Common Compiler Infrastructure might help you too: http://ccimetadata.codeplex.com/.

I would second itowlson's suggestion to just disassemble the assembly into an .il file and parse it using grep if that is what you are looking for. Since ILDasm will show full namespaces for all types you should beable to figure it out rather quickly if it is your type or a referenced type.

Jason Haley
Forgot to mention the commandline for you. Something like the following would give you a text file you could then grep:ildasm <yourassemblyname> /out:<someilfilenametocreate>.il
Jason Haley
I believe with the ildasm shipped with vs2008, if you don't use the /raweh on the command line, your try/catch/finally will be in the code (expanded) as .try/catch/finally.If you use /raweh then the exeception handling block in formation is at the end of the method (like it is stored in the byte code). You'll have to decipher these into where they go in the code using the labels.
Jason Haley