【问题标题】:Using the Ollydbg,anyone tell me what the address of the variable "a" is?使用 Ollydbg,谁能告诉我变量“a”的地址是什么?
【发布时间】:2016-11-21 18:40:24
【问题描述】:

我非常简单的测试程序

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

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

system("PAUSE");
return 0;

}

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

图为main()函数,但查不到变量a的地址是什么。在将参数传递给printf()函数时,它会将3039压入堆栈,那么这意味着变量a的值是3039?不,值为12345。所以这意味着变量a的地址是00003039?任何人

【问题讨论】:

    标签: c reverse-engineering decompiling ollydbg


    【解决方案1】:

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

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

    【讨论】:

    • 谢谢。我还没有意识到 (12345)10 = (0x3039)16
    【解决方案2】:

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

    非常简单:

    将此语句插入您的程序中。

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

    我们如何知道地址?

    我们不是坐在你的电脑前

    而且在大多数计算机上都会有所不同。

    使用建议的呼叫printf() 了解“地址”

    但是,由于分页、地址转换、虚拟寻址等原因。该地址不是您计算机内存空间中的实际物理地址。

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        【解决方案4】:

        为了更好地理解这一点,让我们稍微修改一下程序并在 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 是变量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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-05-29
          • 1970-01-01
          • 1970-01-01
          • 2020-08-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多