也谈如何dump一个程序集中的所有类型和方法的IL源代码

最近在网上看一些关于.Net下程序集加密解密的资料,在“紫雨轩 .Net”的blog上看到几篇关于如何在内存中dump一个程序集中的所有类型和方法的IL源代码的介绍,地址如下:
http://www.cnblogs.com/rick/archive/2006/09/14/504525.html
http://www.cnblogs.com/rick/archive/2006/09/28/517603.html
作者的思路非常好,任何程序集在内存中肯定都有自己的IL源代码的,通过反射的方式肯定能得到,但作者在文章中对exe的dump说要通过dll注入来实现(在vs中不能直接reference一个exe),而且还没有提供注入的方法和代码。
其实不需要这么麻烦(我只知道win32下的dll注入,有点麻烦),既然.net framework提供了反射机制,那为什么一定要直接在项目中reference进一个程序集后才能对它dump呢?直接通过反射把程序集载入不是更方便?通过反射动态加载进一个exe的程序集是没问题的,我在原作者的代码上稍微改了下,并用一个exe程序集测试通过,代码如下:
  1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using System.Reflection;
  5using System.IO;
  6using System.Windows.Forms;
  7
  8namespace testcon
  9{
 10    class Dump
 11    {
 12        /// <summary>
 13        /// dump一个程序集
 14         /// </summary>
 15        /// <param name="assPath"></param>
 16        /// <param name="path"></param>

 17        public void DumpAssembly(string assPath, string path)
 18        {
 19            Assembly ass = Assembly.LoadFrom(assPath);// 通过反射载入程序集,可以是exe
 20            DumpAssembly(ass, path);
 21        }

 22
 23        //这个函数将一个Assembly全部dump到path中。
 24        public void DumpAssembly(Assembly ass, string path)
 25        {
 26            StreamWriter writer1 = new StreamWriter(path, false);
 27            Type[] typeArray1 = ass.GetTypes();
 28            for (int num1 = 0; num1 < typeArray1.Length; num1++)
 29            {
 30                this.DumpType(typeArray1[num1], writer1);
 31            }

 32            writer1.Flush();
 33            writer1.Close();
 34        }

 35
 36        //dump单个类型,由dumpassembly调用
 37        private void DumpType(Type tp, StreamWriter sw)
 38        {
 39            BindingFlags flags1 = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
 40            string text1 = tp.ToString();
 41            sw.Write("TYPE: " + text1 + "\r\n");
 42            if (tp.IsEnum)
 43            {
 44                sw.Write("IsEnum ");
 45            }

 46            if (tp.IsImport)
 47            {
 48                sw.Write("IsImport ");
 49            }

 50            if (tp.IsNested)
 51            {
 52                sw.Write("IsNested ");
 53            }

 54            if (tp.IsClass)
 55            {
 56                sw.Write("IsClass");
 57            }

 58            sw.Write("\r\n");
 59            //if ((text1 != "InFaceMaxtoCode") || !this.checkBox1.Checked)
 60            //{
 61                sw.Write("**********Begin MemberInfo**********\r\n");
 62                MemberInfo[] infoArray1 = tp.GetMembers(flags1);
 63                for (int num1 = 0; num1 < infoArray1.Length; num1++)
 64                {
 65                    MemberInfo info1 = infoArray1[num1];
 66                    sw.Write(info1.MemberType.ToString() + "\t" + infoArray1[num1].ToString() + "\r\n");
 67                    if ((info1.MemberType == MemberTypes.Method) || (info1.MemberType == MemberTypes.Constructor))
 68                    {
 69                        this.DumpMethod((MethodBase)info1, sw);
 70                    }

 71                }

 72                sw.Write("**********  End MemberInfo**********\r\n");
 73                sw.Write("\r\n\r\n");
 74            //}
 75        }

 76
 77
 78
 79        //dump单个方法,由dumptype调用
 80        private void DumpMethod(MethodBase mb, StreamWriter sw)
 81        {
 82            MethodBody body1 = mb.GetMethodBody();
 83            if (body1 != null)
 84            {
 85                byte[] buffer1 = body1.GetILAsByteArray();
 86                try
 87                {
 88                    sw.Write("\tMaxStackSize: " + body1.MaxStackSize.ToString());
 89                    sw.Write("\tCodeSize: " + buffer1.Length.ToString());
 90                    sw.Write("\r\n");
 91                }

 92                catch (Exception exception1)
 93                {
 94                    MessageBox.Show("1:" + mb.ToString() + "\r\n" + exception1.ToString());
 95                }

 96                foreach (LocalVariableInfo info1 in body1.LocalVariables)
 97                {
 98                    sw.Write("LocalVar: " + info1.ToString());
 99                    sw.Write("\r\n");
100                }

101                sw.Write("\r\n\r\n");
102                StringBuilder builder1 = new StringBuilder();
103                foreach (byte num1 in buffer1)
104                {
105                    builder1.Append(num1.ToString("X2"));
106                }

107                sw.Write(builder1.ToString());
108                sw.Write("\r\n\r\n");
109                foreach (ExceptionHandlingClause clause1 in body1.ExceptionHandlingClauses)
110                {
111                    sw.Write(clause1.ToString());
112                    sw.Write("\r\n");
113                }

114                sw.Write("\r\n");
115            }

116
117        }

118    }

119}

120
posted on 2006-12-28 17:24  sss  阅读(1159)  评论(2)    收藏  举报