破译简单的汇编代码:是strcpy还是strcat?

问题描述 投票:0回答:1
1  .text
2  .globl mystery
3  .type mystery, @function

4  mystery:
5  movq %rdi, %rax
6  movq %rdi, %rdx
7  cmpb $0, (%rdi)
8  je .L5

9  .L3:
10 addq $1, %rdx
11 cmpb $0, (%rdx)
12 jne .L3

13 .L5:
14 addq $1, %rsi
15 movb -1(%rsi), %cl
16 addq $1, %rdx
17 movb %cl, -1(%rdx)
18 cmpb $0, %cl
19 jne .L5

20 ret

我真的很困惑这个。它是 strcpy 还是 strcat 的实现。另外,我知道第一个循环搜索字符串的空终止符,第二个循环执行相同的操作但也复制了字符串,但我很难理解整个函数在做什么. 它是将存储在 %rdi 的字符串复制到另一个位置(strcpy)还是将存储在 %rsi 的字符串添加到 %rdi 的末尾(strcat)。

assembly x86-64 reverse-engineering
1个回答
2
投票

带有伪C注释

1  .text
2  .globl mystery
3  .type mystery, @function

4  mystery:
5  movq %rdi, %rax      # rax = rdi
6  movq %rdi, %rdx      # rdx = rdi
7  cmpb $0, (%rdi)      # *(char*)rdi == 0 ?
8  je .L5               # Jump if equal (zero)

9  .L3:
10 addq $1, %rdx        # ++rdx
11 cmpb $0, (%rdx)      # *(char*)rdx == 0?
12 jne .L3              # Jump if not equal (non zero)

13 .L5:
14 addq $1, %rsi        # ++rsi
15 movb -1(%rsi), %cl   # cl = *((char*)rsi - 1)
16 addq $1, %rdx        # ++rdx
17 movb %cl, -1(%rdx)   # *((char*)rdx - 1) = cl
18 cmpb $0, %cl         # Is cl == 0 ?
19 jne .L5              # Jump if not equal

20 ret

所以重写成C代码:

char* func(char* rsi, char *rdi) {
    char *dest = rdi;   // rdx 
    char *src  = rsi;   // rsi
    char c;

    // Find first '\0'
    if (*dest != 0)
        while (*++dest != 0)
            ;

    // Copy from src until '\0' reached
    do {
        c = *src++;
        *dest++ = c;
    } while (c != 0)

    return rdi; // rax
}

所以我们看到这是

strcat()
,因为它先跳过现有的字符串,然后复制。

© www.soinside.com 2019 - 2024. All rights reserved.