汇编和 C++

逆向工程 拆卸 部件 C++ C 补丁反转
2021-06-16 12:34:31

我正在努力学习逆向工程,此时我没有任何优化地编译C++代码并在IDA的反汇编器中看到相应的程序集,但是代码的某些部分我无法猜测会发生什么。下面的汇编代码中有一些问题。

C++代码:

#include <stdio.h>
#include <string>

void fillarray(int is[11], int size)
{
    for (int i = 0; i < size; ++i)
    {
        is[i] = i;
    }
}

int main()
{
    char* chr = "First";
    std::string m = "Secdond";

    static int arr[11];

    std::string m1 = "Third";

    auto size = sizeof(arr) / sizeof(arr[0]);

    fillarray(arr, size);

    int num = 11;

    printf_s("%d", num);


    getchar();

    return 0;
}

IDA中的主要功能:

.text:00401E20
.text:00401E20
.text:00401E20 ; Attributes: bp-based frame
.text:00401E20
.text:00401E20 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00401E20 main proc near
.text:00401E20
.text:00401E20 First_via_char= dword ptr -50h
.text:00401E20 var_4C= dword ptr -4Ch
.text:00401E20 var_eleven= dword ptr -48h
.text:00401E20 size= dword ptr -44h
.text:00401E20 Second_via_str= byte ptr -40h
.text:00401E20 Third_via_str= byte ptr -28h
.text:00401E20 CANARY= dword ptr -10h
.text:00401E20 var_C= dword ptr -0Ch
.text:00401E20 var_4= dword ptr -4
.text:00401E20 argc= dword ptr  8
.text:00401E20 argv= dword ptr  0Ch
.text:00401E20 envp= dword ptr  10h
.text:00401E20
.text:00401E20 push    ebp
.text:00401E21 mov     ebp, esp
.text:00401E23 push    0FFFFFFFFh
.text:00401E25 push    offset sub_402D20
.text:00401E2A mov     eax, large fs:0         // what is this? I know that fs:0 is to access PEB, but why this code uses this? 
.text:00401E30 push    eax
.text:00401E31 sub     esp, 44h
.text:00401E34 mov     eax, ___security_cookie
.text:00401E39 xor     eax, ebp
.text:00401E3B mov     [ebp+CANARY], eax       // I thinks it's CANARY
.text:00401E3E push    eax
.text:00401E3F lea     eax, [ebp+var_C]       // what is var_C for?
.text:00401E42 mov     large fs:0, eax        // At this moment, var_C is uninitialized. How and why programm need this?
.text:00401E48 mov     [ebp+First_via_char], offset aFirst ; "First"
.text:00401E4F push    offset aSecdond ; "Secdond"
.text:00401E54 lea     ecx, [ebp+Second_via_str]
.text:00401E57 call    basic_string
.text:00401E5C mov     [ebp+var_4], 0
.text:00401E63 push    offset aThird   ; "Third"
.text:00401E68 lea     ecx, [ebp+Third_via_str]
.text:00401E6B call    basic_string
.text:00401E70 mov     byte ptr [ebp+var_4], 1      // what is var_4?
.text:00401E74 mov     [ebp+size], 0Bh
.text:00401E7B mov     eax, [ebp+size]
.text:00401E7E push    eax
.text:00401E7F push    offset unk_404098 ; address of arrary
.text:00401E84 call    fill_array_function
.text:00401E89 add     esp, 8
.text:00401E8C mov     [ebp+var_eleven], 0Bh
.text:00401E93 mov     ecx, [ebp+var_eleven]
.text:00401E96 push    ecx
.text:00401E97 push    offset aD       ; "%d"
.text:00401E9C call    printf
.text:00401EA1 add     esp, 8
.text:00401EA4 call    ds:getchar
.text:00401EAA mov     [ebp+var_4C], 0
.text:00401EB1 mov     byte ptr [ebp+var_4], 0
.text:00401EB5 lea     ecx, [ebp+Third_via_str]
.text:00401EB8 call    sub_401270                    // What is this? I think it's destructor, but I'm not sure.
.text:00401EBD mov     [ebp+var_4], 0FFFFFFFFh
.text:00401EC4 lea     ecx, [ebp+Second_via_str]
.text:00401EC7 call    sub_401270                    // Destructor?
.text:00401ECC mov     eax, [ebp+var_4C]             // what is var_4C?
.text:00401ECF mov     ecx, [ebp+var_C]              // var_C?
.text:00401ED2 mov     large fs:0, ecx
.text:00401ED9 pop     ecx
.text:00401EDA mov     ecx, [ebp+CANARY]
.text:00401EDD xor     ecx, ebp
.text:00401EDF call    sub_401F68
.text:00401EE4 mov     esp, ebp
.text:00401EE6 pop     ebp
.text:00401EE7 retn
.text:00401EE7 main endp
.text:004
1个回答

您评论的部分主要与异常处理有关。编译器必须防范可能随时发生的异常,即使您的程序没有明确使用异常。特别var_4是当前执行点的所谓“trylevel”,var_C是SEH机制的异常注册记录。CANARY确实是堆栈溢出保护金丝雀(MSVC 术语中的“cookie”)。

您可以在关于该主题的OpenRCE 文章中找到更多详细信息

PSvar_4C只是一个临时变量,用于存储函数的返回值(0)。它被保存是因为字符串的销毁必须在 return 语句之后但在函数实际返回之前发生。