Поделиться через


Синтаксис диапазона адресов и адресов

В отладчике можно указать адреса несколькими способами.

Адреса обычно являются виртуальными, за исключением случаев, когда документация специально указывает другой тип адреса. В пользовательском режиме отладчик интерпретирует виртуальные адреса в соответствии с каталогом страниц текущего процесса. В режиме ядра отладчик интерпретирует виртуальные адреса в соответствии с каталогом страницы процесса, который указывает контекст процесса. Вы также можете напрямую задать контекст адреса в пользовательском режиме. Дополнительные сведения о контексте адреса в пользовательском режиме см. в разделе .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).

Сведения о том, как можно просматривать и изменять память с помощью окна памяти, см. в разделе "Использование окна памяти".