Can PEVerify tell me the severity of each error?

2019-08-31 06:13发布

问题:

I'm modifying an assembly using Mono.Cecil, and I want to check it for validity (whether the result will run at all). I'm trying to use PEVerify, but I'm having a problem.

It was designed for ensuring code is verifiable, so it just says ERROR whether the error means the IL is completely invalid and will not execute, or whether it's a verifiability issue that would be ignored in full trust. Here are some examples:

  1. Using pointers and the like.
  2. Not setting .locals init when the method has locals.
  3. Calling .ctor from a non-constructor method.

Issues that make the IL fail to run include:

  1. Member isn't accessible from the location it is used in.
  2. Member doesn't exist.

Is there a way to make it give me some indication of the severity of the issue? If not, is there another tool that can do this?

回答1:

@HansPassant already tried to explain it, but just so that we all understand each other, here's what's going on.

PEVerify checks your assembly for constructs that are not okay. That said, PEVerify is not the JIT compiler. The JIT compiler itself doesn't check the IL assembly - it just grabs the method it's going to call, changes it into an SSA form, optimizes it, compiles it and then calls the resulting binary assembly.

Now, the compiler will evolve over time. Optimizations are changed and added, and the role of the compiler is not necessarily to check for error (if it finds one as a by-product, it'll probably report it, but no guarantees). Remember, the JIT compiler is relentlessly optimized for just one thing, and that is to produce pretty good assembler byte code (because it's a JIT'ted language, the time it takes to compile something is really important). So, two different tools.

This basically results in the following:

  • The compiler will compile and execute what it was given.
  • PEVerify will tell you if the result of the method / assembly is defined.

If you ignore an error of PEVerify, this basically means that the result will be undefined behavior - which can be anything from a working executable to a hard crash. There is no such thing as a 'warning'.