주소 및 주소 범위 구문

디버거에서 주소를 지정하는 방법에는 여러 가지가 있습니다.

설명서가 다른 종류의 주소를 구체적으로 나타내는 경우를 제외하고 주소는 일반적으로 가상 주소입니다. 사용자 모드에서 디버거는 현재 프로세스의 페이지 디렉터리에 따라 가상 주소를 해석합니다. 커널 모드에서 디버거는 프로세스 컨텍스트 가 지정하는 프로세스의 페이지 디렉터리에 따라 가상 주소를 해석합니다. 사용자 모드 주소 컨텍스트를 직접 설정할 수도 있습니다. 사용자 모드 주소 컨텍스트에 대한 자세한 내용은 .context(User-Mode 주소 컨텍스트 설정)를 참조하세요.

MASM 식에서 poi 연산자를 사용하여 포인터를 역참조할 수 있습니다. 예를 들어 주소 0x0000008e'ed57b108의 포인터가 주소 위치 0x805287637256 가리키는 경우 다음 두 명령은 동일합니다.

0:000> dd 805287637256
0:000> dd poi(000000bb`7ee23108)

메모리 주소 표시 예제

poi를 사용하는 예제를 보려면 TEB(스레드 환경 블록)의 CurrentLocale 에 대한 오프셋을 결정합니다. dx 명령을 사용하여 현재 프로그램 카운터 위치와 같은 일반적인 주소를 포함하는 의사 레지스터의 예인 @$teb 표시합니다.

0:000> dx @$teb
@$teb                 : 0x1483181000 [Type: _TEB *]

...

    [+0x108] CurrentLocale    : 0x409 [Type: unsigned long]

CurrentLocale 은 TEB 시작부터 +0x108. 다음으로 해당 위치의 메모리 주소를 확인합니다.

0:000> ? @$teb + 0x108
Evaluate expression: 613867303176 = 0000008e`ed57b108

poi를 사용하여 해당 주소를 역참조하여 0x409 CurrentLocale 값이 포함되어 있는지 확인합니다.

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

두 식 계산기에 대한 자세한 내용은 식 평가를 참조하세요.

원본 원본 파일 이름 및 줄 번호를 지정하여 애플리케이션에서 주소를 나타낼 수도 있습니다. 이 정보를 지정하는 방법에 대한 자세한 내용은 원본 줄 구문을 참조하세요.

주소 범위

주소 한 쌍 또는 주소 및 개체 수별로 주소 범위를 지정할 수 있습니다.

한 쌍의 주소로 범위를 지정하려면 시작 주소와 끝 주소를 지정합니다. 예를 들어 다음 예제는 주소 0x00001000 시작하여 8바이트 범위입니다.

0x00001000  0x00001007

주소 및 개체 수별로 주소 범위를 지정하려면 주소 인수, 문자 L(대문자 또는 소문자) 및 값 인수를 지정합니다. 주소는 시작 주소를 지정합니다. 값은 검사하거나 표시할 개체의 수를 지정합니다. 개체의 크기는 명령에 따라 달라집니다. 예를 들어 개체 크기가 1바이트인 경우 다음 예제는 주소 0x00001000 시작하여 8바이트 범위입니다.

0x00001000  L8

그러나 개체 크기가 이중 단어(32비트 또는 4바이트)인 경우 다음 두 범위는 각각 8바이트 범위를 제공합니다.

0x00001000  0x00001007
0x00001000  L2

L 크기 범위 지정자

값을 지정하는 다른 두 가지 방법( L크기 범위 지정자)은 다음과 같습니다.

  • L?크기 (물음표 포함)는 L을 제외하고 L크기와 동일합니까 ?크기 는 디버거의 자동 범위 제한을 제거합니다. 일반적으로 범위 제한은 256MB입니다. 큰 범위는 입력 오류이기 때문입니다. 256MB보다 큰 범위를 지정하려면 L을 사용해야 합니까 ?크기 구문입니다.

  • L-Size(하이픈 포함)는 지정된 주소에서 끝나는 크기 길이 범위를 지정합니다. 예를 들어 800000000 L20 은 0x80000000 0x8000001F 범위를 지정하고 800000000 L-20 은 0x7FFFFFE0 범위부터 0x7FFFFFFF까지의 범위를 지정합니다.

주소 범위를 요청하는 일부 명령은 단일 주소를 인수로 허용합니다. 이 경우 명령은 일부 기본 개체 수를 사용하여 범위의 크기를 계산합니다. 일반적으로 주소 범위가 최종 매개 변수인 명령은 이 구문을 허용합니다. 각 명령에 대한 정확한 구문과 기본 범위 크기는 각 명령에 대한 참조 topics 참조하세요.

메모리 범위 검색 예제

먼저 MASM 식 계산기를 사용하여 rip 명령 포인터 레지스터의 주소를 결정합니다.

0:000> ? @rip 
Evaluate expression: 140720561719153 = 00007ffc`0f180771

그런 다음 s(메모리 검색) 명령을 사용하여 00007ffc'0f180771부터 100000을 검색합니다. 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 길이 매개 변수를 사용하여 메모리 범위에서 뒤로 검색할 수 있습니다.

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 매개 변수를 사용하여 3바이트의 코드를 언어셈블합니다.

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

또는 다음과 같이 언어셈블할 메모리의 3개 바이트 범위를 지정합니다.

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는 다음 주소 지정 모드를 지원합니다. 이러한 모드는 접두사로 구분됩니다.

접두사 Name 주소 유형
% 플랫 32비트 주소(32비트 세그먼트를 가리키는 16비트 선택기) 및 64비트 시스템의 64비트 주소
& 가상 86 실제 모드 주소입니다. x86 기반 전용입니다.
# plain 실제 모드 주소입니다. x86 기반 전용입니다.

일반 모드와 가상 86 모드의 차이점은 일반 16비트 주소가 세그먼트 값을 선택기로 사용하고 세그먼트 설명자를 조회한다는 것입니다. 그러나 가상 86 주소는 선택기를 사용하지 않고 대신 하위 1MB에 직접 매핑됩니다.

현재 기본 모드가 아닌 주소 지정 모드를 통해 메모리에 액세스하는 경우 주소 모드 접두사를 사용하여 현재 주소 모드를 재정의할 수 있습니다.

주소 인수

주소 인수는 변수 및 함수의 위치를 지정합니다. 다음 표에서는 CDB 및 KD에서 사용할 수 있는 다양한 주소의 구문과 의미를 설명합니다.

Syntax 의미

offset

현재 실행 모드에 해당하는 형식이 있는 가상 메모리 공간의 절대 주소입니다. 예를 들어 현재 실행 모드가 16비트인 경우 오프셋은 16비트입니다. 실행 모드가 32비트 분할된 경우 오프셋은 32비트 분할됩니다.

&[[ segment:]] 오프셋

실제 주소입니다. x86 기반 및 x64 기반

%segment:[[ offset]]

분할된 32비트 또는 64비트 주소입니다. x86 기반 및 x64 기반

%[[ 오프셋]]

가상 메모리 공간의 절대 주소(32비트 또는 64비트)입니다. x86 기반 및 x64 기반

name[[ +|- ]] 오프셋

플랫 32비트 또는 64비트 주소입니다. name 은 기호일 수 있습니다. 오프셋 은 오프셋을 지정합니다. 이 오프셋은 접두사에서 나타내는 주소 모드일 수 있습니다. 기본 모드 주소를 지정하는 접두사는 없습니다. 오프셋을 양수(+) 또는 음수(-) 값으로 지정할 수 있습니다.

dg(디스플레이 선택기) 명령을 사용하여 세그먼트 설명자 정보를 봅니다.

참고 항목

메모리에 대한 정보를 표시하려면 !address 명령을 사용합니다.

메모리를 검색하려면 s(메모리 검색) 명령을 사용합니다.

메모리 내용을 표시하려면 d, da, db, dc, dd, dD, df, dp, dq, du, dw(메모리 표시) 명령을 사용합니다.

메모리 창을 사용하여 메모리를 보고 편집하는 방법에 대한 자세한 내용은 메모리 창 사용을 참조하세요.