使用Ollydbg,任何人都可以告诉我变量的地址是什么" a"是什么?

时间:2016-07-19 02:57:21

标签: c reverse-engineering decompiling ollydbg

我非常简单的测试程序

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

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

system("PAUSE");
return 0;

}

编译并连接后,创建了EXE文件。然后我在Ollydbg中打开EXE文件: OllyDbg

图片显示了main()函数。但是我无法找出变量a的地址。将params传递给printf()函数时,它会将3039推入堆栈,那么它意味着变量a的值是3039?不,值为12345。那么这意味着变量a的地址是00003039?任何人

4 个答案:

答案 0 :(得分:3)

a变量的地址为[ebp-8]。您看到0x3039分配,因为十进制12345是十六进制0x3039。如果您将代码更改为使用十六进制值int a = 0x12345,结果会更清晰: IDA results

数字常量通常直接编译到代码中。

答案 1 :(得分:0)

所以你想知道变量a的地址。

非常简单:

将此语句插入您的程序。

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

我们如何知道地址?

我们不是坐在你的电脑上

并且在每台计算机上都会有所不同。

使用建议的printf()来电了解地址&#39;

但是,由于分页,地址转换,虚拟寻址等原因,该地址并非您计算机中的实际物理地址。记忆空间。

答案 2 :(得分:0)

本地变量(如本例中的a)存储在堆栈中,因此在函数执行完成时可以将它们丢弃,所以基本上只是位于本地堆栈帧的内存地址。

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

在这种情况下,a位于[EBP-8]中,如果你检查它指向的位置,你可以看到值3039,当然在分配后存储在那里,3039是十六进制数,当然当然12345在基地10。

答案 3 :(得分: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&amp; 0x12345是十六进制变量ab的值。

要在GDB中验证这些变量的内存地址,请使用print命令,如下所示:

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

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

此外,您可能想知道0x22ff4c0x22ff48的地址来自何处。

要理解这一点,让我们检查一下当前ESP寄存器的值

(gdb) info registers esp
esp            0x22ff20 0x22ff20

然后,替换实际的ESP值

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