为什么 eax 被分配给“变量看起来”像地址

逆向工程 艾达 拆卸 部件 调试 x86
2021-06-28 08:17:40
#include <stdio.h>
int main() {

    int number1, number2, sum;

    printf("Enter two integers: ");
    scanf("%d %d", &number1, &number2);

    
    sum = number1 + number2;

    
    printf("%d + %d = %d", number1, number2, sum);
    return 0;
}

所以这是我的简单 C 代码,它只有三个变量,但是当我在反汇编中调试它时,它的值eax也在其他“变量看起来”(如 r/m32 地址)中复制,我不知道为什么会这样这样做。它不能是编译器生成的代码,因为我已经关闭了这些选项。

这是开始的反汇编,看到的值eax将转到变量 ( sum, number2, number1) 但为什么会[ebp-18h]这样等等。此外,这些[ebp-18h]也不会用于拆卸的任何其他地方。它只是显示在这里。另一个问题是为什么0CCCCCCCCC被移动到eax.

2个回答

从表面上看,这很容易。是的,这些是堆栈上的变量,EAX 中幻数用于表示未初始化的值。引用:

CCCCCCCCMicrosoft 的 C++ 调试运行时库和许多 DOS 环境使用它来标记未初始化的堆栈内存。CC 类似于 x86 处理器上的 INT 3 调试断点中断的操作码。

因此,您很可能使用 MSVC 构建了调试配置。

如果 Visual Studio 2017 社区正在生成模式填充,
则正在使用编译器选项 /RTCsu
这也会打开增量链接(将生成 *.ilk 文件)

早期版本的编译器使用 /GZ 选项,如果现在使用该选项将生成弃用警告

您的代码也没有使用 scanf_s 安全版本的易受攻击的 scanf();这也应该产生警告

下面显示的是编译器的警告和模式填充以及替代 /RTC1 或 RTCsu 建议

你的代码

:\>type magic.cpp
#include <stdio.h>
int main() {
    int number1, number2, sum;
    printf("Enter two integers: ");
    scanf("%d %d", &number1, &number2);
    sum = number1 + number2;
    printf("%d + %d = %d", number1, number2, sum);
    return 0;
}
:\>dir /b
magic.cpp

用 /GZ 编译

:\>cl /Zi /GZ magic.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.16.27035 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9035 : option 'GZ' has been deprecated and will be removed in a future release
cl : Command line warning D9036 : use 'RTC1' instead of 'GZ'
magic.cpp
Microsoft (R) Incremental Linker Version 14.16.27035.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:magic.exe
/debug
magic.obj

反汇编显示模式填充和其他堆栈检查结构,如 RTCCheckESP

:\>cdb -c "uf magic!main;q" magic.exe | awk "/Reading/,/quit/"
0:000> cdb: Reading initial command 'uf magic!main;q'
*** WARNING: Unable to verify checksum for magic.exe
magic!main:
00d37a70 55              push    ebp
00d37a71 8bec            mov     ebp,esp
00d37a73 83ec1c          sub     esp,1Ch
00d37a76 b8cccccccc      mov     eax,0CCCCCCCCh <<<<<<<<<<
00d37a7b 8945e4          mov     dword ptr [ebp-1Ch],eax
00d37a7e 8945e8          mov     dword ptr [ebp-18h],eax
00d37a81 8945ec          mov     dword ptr [ebp-14h],eax
00d37a84 8945f0          mov     dword ptr [ebp-10h],eax
00d37a87 8945f4          mov     dword ptr [ebp-0Ch],eax
00d37a8a 8945f8          mov     dword ptr [ebp-8],eax
00d37a8d 8945fc          mov     dword ptr [ebp-4],eax
00d37a90 6850aed900      push    offset magic!__xt_z+0x108 (00d9ae50)
00d37a95 e8b799ffff      call    magic!ILT+1100(_printf) (00d31451)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
00d37ae0 e834b8ffff      call    magic!ILT+8980(_RTC_CheckStackVars (00d33319) <<<<<<<
00d37ae5 58              pop     eax
00d37ae6 5a              pop     edx
00d37ae7 83c41c          add     esp,1Ch
00d37aea 3bec            cmp     ebp,esp
00d37aec e8bbb6ffff      call    magic!ILT+8615(__RTC_CheckEsp) (00d331ac) <<<<<<<<<<<<
00d37af1 8be5            mov     esp,ebp
00d37af3 5d              pop     ebp
00d37af4 c3              ret
quit: