2016-07-19 7 views
3

내 아주 간단한 테스트 프로그램 컴파일 및 연결 후Ollydbg를 사용하면 누구나 변수 "a"의 주소가 무엇인지 말해 줄 수 있습니까? <a href="https://i.stack.imgur.com/e2BQd.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/e2BQd.png" alt="OllyDbg"></a></p> <p>사진은 main() 함수를 보여줍니다

#include<stdio.h> 
#include<stdlib.h> 

int main() 
{ 
int a = 12345; 
printf("%d\n", a); 

system("PAUSE"); 
return 0; 

} 

는 EXE 파일 내가 올리 디버그에서 EXE 파일을 열 created.Then입니다. 그러나 변수 a의 주소가 무엇인지 알 수 없습니다. 매개 변수를 printf() 함수로 전달할 때 3039을 스택에 넣으면 변수 a의 값이 3039이라는 의미입니까? 아니요, 값은 12345입니다. 따라서 변수 a의 주소는 00003039입니까? 누구나

답변

3

주소가 인 경우 [ebp-8]입니다. 0x3039 십진수가 12345은 16 진수 0x3039이므로 할당이 표시됩니다. 코드가 16 진수 값을 사용하도록 변경하면 IDA results

일반적으로 숫자 상수는 코드에 직접 컴파일됩니다.

+1

당신을 감사합니다 실제 ESP 값을 대체, 그리고

(gdb) info registers esp esp 0x22ff20 0x22ff20 

등록의 현재의 값을 확인 0x3039하자) 16 – freedomwings

0

변수 a의 주소를 알고 싶습니다.

매우 간단합니다 :

삽입 프로그램에이 문장.

printf("address of variable 'a' is: %p\n", &a); 

주소를 어떻게 알 수 있습니까?

우리는 당신의 컴퓨터

에 앉아되지 않으며 대부분의 모든 컴퓨터에 다를 수 있습니다.

인해 페이징, 주소 변환, 주소 가상 등 그 주소는 컴퓨터의 메모리 공간 내에서 실제 물리적 주소가 아닌에, 그러나 '주소'

내용 printf()에 제안 된 호출을 사용합니다.

0

이 경우 a와 같은 지역 변수는 스택에 저장되므로 함수 실행이 끝나면 무시 될 수 있으므로 기본적으로 로컬 스택 프레임의 메모리 주소에 위치합니다. 이 경우

int a = 12345; // MOV DWORD PTR SS:[EBP-8], 3039 
printf("%d\n", a); 

는, A는에 위치한 [EBP-8] 당신이 가리키는 위치를 검사 할 경우도 물론 할당 이후에 저장된 값 (3039)을 볼 수있다 (3039)는 16 진수이다 물론 10 진수의 12345입니다.

0

이 점을 더 잘 이해하기 위해 프로그램을 조금 수정하고 GDB에서 디버깅 해 봅시다.

C:\Codes>gdb test -q 
Reading symbols from C:\Codes\test.exe...done. 
(gdb) set disassembly-flavor intel 
(gdb) list 
1  #include<stdio.h> 
2 
3  int main() 
4  { 
5   int a = 12345; 
6   int b = 0x12345; 
7   printf("Variable a %d (decimal) or 0x%x (hex), located at %p or 0x%x\n", a,a,&a,&a); 
8   printf("Variable b %d (decimal) or 0x%x (hex), located at %p or 0x%x\n", b,b,&b,&b); 
9   return 0; 
10  } 
(gdb) 

표준 출력

C:\Codes>test 
Variable a 12345 (decimal) or 0x3039 (hex), located at 0022FF4C or 0x22ff4c 
Variable b 74565 (decimal) or 0x12345 (hex), located at 0022FF48 or 0x22ff48 

당신이 볼 수 있듯이, 변수 ab의 가상 메모리 주소는 실제로 각각 0x22ff4c0x22ff48에 있습니다.

GDB에서이 프로그램을 살펴 보겠습니다.

(gdb) break 7 
Breakpoint 1 at 0x40135e: file test.c, line 7. 
(gdb) run 
Starting program: C:\Codes/test.exe 
[New Thread 3680.0xed8] 

Breakpoint 1, main() at test.c:7 
7   printf("Variable a %d (decimal) or 0x%x (hex), located at %p or 0x%x\n", a,a,&a,&a); 
(gdb) disassemble 
Dump of assembler code for function main: 
    0x00401340 <+0>:  push ebp 
    0x00401341 <+1>:  mov ebp,esp 
    0x00401343 <+3>:  and esp,0xfffffff0 
    0x00401346 <+6>:  sub esp,0x30 
    0x00401349 <+9>:  call 0x401970 <__main> 
    0x0040134e <+14>: mov DWORD PTR [esp+0x2c],0x3039 
    0x00401356 <+22>: mov DWORD PTR [esp+0x28],0x12345 
=> 0x0040135e <+30>: mov edx,DWORD PTR [esp+0x2c] 
    0x00401362 <+34>: mov eax,DWORD PTR [esp+0x2c] 
    0x00401366 <+38>: lea ecx,[esp+0x2c] 
    0x0040136a <+42>: mov DWORD PTR [esp+0x10],ecx 
    0x0040136e <+46>: lea ecx,[esp+0x2c] 
    0x00401372 <+50>: mov DWORD PTR [esp+0xc],ecx 
    0x00401376 <+54>: mov DWORD PTR [esp+0x8],edx 
    0x0040137a <+58>: mov DWORD PTR [esp+0x4],eax 
    0x0040137e <+62>: mov DWORD PTR [esp],0x403024 
    0x00401385 <+69>: call 0x401be0 <printf> 
    0x0040138a <+74>: mov edx,DWORD PTR [esp+0x28] 
    0x0040138e <+78>: mov eax,DWORD PTR [esp+0x28] 
    0x00401392 <+82>: lea ecx,[esp+0x28] 
    0x00401396 <+86>: mov DWORD PTR [esp+0x10],ecx 
    0x0040139a <+90>: lea ecx,[esp+0x28] 
    0x0040139e <+94>: mov DWORD PTR [esp+0xc],ecx 
    0x004013a2 <+98>: mov DWORD PTR [esp+0x8],edx 
    0x004013a6 <+102>: mov DWORD PTR [esp+0x4],eax 
    0x004013aa <+106>: mov DWORD PTR [esp],0x403064 
    0x004013b1 <+113>: call 0x401be0 <printf> 
    0x004013b6 <+118>: mov eax,0x0 
    0x004013bb <+123>: leave 
    0x004013bc <+124>: ret 
End of assembler dump. 
(gdb) 

그리고 이전 출력에서 ​​볼 수 있듯이이 줄

0x0040134e <+14>: mov DWORD PTR [esp+0x2c],0x3039 
    0x00401356 <+22>: mov DWORD PTR [esp+0x28],0x12345 

에 초점 변수의 가상 메모리 주소 ab 실제로 각각 [esp+0x2c] 또는 0x22ff4c[esp+0x28] 또는 0x22ff48에 있습니다.

0x3039 & 0x12345

변수 16 진수 a b 및 값이있다. 0x22ff4c 또는 0x22ff48의 주소가 어디에서 왔는지 궁금 수도

(gdb) print &a 
$1 = (int *) 0x22ff4c 

(gdb) print &b 
$2 = (int *) 0x22ff48 

을 또한 :

은 GDB에서 이러한 변수의 메모리 주소를 확인 다음과 같이 print 명령을 사용합니다.

이를 이해하기 위해서, (ESP .I이 (12345) 10 = 실현되지 않은

[esp+0x2c] = [0x22ff20 + 0x2c] = 0x22ff4c 
[esp+0x28] = [0x22ff20 + 0x28] = 0x22ff48