Я не уверен, ищете ли вы (1) виртуальный адрес сопоставленного файла сборки или (2) виртуальный адрес, на котором код JITed помещается после загрузки сборки.
Далее я рассмотрю простой случай, когда хост-процесс загружает несколько сборок.Код можно найти здесь .Давайте сосредоточимся на том, что происходит, когда загружается x64_Assembly.dll .
Если то, что мы ищем, определено выше (1) (виртуальный адрес сопоставленного файла в процессе ')адресное пространство), то это означает выделенную строку ниже, показанную в выходных данных VMMap.Это где ОС загружает файл, содержащий сборку.Я не знаю, как вы могли бы получить это программно из своего собственного приложения.
![enter image description here](https://i.stack.imgur.com/6GJLr.png)
For (2), это виртуальный адрес, гдеJIT-код сборки найден, вы можете увидеть соответствующий адрес, если войдете в код с помощью отладчика:
![enter image description here](https://i.stack.imgur.com/JLna4.png)
As этот поток указывает, что сборка JITed помещается в кучу, которую вы можете легко проверить, снова используя VMMap.В моем случае адрес, показанный в отладчике, можно увидеть в блоке кучи с VMMap:
![enter image description here](https://i.stack.imgur.com/Sqcxm.png)
Так на какой адрес вы нацеливаетесь?
Позднее обновление : Вы можете использовать CLR MD для получения очень интересных данных.Взгляните на простой код ниже (взят из «Написание высокопроизводительного кода .NET» Бена Уотсона), который получает (1) и , возможно (2).Вы можете видеть, что адрес образа загруженной сборки в VMMap соответствует значению module.ImageBase
, поэтому вы обязательно получите (1).Однако для (2) значение module.Address
НЕ совпадает с переменной m_assembly
, замеченной в отладчике в моем исходном ответе, поэтому один из них показывает что-то еще.Однако, если вы подумаете об этом, не весь код JITed одновременно - вместо этого CLR будет JIT компилировать методы так, как (и если) они вызываются.Поэтому я считаю, что виртуальные адреса, содержащиеся в 2 переменных, указывают на некоторую общую структуру, представляющую сборку.
![enter image description here](https://i.stack.imgur.com/tg55M.png)
Поскольку вы упомянули, у вас есть доступ к проверкесодержимое памяти, вы можете довольно быстро выяснить, какая из двух переменных представляет интерес для (2).
Как вы могли бы сделать это на практике?Я имею в виду создание проекта CLR MD, который просто выводит информацию, которую вы ищете ((1) и (2), в простой файл)), а затем запускает этот EXE-файл вашим основным кодом, чтобы он анализировал ваш процесс исборка он загружает и записывает данные.Когда процесс CLR MD завершается, ваш реальный код может получить информацию, записанную в файле, и работать с теми виртуальными адресами, которые он получил.В моем примере выше PID был просто жестко задан (я использовал Process Explorer, чтобы увидеть назначенный PID), но вы, вероятно, могли бы передать его в качестве аргумента в свой проект CLR MD.
Вы можете использовать ManageОпция NuGet Packages for Solution в Visual Studio для установки CLR MD и ее настройки для вашего конкретного проекта, а затем просто добавьте using Microsoft.Diagnostics.Runtime
.
2 вещей, которые необходимо учитывать:
- "битность" используемого вами кода CLR MD должна соответствовать анализируемому процессу (например, не создавать один для x86, а другой для x64; полные сведения о сборкахзагрузка по кросс-битности в статье, на которую я ранее ссылался )
- , вам придется использовать
AttachFlag.Passive
в методе AttachToProcess
, иначе ваш исходный код будет приостановлен на неопределенный срок,Я также проверил эту опцию после того, как сделал снимок экрана выше и успешно получил значения module.ImageBase
и module.Address
, плюс исходный код продолжал работать просто отлично.