您的位置:首页 > 编程语言 > C#

在C#的安全环境下使用指针操作

2005-08-03 23:31 411 查看
自动换行  【由 孤帆代码着色器1.0.1  着色】  孤帆Blog
[code]1       C#中要操作指针正规的方法是把代码块标为"unsafe"。虽然不安全代码
2    可以触及些许C代码的感觉,但不安全代码还是存在很多的限制,并且代码的
3    运行也受到限制.
4       那么有没有其他替代方法呢?没有.当然只依靠C#按常规的方法是很难
5    达到我们的远大理想的!既然如此我们能否用其他语言来辅助实现呢?可
6    以!废话!不然我写这些垃圾做什么?现在请听我慢慢道来.各位看官请喝
7    茶!
8
9    一、.Net里的内部指针截获
10        在托管环境下用户涉及到的指针操作都是由CLR来完成的(不安全代码除外
11    ).但这样并不表示我们在安全的.Net下没有使用指针,因为所有涉及到字段的
12    移动、更新必须通过指针操作才能实现的.
13        那么CLR又怎样知道我们什么时候要更新字段数据、什么时候只需要获取字
14    段数据呢?(呵呵!喝茶先)
15       1. C#程序中的"指针"表示方式
16        out、ref关键字就是我们的寻找的答案了。慢!先让我简单解释一下这
17    些家伙是什么东西先(郁闷!又要背书了!背的不好各位大哥请自行找书了).
18
19
20 ref :引用实参(实参必须已经初始化)
21 out :跟ref差别是不检查实参是否已经初始化
22 OK!现在各位大概已经知道我们的目标在那里了吧!没错!我们需要的就是ref
23 和out我们的实参.为什么?别理她什么东东,暂且把她们当作我们的白雪公主(指针
24 )来看待.
25
26 2.怎样从out或ref中得到实参指针呢?
27 如前面所说我们的指针操作都是如CLR来帮助完成的,所以当用out或ref我们
28 的实参时实际上CLR就是封送托管中字段的指针.
29 所以我们只要把CLR传过来的指针截获就ok了!怎样截获呢?用其他允许指针
30 操作的语言做个dll来实现.
31 以下我给出用asm写的dll源代码:
32 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
33 ;getVarPtr.asm
34 .386
35 .Model Flat,StdCall
36 Option CaseMap:None
37
38 .code
39 DllMain proc hInstance:DWORD,reason:DWORD,unused:DWORD
40 mov eax,1
41 ret
42 DllMain endp
43
44 ;***************************************************
45 ;功能 :获取CLR传过来的指针函数.
46 ;返回值:CLR传过来的指针
47 ;用C/C++描述如下
48 ;int getVarPtr(int var)
49 ;{
50 ; return var;
51 ;}
52 ;***************************************************
53 getVarPtr proc
54 mov eax,[esp+4]
55 ret 4
56 getVarPtr endp
57
58 end DllMain
59 ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
60
61 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
62 导出函数文件 getVarPtr.def
63 EXPORTS
64 getVarPtr
65 ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
66
67
68 二、动刀杀牛!
69 说了那么多废话还是给个代码让大家看下,辛苦各位了!
70
71 //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
72 class CPtrINSafeEnv
73 {
74 //我们的获取CRT传过来的指针函数
75 [DllImport("getVarPtr.dll")]
76 public static extern int getVarPtr(ref int var) ;
77
78 //内存拷贝的好东西
79 [DllImport("kernel32", EntryPoint="RtlMoveMemory")]
80 public static extern void CopylpInt2Int(ref int dest,int src,int nLen);
81 [STAThread]
82 static void Main(string[] args)
83 {
84 int dwTest=123456;
85 int pdwTest=0;
86 int dwTmp=0;
87 Console.WriteLine("dwTest={0},pdwTest={1},dwTmp={2}/n",
88 dwTest.ToString() ,pdwTest.ToString(),dwTmp.ToString());
89
90 //动态获取dwTest在托管环境下的地址
91 pdwTest=getVarPtr(ref dwTest);
92 Console.WriteLine ("dwTest在托管环境下的实际地址是:"
93 + pdwTest.ToString());
94
95 //通过dwTest的指针把dwTest的数据复制到dwTmp
96 CopylpInt2Int(ref dwTmp,pdwTest,4);
97 Console.WriteLine("/n通过dwTest的指针把dwTest的数据复制到dwTmp后/ndwTmp="
98 + dwTmp.ToString());
99
100 Console.Read();
101 }
102 }
103 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
104
105 简单解释
106
107 上面的代码执行过程如下:
108 1.获取dwTest的托管指针保存到pdwTest中
109 2.通过保存在pdwTest中dwTest的指针,把dwTest的数据拷贝到dwTmp中去.
110
111 提示:运行时请把dll拷贝到程序运行目录
112
113 下载地址:http://upload.programfan.com/upfile/200508051233342.rar
115 三、这种方法是否安全
116
117 1.以上的方法是否安全?
118 不安全!因为"指针操作都是不安全的!!"^_^.所以安全是相对的
119 .谁敢确保CLR处理我们的指针就安全呢?Java不也内存泄漏吗?我们都
120 是见效率忘安全中人!呵呵!!
121
122 2.如果GC压缩内存我们的代码是否会出错呢?
123 不会.只要我们是动态的获取字段指针就不会出现错误!
124
125 四、有什么用呢?
126 呵呵!当然是为了不安分的自己,满足一些无法用常规实现的不可告人的
127 目的(最直接的就是速度了,还有就是....自己想).
128
[/code]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: