我的班级中的方法有以下属性SecurityPermission(SecurityAction.Assert)
。我编译它(调试版本)并通过查看原始堆并查看包含PermissionSet blob的blob堆来查看ildasm.exe中的输出。我期望(根据ECMA-335):
2e 01 80 84 53 79 73 74 65 6d 2e 53 65 63 75 72 >. System.Secur<
69 74 79 2e 50 65 72 6d 69 73 73 69 6f 6e 73 2e >ity.Permissions.<
53 65 63 75 72 69 74 79 50 65 72 6d 69 73 73 69 >SecurityPermissi<
6f 6e 41 74 74 72 69 62 75 74 65 2c 20 6d 73 63 >onAttribute, msc<
6f 72 6c 69 62 2c 20 56 65 72 73 69 6f 6e 3d 32 >orlib, Version=2<
2e 30 2e 30 2e 30 2c 20 43 75 6c 74 75 72 65 3d >.0.0.0, Culture=<
6e 65 75 74 72 61 6c 2c 20 50 75 62 6c 69 63 4b >neutral, PublicK<
65 79 54 6f 6b 65 6e 3d 62 37 37 61 35 63 35 36 >eyToken=b77a5c56<
31 39 33 34 65 30 38 39 00 00
但我看到的是:
2e 01 80 84 53 79 73 74 65 6d 2e 53 65 63 75 72 >. System.Secur<
69 74 79 2e 50 65 72 6d 69 73 73 69 6f 6e 73 2e >ity.Permissions.<
53 65 63 75 72 69 74 79 50 65 72 6d 69 73 73 69 >SecurityPermissi<
6f 6e 41 74 74 72 69 62 75 74 65 2c 20 6d 73 63 >onAttribute, msc<
6f 72 6c 69 62 2c 20 56 65 72 73 69 6f 6e 3d 32 >orlib, Version=2<
2e 30 2e 30 2e 30 2c 20 43 75 6c 74 75 72 65 3d >.0.0.0, Culture=<
6e 65 75 74 72 61 6c 2c 20 50 75 62 6c 69 63 4b >neutral, PublicK<
65 79 54 6f 6b 65 6e 3d 62 37 37 61 35 63 35 36 >eyToken=b77a5c56<
31 39 33 34 65 30 38 39 01 00
请特别注意我预期01 00
末尾的00 00
。规范说,计数后的字符串应该是命名参数的数量。由于我没有传递任何命名参数,我预计该数字为16位0。
这是使用Visual Studio 2013针对.NET 2.0编译的。
更复杂的是,如果我添加一个命名参数,我得到这个:
2e 01 80 84 53 79 73 74 65 6d 2e 53 65 63 75 72 >. System.Secur<
69 74 79 2e 50 65 72 6d 69 73 73 69 6f 6e 73 2e >ity.Permissions.<
53 65 63 75 72 69 74 79 50 65 72 6d 69 73 73 69 >SecurityPermissi<
6f 6e 41 74 74 72 69 62 75 74 65 2c 20 6d 73 63 >onAttribute, msc<
6f 72 6c 69 62 2c 20 56 65 72 73 69 6f 6e 3d 32 >orlib, Version=2<
2e 30 2e 30 2e 30 2c 20 43 75 6c 74 75 72 65 3d >.0.0.0, Culture=<
6e 65 75 74 72 61 6c 2c 20 50 75 62 6c 69 63 4b >neutral, PublicK<
65 79 54 6f 6b 65 6e 3d 62 37 37 61 35 63 35 36 >eyToken=b77a5c56<
31 39 33 34 65 30 38 39 12 01 54 02 0d 55 6e 6d >1934e089 T Unm<
61 6e 61 67 65 64 43 6f 64 65 01 >anagedCode <
再一次,查看属性的计数字符串的结尾,您可以看到12 01
后跟命名参数列表(一个项目的列表)。我希望这是01 00
,一个16位的小端1,用于命名参数的数量。
基于此,我假设计数字符串后面的第二个字节是命名参数计数,但我仍然不明白第一个字节是什么(第一个例子中是0x01,下一个是0x12)。
如果我添加第二个命名属性,则第一个字节更改为26,如果我添加第三个命名属性,则更改为33.我没有看到数字的明显模式,而不是它们正在增加的事实
我问的是这个问题,因为我正在尝试手工构建一个PermissionSet blob(我正在编写一个CLR探查器),我需要知道该字节中要放什么。
答案 0 :(得分:1)
我认为你的沮丧是正确的,我记得我以前对命名参数的经验 - NumNamed
是作为压缩的int实现的,而不是规范中陈述的int16,并且与给出的示例不同VI.B.3。我不知道在后续的.NET 3.0+实现中是否已经改变了。
对于您正在寻找的 PermissionSet ,
... *一组属性,编码为自定义的命名参数 属性将是(如§II.23.3,从NumNamed开始)。
... §II.23.3 ...
接下来是对可选“命名”字段和属性的描述。 这从NumNamed开始 - 一个unsigned int16给出的数字 “命名”属性或后面的字段。 ... 在这种情况下 NumNamed非零,其后是NumNamed重复 NamedArgs。
12 01
是小端整数“给出后面的属性数”。一个命名属性,总长度为18(十进制,包括在内)。
这个总长度是你正在寻找的模式,但要注意,因为我认为这个长度是可选的,有时编译器设法在前面的int16中打包属性的数量,丢弃长度。您将不得不尝试使用不同数量的属性来确保正确解析所有情况。
NamesArgs:
... SerString - PackedLen字节数,后跟UTF8 字符
PROPERTY是单字节0x54。 FieldOrPropName是其名称 字段或属性,存储为SerString(上面定义)