yck1509 / ConfuserEx

An open-source, free protector for .NET applications
http://yck1509.github.io/ConfuserEx/
Other
3.57k stars 1.64k forks source link

How can I investigate issues reported by PEVerify? #405

Open ivan-danilov opened 8 years ago

ivan-danilov commented 8 years ago

I ran ConfuserEx with rename protection on a few assemblies (one of them is large though). It completed without errors, but PEVerify outputs 436 errors on it like the following:

[IL]: Error: [d:\1\Confused\my.dll : _YGbNngBKpRxvvy7NkSKSrcvDmJG_::_17w1GiROq6y1aWRw9wWSUGOde1C_][mdToken=0x60003cd] Method does not exist.
Method does not exist.
Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : _cdMM5QrQwL2ksRGa1UJRmJUkVTd_::.ctor][mdToken=0x60006c8][offset 0x00000002] Unable to resolve token.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_tGtv2dtaIMIA6LoHXu7DwMxfvlS_][mdToken=0x6000732] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_tk0zK3VXciZeRsH2nVWBZ6jNVdE_][mdToken=0x6000733] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_tGtv2dtaIMIA6LoHXu7DwMxfvlS_][mdToken=0x6000732] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_tk0zK3VXciZeRsH2nVWBZ6jNVdE_][mdToken=0x6000733] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_PkJlSB6sykBdsQ8OXX3CBVEXudk_][mdToken=0x6000735] Method does not exist.
[IL]: Error: [d:\1\Confused\my.dll : ClassXyz::_AYy29oWv1vnvKJP5Q1lcxUcQZRd_][mdToken=0x6000757] Method does not exist.

Unfortunately I can't share the assembly in question, so my question is - how can I proceed myself to find the cause? I can find symbols.map and lookup these long identifiers, I set seed, so they are the same, but I basically don't know what to look for. If I open confused assembly with dnSpy and manually look for mentioned methods - they indeed are present.

yck1509 commented 8 years ago

Hi, Unfortunately, these error from peverify tends to be vague and hard to debug. You may try using the methods stated in the errors at runtime and see what exception is thrown.

ivan-danilov commented 8 years ago

After passing ildasm through obfuscated assembly, I found the following line:

  .method family hidebysig virtual instance class [mscorlib]System.Collections.Generic.IList`1<class _9bRhS29inzna1jXLTyEAM472OBK_> 
          _8GTfIborl5rHvJBvnXjFYkj72xE_(!'' A_1) cil managed
  {
    .override  method instance class [mscorlib]System.Collections.Generic.IList`1<class _9bRhS29inzna1jXLTyEAM472OBK_> class _WwWC9aeUcXa00dIcH6E2UpxfiTJ_<!''>::Install(!0)

Note that override states that it overrides Install(!0) method (unobfuscated name), while its name is _8GTfIborl5rHvJBvnXjFYkj72xE_ - and that is precisely obfuscated counterpart of Install judging by symbols.map file.

ivan-danilov commented 8 years ago

By the way, underscores removed in b9d74ba41f76c4a723d93da7dc69ffd7ff9ebbfd would be better made optional with project property or command line argument... It is very hard to analyze/troubleshoot decompiled IL when obfuscated symbol in question is just 2. A lot easier when it is _2_.

ivan-danilov commented 8 years ago

Could you please clarify for me, how chains of overrides are handled in rename protection? I'm looking at VTableAnalyzer.cs and it looks like it just considers declaring class and interface slots. I have the following situation:

interface Intf { void X(); }
class A : Intf { ... }

[Obfuscation(Exclude = true, ApplyToMembers = true)]
class B : Intf { ... }

In my case ConfuserEx correctly decided that both Intf.X and B.X must not be renamed. But when analysis of A.X happens - Intf.X has not been processed yet and A.X is not shielded from rename.

yck1509 commented 8 years ago

This is intended. If A.X is renamed at last, an .override directive would be inserted to explicitly implement Inf.X