0

I made the function strcpy in assembly, then I tried to launch several program like Firefox, emacs, ... But I have an issue on the copy and I don't know where the problem is.

Assembly code :

global strcpy

section .text

strcpy:
    push rbp
    push rdx
    mov rbp, rsp
    mov rdx, 0
strcpy_loop:
    cmp byte [rsi + rdx], 0
    je strcpy_end
    mov al, byte [rsi + rdx]
    mov byte [rdi + rdx], al
    inc rdx
    jmp strcpy_loop
strcpy_end:
    mov rax, rdi
    mov rsp, rbp
    pop rdx
    pop rbp
    ret

result when i try to launch a small program with my shared library:

s1 = hello
s2 before copy = 
s2 after copy = hello

result when i try to launch firefox with my shared library:

/usr/bin/firefox: line 52: $'basenamex\326g\002Lame $0`': command not found
/usr/bin/firefox: line 57: bad substitution: no closing "`" in `x�gL
/usr/bin/firefox: line 63: $'[\340\n\002': command not found
/usr/bin/firefox: line 73: fileL: command not found
/usr/bin/firefox: line 75: echoL: command not found
grep: invalid option -- 'g'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
/usr/bin/firefox: line 78: $'[\351\n\002L': command not found
/usr/bin/firefox: line 83: export: `MOZILLA_FIVE_HOME�gL': not a valid identifier
/usr/bin/firefox: line 91: $'[\257\n\002': command not found
/usr/bin/firefox: line 95: /dev/null�gL: Permission denied
/usr/bin/firefox: line 97: $'[\t\v\002': command not found
/usr/bin/firefox: line 108: $'[\006\v\002': command not found
/usr/bin/firefox: line 131: $'[\023\v\002': command not found
/usr/bin/firefox: line 138: exec: =0
                                : not found

The small program is working, but not firefox.

1 Answers1

0

You're not actually copying the string terminator \0 at the end of the string, meaning that the destination string is left without one. In other words, if you do something like:

char buff[] = "Hello there";
strcpy (buff, "Bye");         // your strcpy, not a 'real' one.

then you'll end up with:

Byelo there

which is not what you want. In order to correct this, you can do it with something like:

strcpy_end:
    xor   al, al                  ; force al to `\0`.
    mov   byte [rdi + rdx], al    ; and store it.

    mov   rax, rdi                ; rest of original
    mov   rsp, rbp                ;    code here ...
    pop   rdx
    pop   rbp
    ret

Alternatively, you could leave the finishing code as-is and integrate the final transfer into your main loop, making it a do-X-while-condition rather than a while-condition-do-X:

strcpy_loop:
    mov   al, byte [rsi + rdx]
    mov   byte [rdi + rdx], al
    inc   rdx
    cmp   al, 0
    jne   strcpy_loop

    mov   rax, rdi                ; rest of original
    mov   rsp, rbp                ;    code here ...
    pop   rdx
    pop   rbp
    ret
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953