Я отлаживал очень сложную проблему.
По сути, у меня есть запутанная сборка, которая вылетает по-разному. Необфусцированная сборка не имеет проблем, хотя нет никакой гарантии, что обфускатор здесь не виноват. (это то, что я мог бы стремиться исправить)
Во всяком случае, запутанная сборка также отлично работает на .Net 4.0. Он работает нормально, если я отключу оптимизацию JIT в .Net 4.5.
Что я пробовал:
Я попытался отладить его против IL. Нарушение прав доступа происходит из-за операции IL, которая просто загружает что-то в стек. Опять же, полностью управляемый код.
На всякий случай это связано с String.Empty я прошел IL и заменил все вызовы string::empty на ldstr ""
.. Теперь вместо AccessViolation я получаю FatalEngineException
Однако запуск его через деобфускатор со всеми отключенными параметрами заставляет его работать. По сути, все, что делает деобфускатор, когда ничего не включено, — это просто перестраивает IL и вставляет несколько NOP.
Кроме того, исполняемый файл проходит PEVerify, так что это не проблема.
Плохой исполняемый файл: Test.exe
Хороший исполняемый файл: Test-cleaned.exe
Оскорбительная трассировка стека:
Test.exe!PreEmptive.SoS.Client.Cache.CacheService.ServiceCache() Line 22032 + 0x137 bytes Unknown Test.exe!Test.TestConsole.Main(string[] args) Line 14 + 0x6 bytes Unknown
Вы можете использовать ildasm для сравнения двух исполняемых файлов. Однако, поскольку он переупорядочен, на мой вкус он показался мне слишком сложным. Я сделал небольшой инструмент, чтобы просто сбросить IL метода и иметь методы в отсортированном порядке для простота сравнения.
Плохой дамп IL: testcount.il
Хороший дамп IL: testcountcleaned.il
В любом случае, если у кого-нибудь есть какие-либо идеи о том, как проанализировать это и выяснить, какие именно части IL вызывают это, я был бы признателен.