Как можно получить имя начального адреса процесса, как это делается в Process Explorer?

Хорошо, я пишу приложение, предназначенное для перечисления потоков в заданном процессе, как это делает Process Explorer. Я хорошо понимаю, что это потенциально может сломаться между разными версиями Windows, потому что оно основано на «неофициальных» API, таких как NtQuerySystemInformation, и меня это вполне устраивает.

У меня уже есть код для получения базового адреса данного потока. Теперь я хотел бы превратить это во что-то вроде того, что делает проводник процессов, то есть «ntdll.dll!EtwDeliverDataBlock+0x453». На самом деле мне не нужно имя функции или смещение, только имя модуля.

Как я могу это сделать?


person Billy ONeal    schedule 11.12.2010    source источник


Ответы (3)


Если вам нужно только имя модуля, проще всего использовать EnumProcessModules чтобы получить список всех загруженных модулей, используйте GetModuleInformation на каждом из них. Одна из вещей, которую возвращает GetModuleInformation, — это базовый адрес, по которому загружается этот модуль. Технически целочисленное значение самого HMODULE совпадает с базовым адресом, но мне это кажется немного хрупким...

Тогда нужно просто найти модуль с базовым адресом чуть ниже текущего (или начального) адреса потока.

Да, и чтобы получить фактическое имя модуля, есть GetModuleBaseName.

person Dean Harding    schedule 11.12.2010
comment
Хм.. это может сработать. Есть ли способ сделать это так, чтобы мне не нужно было фактически открывать дескриптор целевого процесса? (например, нельзя сделать это с системным процессом) - person Billy ONeal; 13.12.2010
comment
@ Билли: я не уверен. Я считаю, что Process Explorer на самом деле использует драйвер режима ядра для некоторых своих функций, так что, может быть, это один из таких случаев? - person Dean Harding; 14.12.2010
comment
Работая над этим, вызывая NtQuerySystemInformation с классом SystemModuleInformation, я вернусь к вам с тем, что придумал. - person Billy ONeal; 15.12.2010

Вы можете использовать GetModuleHandleEx с флагом GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS. чтобы получить дескриптор модуля с заданным адресом. Затем вы можете использовать GetModuleBaseName, чтобы получить название модуля.

Редактировать: вы, вероятно, также захотите использовать флаг GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, чтобы не увеличивать количество ссылок на модуль.

person Paul    schedule 11.12.2010
comment
GetModuleHandleEx не работает для удаленных процессов. Из-за этого ваше предложение использовать флаг UNCHANGED_REFCOUNT также не имеет значения... - person wj32; 11.12.2010