我有一些自定义的IL我写的,它不会通过PEVerify。我得到的错误是
$ peverify foo.exe Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.17929 Copyright (c) Microsoft Corporation. All rights reserved. [IL]: Error: [Z:\virtualbox_shared\foo.exe : HelloWorld.Program::Main][offset 0x00000021] Stack height at all points must be determinable in a single forward scan of IL. 1 Error(s) Verifying foo.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
为什么我收到此错误?
答案 0 :(得分:6)
必须在IL的单个正向扫描中可确定
这是验证失败的关键部分。验证者不会尝试验证每个分支路径,这将需要解决暂停问题。它对POP不满意,它无法在单个正向扫描中看到该操作码由具有非空堆栈的后向分支到达,因此是有效的。
答案 1 :(得分: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