Синтаксис диапазона адресов и адресов
В отладчике можно указать адреса несколькими способами.
Адреса обычно являются виртуальными, за исключением случаев, когда документация специально указывает другой тип адреса. В пользовательском режиме отладчик интерпретирует виртуальные адреса в соответствии с каталогом страниц текущего процесса. В режиме ядра отладчик интерпретирует виртуальные адреса в соответствии с каталогом страницы процесса, который указывает контекст процесса. Вы также можете напрямую задать контекст адреса в пользовательском режиме. Дополнительные сведения о контексте адреса в пользовательском режиме см. в разделе .context (Set User-Mode Address Context).
В выражениях MASM можно использовать оператор poi для расшифровки любого указателя. Например, если указатель на адрес 0x0000008e'ed57b108 указывает на расположение адреса 0x805287637256, следующие две команды эквивалентны.
0:000> dd 805287637256
0:000> dd poi(000000bb`7ee23108)
Пример отображения адреса памяти
Чтобы просмотреть пример использования poi, определите смещение для CurrentLocale блока среды потока (TEB). Используйте команду dx для отображения @$teb, который является примером псевдорегистров, которые содержат общие адреса, например текущее расположение счетчика программы.
0:000> dx @$teb
@$teb : 0x1483181000 [Type: _TEB *]
...
[+0x108] CurrentLocale : 0x409 [Type: unsigned long]
CurrentLocale — +0x108 с начала TEB. Затем определите адрес памяти этого расположения.
0:000> ? @$teb + 0x108
Evaluate expression: 613867303176 = 0000008e`ed57b108
Используйте poi для расшифровки этого адреса, чтобы увидеть, что он содержит значение CurrentLocale 0x409.
0:000> ? poi(0000008e`ed57b108)
Evaluate expression: 1033 = 00000000`00000409
В выражениях отладчика C++ указатели ведут себя как указатели в C++. Однако числа интерпретируются как целые числа. Если необходимо отложить фактическое число, может потребоваться сначала привести его, как показано в следующем примере.
Чтобы попробовать это, используйте .expr , чтобы задать средство оценки выражений на C++.
0:000> .expr /s C++
Current expression evaluator: C++ - C++ source expressions
С помощью средства оценки выражений, установленного на C++, мы можем привести значение long.
0:000> d *((long*)0x00000014`83181108 )
00000000`00000409 ???????? ???????? ???????? ????????
Дополнительные сведения о приведение числовых значений см. в разделе чисел и операторов C++.
Если для вычислителя выражений задано значение c++, то мы можем упаковать указатель poi с помощью @@masm(), чтобы только часть выражения, вычисляемого вычислителем выражений MASM.
0:000> .expr /s c++
Current expression evaluator: C++ - C++ source expressions
0:000> ? @@masm(poi(00000078`267d7108))
Evaluate expression: 1033 = 00000000`00000409
Дополнительные сведения о двух вычислителях выражений см. в разделе "Оценка выражений".
Можно также указать адрес в приложении, указав исходное имя исходного файла и номер строки. Дополнительные сведения об указании этой информации см. в разделе "Синтаксис исходной строки".
Диапазоны адресов
Диапазон адресов можно указать по паре адресов или по количеству адресов и объектов.
Чтобы указать диапазон по паре адресов, укажите начальный адрес и конечный адрес. Например, в следующем примере представлен диапазон 8 байт, начиная с адреса 0x00001000.
0x00001000 0x00001007
Чтобы указать диапазон адресов по количеству адресов и объектов, укажите аргумент адреса, букву L (верхний или нижний регистр) и аргумент значения. Адрес указывает начальный адрес. Значение указывает количество объектов для проверки или отображения. Размер объекта зависит от команды. Например, если размер объекта равен 1 байту, следующий пример — это диапазон 8 байтов, начиная с адреса 0x00001000.
0x00001000 L8
Однако если размер объекта является двойным словом (32 бита или 4 байта), следующие два диапазона дают диапазон 8-байтов.
0x00001000 0x00001007
0x00001000 L2
Описатель диапазона L
Существует два других способа указать значение (описатель диапазона L Size):
L? Размер (с вопросительным знаком) означает тот же размер, что и L, за исключением того, что L? Размер удаляет автоматическое ограничение диапазона отладчика. Как правило, существует ограничение диапазона в 256 МБ, так как большие диапазоны являются типографическими ошибками. Если вы хотите указать диапазон, размер которого превышает 256 МБ, необходимо использовать L? Синтаксис размера .
L-Size (с дефисом) задает диапазон длины, который заканчивается на заданном адресе. Например, 8000000 L20 указывает диапазон от 0x80000000 до 0x8000001F, а 80000000 L-20 указывает диапазон от 0x7FFFFFE0 до 0x7FFFFFFF.
Некоторые команды, запрашивающие диапазоны адресов, принимают один адрес в качестве аргумента. В этой ситуации команда использует некоторое число объектов по умолчанию для вычисления размера диапазона. Как правило, команды, для которых диапазон адресов является окончательным параметром, разрешают этот синтаксис. Точный синтаксис и размер диапазона по умолчанию для каждой команды см. в справочных разделах для каждой команды.
Пример диапазона памяти поиска
Сначала мы определим адрес регистра указателя инструкции rip с помощью вычислителя выражений MASM.
0:000> ? @rip
Evaluate expression: 140720561719153 = 00007ffc`0f180771
Затем мы будем искать начиная с 00007ffc'0f180771, для 100000 с помощью команды s (Search Memory). Мы указываем диапазон для поиска с помощью L100000.
0:000> s -a 00007ffc`0f180771 L100000 "ntdll"
00007ffc`0f1d48fa 6e 74 64 6c 6c 5c 6c 64-72 69 6e 69 74 2e 63 00 ntdll\ldrinit.c.
00007ffc`0f1d49c2 6e 74 64 6c 6c 5c 6c 64-72 6d 61 70 2e 63 00 00 ntdll\ldrmap.c..
00007ffc`0f1d4ab2 6e 74 64 6c 6c 5c 6c 64-72 72 65 64 69 72 65 63 ntdll\ldrredirec
00007ffc`0f1d4ad2 6e 74 64 6c 6c 5c 6c 64-72 73 6e 61 70 2e 63 00 ntdll\ldrsnap.c.
...
Кроме того, можно указать тот же диапазон, что и в двух адресах памяти.
0:000> s -a 0x00007ffc`0f180771 0x00007ffc`0f280771 "ntdll"
00007ffc`0f1d48fa 6e 74 64 6c 6c 5c 6c 64-72 69 6e 69 74 2e 63 00 ntdll\ldrinit.c.
00007ffc`0f1d49c2 6e 74 64 6c 6c 5c 6c 64-72 6d 61 70 2e 63 00 00 ntdll\ldrmap.c..
00007ffc`0f1d4ab2 6e 74 64 6c 6c 5c 6c 64-72 72 65 64 69 72 65 63 ntdll\ldrredirec
00007ffc`0f1d4ad2 6e 74 64 6c 6c 5c 6c 64-72 73 6e 61 70 2e 63 00 ntdll\ldrsnap.c.
...
Наконец, мы можем искать назад в диапазоне памяти с помощью параметра L-length.
0:000> s -a 00007ffc`0f1d4ad2 L-100000 "ntdll"
00007ffc`0f1d48fa 6e 74 64 6c 6c 5c 6c 64-72 69 6e 69 74 2e 63 00 ntdll\ldrinit.c.
00007ffc`0f1d49c2 6e 74 64 6c 6c 5c 6c 64-72 6d 61 70 2e 63 00 00 ntdll\ldrmap.c..
00007ffc`0f1d4ab2 6e 74 64 6c 6c 5c 6c 64-72 72 65 64 69 72 65 63 ntdll\ldrredirec
Пример отмены памяти
В этом примере используется команда u (unassemble) и параметр L для отмены удаления трех байтов кода.
0:000> u 00007ffc`0f1d48fa L3
ntdll!`string'+0xa:
00007ffc`0f1d48fa 6e outs dx,byte ptr [rsi]
00007ffc`0f1d48fb 7464 je ntdll!`string'+0x21 (00007ffc`0f1d4961)
00007ffc`0f1d48fd 6c ins byte ptr [rdi],dx
Или укажите три диапазона байтов памяти, чтобы отменить это.
0:000> u 00007ffc`0f1d48fa 00007ffc`0f1d48fd
ntdll!`string'+0xa:
00007ffc`0f1d48fa 6e outs dx,byte ptr [rsi]
00007ffc`0f1d48fb 7464 je ntdll!`string'+0x21 (00007ffc`0f1d4961)
00007ffc`0f1d48fd 6c ins byte ptr [rdi],dx
Режимы адресов и поддержка сегментов
На платформах x86 CDB и KD поддерживают следующие режимы адресации. Эти режимы отличаются их префиксами.
Префикс | Имя. | Типы адресов |
---|---|---|
% | flat | 32-разрядные адреса (также 16-разрядные селекторы, указывающие на 32-разрядные сегменты) и 64-разрядные адреса в 64-разрядных системах. |
& | virtual 86 | Адреса в режиме реального режима. Только на основе x86. |
# | plain | Адреса в режиме реального режима. Только на основе x86. |
Разница между режимами обычного и виртуального 86 заключается в том, что обычный 16-разрядный адрес использует значение сегмента в качестве селектора и ищет дескриптор сегмента. Но виртуальный 86-адрес не использует селекторы и вместо этого сопоставляется непосредственно с меньшим размером 1 МБ.
Если доступ к памяти осуществляется через режим адресации, который не является текущим режимом по умолчанию, можно использовать префиксы режима адреса для переопределения текущего режима адреса.
Аргументы адреса
Аргументы адреса указывают расположение переменных и функций. В следующей таблице объясняется синтаксис и смысл различных адресов, которые можно использовать в CDB и KD.
Синтаксис | Значение |
---|---|
offset |
Абсолютный адрес в пространстве виртуальной памяти с типом, соответствующим текущему режиму выполнения. Например, если текущий режим выполнения равен 16 биту, смещение равно 16 биту. Если режим выполнения сегментирован в 32-разрядном режиме, смещение равно 32-разрядному сегменту. |
&[[ сегмент:]] смещение |
Реальный адрес. на основе x86 и на основе x64. |
%segment:[[смещение]] |
Сегментированные 32-разрядные или 64-разрядные адреса. на основе x86 и на основе x64. |
%[[смещение]] |
Абсолютный адрес (32-разрядная или 64-разрядная) в пространстве виртуальной памяти. на основе x86 и на основе x64. |
name[[ +|- ]] смещение |
Неструктурированный 32-разрядный или 64-разрядный адрес. имя может быть любым символом. смещение указывает смещение . Это смещение может быть любым режимом адреса, который указывает префикс. Префикс по умолчанию не указывает адрес режима по умолчанию. Смещение можно указать как положительное (+) или отрицательное значение (-). |
Используйте команду dg (селектор отображения) для просмотра сведений о дескрипторе сегмента.
См. также
Чтобы отобразить сведения о памяти, используйте команду !address .
Для поиска памяти используйте команду s (Search Memory).
Чтобы отобразить содержимое памяти, используйте команду d, da, db, dc, dd, dD, df, dp, dq, du, dw (display Memory).
Сведения о том, как можно просматривать и изменять память с помощью окна памяти, см. в разделе "Использование окна памяти".