Ситуация: Kernel, есть какой-либо адресс -- необходимо узнать какой модуль создал блок памяти, содержащий этот адресс.
Что подразумевается под созданием блока паямяти? Если нужно узнать, какой модуль загружен по тому или иному адресу, то ZwQuerySystemInformation с классом SystemModuleInformation
Видимо, необходимо узнать, кто выделил эту память вызовом ExAllocatePool или че-нить такое. ИМХО никак...
MoonShiner "Видимо, необходимо узнать, кто выделил эту память вызовом ExAllocatePool или че-нить такое. ИМХО никак..." Вот именно! Неужели нет никакого аттрибутика, который бы хранился для каждого выделенного блока?? Маньяки КЕРНЕЛА! Взываю к вашим знаниям!
А ты подебажь ExAllocatePoolWithTag и подумай... Навскидку - никак, я вроде когда-то в молодости тоже хотел=)
Может даже не подебажить, а похукать, и попробовать определить, какой модуль был активный в этот момент. Например, посмотреть адрес возврата из ExAllocatePoolWithTag (в стеке) и посмотреть, какому модулю он принадлежит.
я думаю создавший модуль должен хранить в себе адрес...искать дворд в памяти модуля конечно не самое красивое решение но возможно что единственное.
doctor_Ice а если адрес не хранится в глобальной переменной, например, лежит в стеке, или вообще в регистре хранится (если память нужна кратковременно)?
cresta ну мой способ лучше чем ничего. а в твоем случае нужно иметь инспектор на старте который все в логи ложит. твой способ конечно круче на своем капеге повесил инспектор и все знаеш где что и как ибо у него всегда можно спросить. но если мы вдрг оказались в незнакомом кампеге то что?
Каждое выделение из системного пула снабжается такой структурой (по-крайней мере под w2k): Код (Text): struct _POOL_HEADER { /*<thisrel this+0x0>*/ /*|0x1|*/ unsigned char PreviousSize; /*<thisrel this+0x1>*/ /*|0x1|*/ unsigned char PoolIndex; /*<thisrel this+0x2>*/ /*|0x1|*/ unsigned char PoolType; /*<thisrel this+0x3>*/ /*|0x1|*/ unsigned char BlockSize; /*<thisrel this+0x0>*/ /*|0x4|*/ unsigned long Ulong1; /*<thisrel this+0x4>*/ /*|0x4|*/ struct _EPROCESS* ProcessBilled; /*<thisrel this+0x4>*/ /*|0x4|*/ unsigned long PoolTag; /*<thisrel this+0x4>*/ /*|0x2|*/ unsigned short AllocatorBackTraceIndex; /*<thisrel this+0x6>*/ /*|0x2|*/ unsigned short PoolTagHash; }; // <size 0x8> Максимум, что отсюда можно вытянуть - PoolTag и то, только если в глобальных флагах "Enable pool tagging" включён. Но тэг только "правильные" драйверы и системные модули определяют. В DDK есть пара утилей для наблюдения за распределением памяти по тэгам, но узнать можно только какое кол-во памяти, помеченное данным тегом, выделено, и ещё кое-какую доп инфу. Но узнать пост-фактум, кто именно выделили конкретный кусок памяти теоретически невозможно. OSR'овская тулза DDK\tools\pooltag DDK'ашная тулза со списком тэгов и их описанием DDK\tools\other\<платформа>\poolmon.exe DDK\tools\other\<платформа>\pooltag.txt
Естественно, что грузить драйвер и ставить хук надо как можно раньше, но если хук поймал адрес, сохранил его и он совпадает с искомым - это 100% гарантия того, что найден модуль, выделявший память. И при необходимости можно достаточно уверенно с этим адресом работать. А если шарить по модулям в поисках некоего дворда, то кроме того, что он может быть и не найден (50 на 50), даже если и нашли похожее число, это совсем не значит, что это число есть адрес, а не какой-нибудь результат вычислений и т.п. Т.е. гарантия, что идентифицирован именно адрес опять 50 на 50. В итоге, грубо говоря, 25% успеха. И 75% за то, что вывод о принадлежности памяти тому или иному модулю будет ошибочным со всеми вытекающими последствиями. А в кернеле вероятность 25% равнозначна нулю. Либо 100%, либо ноль. Разве не так?
Надо поставить бряк в одном из отладочных регистров на обращение к нужному тебе участку памяти, ну и хукнуть на время исключение #DB, и в обработчике исключения по fs:[124h] можно было бы определить поток, обратившийся к этой памяти. Я поизвращался бы так %)
M4D Хорошая идея. Лучше, чем память сканить. Вот только если к памяти никто не обращается долгое время ... 8( Может есть на форуме люди, ковырявшие ядро? Есть ли внутрях структуры, отвечающие за память. Дело в том, что должны быть, т.к. : <ol type=1><li>после завершения процесса/потока система закрывает все открытые дескрипторы (ПАМЯТЬ, файлы ...) <li>Ядро знает сколько памяти выделил поток/процесс (она же отображается в Диспетчере, т.е. и там можно ковырять)</ol> Ну дальше понятно... 8)
DrSex Речь идет не о процессе, а о его модулях. Принадлежность блока памяти процессу определить можно, а вот конкретному модулю (exe, dll, драйверу) - нет, т.к. это нафиг никому не нужно (по крайней мере MS )