【问题标题】:strcat overflow?strcat溢出?
【发布时间】:2012-03-10 12:29:25
【问题描述】:

有人能解释一下为什么我的 strcat 会这样做吗?

我似乎不知道为什么要重写源字符串的一部分。

输出如下: New String: HelloThis shall be after my backslash 0 in str1h 0 in str1

    global  strcat
            extern  strlen

strcat:

    push    ebp
    mov     ebp, esp
    push    ecx
    push    esi
    push    edi
    push    ebx
    push    edx
    xor     edx, edx
    xor     edi, edi
    xor     ebx, ebx
    xor     esi, esi
    xor     ecx, ecx
    mov     edi, [ebp + 8]
    mov     esi, [ebp + 12]
    push    edi
    call    strlen
    pop     edi
    mov     ecx, eax
    xor     eax, eax
    push    esi
    call    strlen
    pop     esi
    mov     ebx, eax
    xor     eax, eax
    cmp     [edi + ecx], byte 0b
    je      PUT_LINE
    jmp     FINALIZE_END

PUT_LINE:

    cmp     ebx, eax
    je      END
    mov     dl, [esi + eax]
    mov     [edi + ecx], dl
    xor     edx, edx
    inc     eax
    inc     ecx
    jmp     PUT_LINE

结束:

    mov     eax, [ebp + 8]
    jmp     FINALIZE_END

FINALIZE_END:

    pop     edx
    pop     ebx
    pop     edi
    pop     esi
    pop     ecx
    mov     esp, ebp
    pop     ebp
    ret

~

~

int     main(int argc, char** argv)
{
        (void)argc;
        (void)argv;
        char*   str1;   
        char*   str2;

        str1 = strdup("Hello");

        str2 = strdup("This shall be after my backslash 0 in str1");
        printf("New String : %s\n", strcat(str1, str2));
        return (0);
}

~

【问题讨论】:

  • 对不起,我刚刚解决了,看起来 Printf 也在寻找 \0,但是因为我没有在目标字符串的末尾设置 \0,所以它溢出了。 END: mov [edi + ecx], byte 0b mov eax, [ebp + 8] jmp FINALIZE_END
  • 在加载寄存器之前将寄存器归零有点违背了编写 asm 的目的......
  • 我只是想避免在使用 8 位还是 16 位时遇到问题,并猜测这是一个坏习惯,但感谢您的间接建议。
  • 看起来您正在保存和恢复的大多数寄存器都不需要保存或恢复。至少在标准的 x86 abi 上,只有 ebp、esi、edi 和 ebx 是被调用者保存的,如果你不使用它们,就不需要保存它们。也不需要在 ebp 中设置帧指针;只需使用 esp 相对寻址。在您进行这样的更改之前,您的strcat 几乎肯定会比短字符串上的标准慢很多,因为进入/退出开销很高。当然,即使你优化得很好,它可能仍然不会更快,但至少你学到了一些好的技巧。

标签: c assembly x86 nasm strcat


【解决方案1】:

strcat() 将字符从一个字符串附加到另一个字符串。目标字符串被修改。所以strcat(str1, str2)修改str1也包含str2的内容。

由于没有为str1 分配足够的内存来包含两个字符串中的字符,这会导致溢出。

【讨论】:

  • 谢谢你,你让我意识到我只是用 \0 来为这个问题加香。
  • 是的,谢谢。但是你如何增加 str1 的内存呢?
  • 你不能增加它。由于 strcat() 仅将字符从一个字符串附加到另一个字符串,因此您可以做的是在使用 strcat() 之前,您必须了解您需要的空间并正确分配它以避免溢出。更多信息linux.die.net/man/3/strcat
猜你喜欢
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 2013-08-23
  • 2019-08-04
  • 2011-01-30
相关资源
最近更新 更多