!список
Расширение !list выполняет указанные команды отладчика несколько раз для каждого элемента в связанном списке.
!list -t [Module!]Type.Field -x "Commands" [-a "Arguments"] [Options] StartAddress
!list " -t [Module!]Type.Field -x \"Commands\" [-a \"Arguments\"] [Options] StartAddress "
!list -h
Параметры
Модуль
Необязательный параметр, указывающий модуль, определяющий эту структуру. Если существует вероятность того, что тип может соответствовать допустимому символу в другом модуле, следует включить модуль , чтобы устранить неоднозначность.
Тип
Задает имя структуры данных.
Поле
Указывает поле, содержащее ссылку списка. Это может быть последовательность полей, разделенных точками (другими словами, Type.Field.Subfield.Subsubfield и т. д.).
-x "Команды"
Указывает выполняемые команды. Это может быть любое сочетание команд отладчика. Он должен быть заключен в кавычки. Если указаны несколько команд, разделите их точкой с запятой, заключите всю коллекцию аргументов !list в кавычки и используйте escape-символ (\ ) перед каждой кавычками внутри этих внешних кавычки. Если команды опущены, значение по умолчанию — dp (display Memory).
-a "Аргументы"
Указывает аргументы для передачи в параметр Commands . Это должно быть заключено в кавычки. Аргументы могут быть любой допустимой строкой аргументов , которая обычно разрешена выполнять эту команду, за исключением того, что аргументы не могут содержать кавычки . Если псевдорегистрация $extret включена в команды, параметр -a "Arguments" может быть опущен.
Параметры могут быть любым количеством следующих параметров:
-e
Эхо выполняет команду для каждого элемента.
-m Max
Указывает максимальное количество элементов для выполнения команды.
StartAddress
Задает адрес первой структуры данных. Это адрес в верхней части структуры, а не обязательно адрес поля ссылки.
-h
Отображает краткий текст справки для этого расширения в окне команды отладчика.
DLL-библиотеки
Ext.dll
Замечания
Расширение !list будет проходить через связанный список и выдавать указанную команду один раз для каждого элемента списка.
Псевдорегистрирующий $extret имеет значение адреса записи списка для каждого элемента списка. Для каждого элемента выполняются команды командной строки. Эта командная строка может ссылаться на этот псевдорегистрирующий регистр с помощью синтаксиса $extret . Если это не отображается в командной строке, значение адреса записи списка добавляется к концу командной строки перед выполнением. Если необходимо указать, где это значение должно отображаться в команде, необходимо явно указать этот псевдорегистрирующий регистр.
Эта последовательность команд будет выполняться до тех пор, пока список не завершится в указателе NULL, или завершится циклом обратно на первый элемент. Если список циклит обратно на более поздний элемент, эта команда не остановится. Однако эту команду можно остановить в любое время с помощью CTRL+C в KD и CDB или Debug | Разрыв или CTRL+BREAK в WinDbg.
Каждый раз при выполнении команды адрес текущей структуры будет использоваться в качестве адреса по умолчанию, если используется команда имеет необязательные параметры адреса.
Ниже приведены два примера использования этой команды в пользовательском режиме. Обратите внимание, что использование режима ядра также возможно, но соответствует другому синтаксису.
В качестве простого примера предположим, что у вас есть структура, имя типа которой — MYTYPE, и которая содержит ссылки в его ссылках .links. Flink и .links. Поля мигания . У вас есть связанный список, начинающийся со структуры по 0x6BC000. Следующая команда расширения будет проходить через список, и для каждого элемента будет выполняться команда dd L2. Так как адрес не указан в команде dd , он будет принимать адрес головы списка в качестве нужного адреса. Это приводит к отображению первых двух DWORD в каждой структуре.
0:000> !list -t MYTYPE.links.Flink -x "dd" -a "L2" 0x6bc00
В более сложном примере рассмотрим вариант использования $extret. Он следует списку типов _LIST_ENTRY в RtlCriticalSectionList. Для каждого элемента отображается первые четыре DWORDS, а затем отображается структура _RTL_CRITICAL_SECTION_DEBUG, расположенная в смещение 8 байтов до элемента Flink записи списка.
0:000> !list "-t ntdll!_LIST_ENTRY.Flink -e -x \"dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8\" ntdll!RtlCriticalSectionList"
dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8
7c97c0c8 7c97c428 7c97c868 01010000 00000080
+0x000 Type : 1
+0x002 CreatorBackTraceIndex : 0
+0x004 CriticalSection : (null)
+0x008 ProcessLocksList : _LIST_ENTRY [ 0x7c97c428 - 0x7c97c868 ]
+0x010 EntryCount : 0x1010000
+0x014 ContentionCount : 0x80
+0x018 Spare : [2] 0x7c97c100
dd @$extret l4; dt ntdll!_RTL_CRITICAL_SECTION_DEBUG @$extret-0x8
7c97c428 7c97c448 7c97c0c8 00000000 00000000
+0x000 Type : 0
+0x002 CreatorBackTraceIndex : 0
+0x004 CriticalSection : 0x7c97c0a0
+0x008 ProcessLocksList : _LIST_ENTRY [ 0x7c97c448 - 0x7c97c0c8 ]
+0x010 EntryCount : 0
+0x014 ContentionCount : 0
+0x018 Spare : [2] 0