Как использовать код операции .net cil jmp

Я пытаюсь заставить код операции jmp работать в Cil.

jmp  void ILTest.Program::MyFunc2(int32)

С ilasm все в порядке, но когда я запускаю программу, я всегда получаю исключение «среда выполнения общего языка обнаруживает недопустимую программу».

Я знаю, что это непроверяемый код, поэтому я попытался дать разрешения

SecurityPermission perm = new SecurityPermission(SecurityPermissionFlag.Execution | SecurityPermissionFlag.SkipVerification | SecurityPermissionFlag.UnmanagedCode);

но, похоже, это не имеет никакого эффекта.

У кого-нибудь есть работающая программа, использующая jmp?


person William Pearson    schedule 27.08.2012    source источник
comment
Не могли бы вы показать нам свой реальный код, который мы могли бы попробовать?   -  person svick    schedule 27.08.2012
comment
Я борюсь с той же проблемой. Вам повезло?   -  person AareP    schedule 26.10.2015


Ответы (2)


jmp может перейти только к методу с теми же аргументами, что и текущий метод. Убедитесь, что вы уже находитесь в методе, принимающем int32 в качестве параметра, и что вы ничего не помещали в стек: он должен быть пустым. Также убедитесь, что вы не находитесь в блоке try/catch/filter/finally.

Если вы не можете соответствовать этим критериям, используйте вместо этого call.

person Julien Lebosquain    schedule 27.08.2012
comment
метод jmped to имеет ту же подпись, что и вызывающий метод. - person William Pearson; 27.08.2012
comment
Что насчет стека? Также убедитесь, что вы не находитесь в блоке обработки исключений. - person Julien Lebosquain; 27.08.2012
comment
я просто экспериментирую с очень простым кодом. У меня был рабочий код с «вызовом», и я просто заменил его на «jmp». Я уверен, что проблема в том, что инструкция jmp не поддается проверке. Если у кого-нибудь есть рабочий пример, это было бы здорово. Мне нужно использовать jmp в моей реальной системе, потому что нет возможности раскрутить стек. - person William Pearson; 27.08.2012
comment
@WilliamPearson Что вы имеете в виду под «нет возможности раскрутить стек»? Не могли бы Вы уточнить? - person svick; 27.08.2012
comment
Спасибо, чувак, ты только что ответил на вопрос, который у меня был весь день, я ссылаюсь на твой ответ - person johnny 5; 22.11.2019

Следует иметь в виду, что все сборки и динамические методы имеют свои собственные наборы токенов метаданных, которые используются для ссылки на другие методы, поля и типы. Таким образом, при замене IL-кода существующей сборки вы можете использовать только те токены, которые уже использовались в этой сборке (в других классах и методах). Скорее всего, вы не сможете выделить новые токены после того, как сборка уже собрана. (по крайней мере, это моя догадка)

Также я думаю, что есть два способа "прыгать" с одной сборки на другую. Один использует DynamicMethod.Invoke, другой предварительно создает фиктивный метод и анализирует токен метода назначения из его кода IL. В моем проекте мне понадобились оба, так что удачи. :)

Кроме того, при замене IL-кода существующего метода вам необходимо иметь достаточно большое значение «максимального стека» и каким-то образом убедиться, что для вашего нового кода достаточно локальных переменных.

К сожалению, исключения времени выполнения .net действительно универсальны и никогда не сообщают вам, что пошло не так. Итак, будьте готовы к тому, что у вас будет множество небольших тестовых случаев для проверки ваших решений на различных методах.

Вот еще несколько полезных ссылок:

http://www.codeproject.com/Articles/14058/Parsing-the-IL-of-a-Method-Body

http://blogs.msdn.com/b/haibo_luo/archive/2006/11/07/turn-methodinfo-to-dynamicmethod.aspx

http://www.codeproject.com/script/Content/ViewAssociatedFile.aspx?rzp=%2Fkb%2Fdotnet%2Fdotnetinternals_injection%2Frbcoree.zip&zep=rbcoree%2Frbcoree.cpp&obid=26060&obtid=2&ovid=1

https://www.google.fi/search?num=100&es_sm=93&q=CORINFO_METHOD_INFO&oq=CORINFO_METHOD_INFO&gs_l=serp.3...0.0.0.4517435.0.0.0.0.0.0.0.0..0.0....0...1c..64.serp..0.0.0.cdFZu2hO9Yo

person AareP    schedule 14.11.2015
comment
Похоже, вы потратили много времени на динамические методы и захотели поделиться своим опытом, написать ответ, а затем начали искать вопрос, который может быть полезен. Это не обязательно плохая идея, но вы выбрали неправильный вопрос, ваш ответ на самом деле не очень хорошо относится к этому вопросу. Если это не то, что вы делали, то вы, вероятно, просто неправильно поняли вопрос, но ваш ответ все равно не соответствует ему. - person ; 14.11.2015
comment
Хех, много предположений в моем очень конкретном ответе на очень общий вопрос. Все еще не худшая из моих ошибок. :) - person AareP; 14.11.2015