6

私が書いたカスタムILが少しありますが、PEVerifyに合格しません。私が得るエラーは

$foo.exeをpeverify

Microsoft(R).NETFrameworkPEベリファイア。バージョン4.0.30319.17929
Copyright(c)MicrosoftCorporation。全著作権所有。

[IL]:エラー:[Z:\ virtualbox_shared \ foo.exe:HelloWorld.Program :: Main] [offset 0x00000021] ILの1回の順方向スキャンで、すべてのポイントのスタックの高さを判別できる必要があります。
1foo.exeの確認中にエラーが発生しました

ただし、プログラムは例外なく正常に実行されます。関連するメソッドのILは次のとおりです。

.method private static hidebysig
  default void Main (string[] args)  cil managed
{
// Method begins at RVA 0x2050
.entrypoint
// Code size 54 (0x36)
.maxstack 2

//custom IL
ldc.i4 1
ldc.i4 1
ceq
switch(first, second)

first:
ldc.i4 1
br.s temp
popit: pop
br.s second

temp: ldc.i4 1
brfalse temp2
temp2: br.s popit

second:
ldc.i4 2
pop

ret

} // end of method Program::Main

完全なソースコードはpastebinにあります

なぜこのエラーが発生するのですか?

4

2 に答える 2

6

ILの1回のフォワードスキャンで判別可能である必要があります

これが検証の失敗の重要な部分です。ベリファイアは、すべての分岐パスを検証しようとはしません。そのため、停止性問題を解く必要があります。POPについては不満です。単一の順方向スキャンでは、このオペコードが空でないスタックを持つ逆方向ブランチによって到達され、したがって有効であることを確認できません。

于 2012-11-07T17:43:46.730 に答える
0

これが答えである理由を完全には理解していませんが、これによりPEVerifyが発生しました。

.method private static hidebysig
  default void Main (string[] args)  cil managed
{
// Method begins at RVA 0x2050
.entrypoint
// Code size 54 (0x36)
.maxstack 2

//custom IL
ldc.i4 1
ldc.i4 1
ceq
switch(first, second)

first:
ldc.i4 1
br.s temp
ldc.i4 1 //not reached, but required!
popit: pop
br.s second

temp: ldc.i4 1
brfalse temp2
temp2: br.s popit

second:
ldc.i4 2
pop

ret

} // end of method Program::Main
于 2012-11-07T17:27:23.647 に答える