переполнение strcat?

Может ли кто-нибудь объяснить, почему мой strcat делает это?

Кажется, я не могу понять, почему я переписываю часть исходной строки.

Вывод выглядит следующим образом: Новая строка: HelloThis должна быть после обратной косой черты 0 в str1h 0 в str1

    global  strcat
            extern  strlen

улкат:

    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

ЗАВЕРШИТЬ_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);
}

~


person Abdellah IDRISSI    schedule 10.03.2012    source источник
comment
Извините, я только что решил это. Кажется, что Printf тоже ищет \0, но поскольку я не установил \0 в конце строки назначения, он переполнился. КОНЕЦ: mov [edi + ecx], byte 0b mov eax, [ebp + 8] jmp FINALIZE_END   -  person Abdellah IDRISSI    schedule 10.03.2012
comment
Обнуление регистров перед загрузкой в ​​них как бы противоречит цели написания asm...   -  person R.. GitHub STOP HELPING ICE    schedule 10.03.2012
comment
Я просто пытался избежать проблем, должен ли я использовать 8 бит или 16 бит, и думаю, это стало плохой привычкой, но спасибо за косвенный совет.   -  person Abdellah IDRISSI    schedule 10.03.2012
comment
Также похоже, что большинство регистров, которые вы сохраняете и восстанавливаете, не нужно сохранять или восстанавливать. По крайней мере, на стандартном x86 abi только ebp, esi, edi и ebx сохраняются вызываемым пользователем, и если вы их не используете, их не нужно сохранять. Также нет необходимости настраивать указатель кадра в ebp; просто используйте esp-относительную адресацию. Пока вы не внесете подобные изменения, ваш strcat почти наверняка будет намного медленнее стандартного на коротких строках из-за высоких накладных расходов на вход/выход. Конечно, даже если вы хорошо оптимизируете его, он, вероятно, все равно не будет работать быстрее, но, по крайней мере, вы узнаете несколько хороших трюков.   -  person R.. GitHub STOP HELPING ICE    schedule 10.03.2012


Ответы (1)


strcat() добавляет символы из одной строки в другую строку. Целевая строка изменена. Таким образом, strcat(str1, str2) изменяет str1, чтобы также содержать содержимое str2.

Так как для str1 выделяется недостаточно памяти, чтобы содержать символы из обеих строк, это приводит к переполнению.

person sth    schedule 10.03.2012
comment
Спасибо за это, вы заставили меня понять, что я просто ароматизировал проблему с помощью \ 0. - person Abdellah IDRISSI; 10.03.2012
comment
Да спасибо вам за это. Но как тогда увеличить память для str1? - person anon58192932; 05.05.2012
comment
Вы не должны увеличивать его. поскольку strcat() только добавляет символы из одной строки в другую, то, что вы можете сделать, это перед использованием strcat(), вы должны знать о необходимом вам пространстве и распределять его правильно, чтобы избежать переполнения. для получения дополнительной информации linux.die.net/man/3/strcat - person Abdellah IDRISSI; 12.05.2012