也谈如何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程序集测试通过,代码如下:
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程序集测试通过,代码如下:
1
using System;
2
using System.Collections.Generic;
3
using System.Text;
4
using System.Reflection;
5
using System.IO;
6
using System.Windows.Forms;
7
8
namespace 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
using System;2
using System.Collections.Generic;3
using System.Text;4
using System.Reflection;5
using System.IO;6
using System.Windows.Forms;7

8
namespace testcon9
{10
class Dump11
{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);// 通过反射载入程序集,可以是exe20
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
try87
{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



浙公网安备 33010602011771号