【问题标题】:memcmp ignores characters at odd positionsmemcmp 忽略奇数位置的字符
【发布时间】:2018-06-16 16:40:21
【问题描述】:

我从 fasm(版本 1.71.51)代码调用memcmp,得到了奇怪的结果。

似乎memcmp 只比较位于奇数位置的字符。 代码:

format ELF64

section '.text' executable

    public _start

    extrn memcmp
    extrn exit

_start:
    push    rbp     ; Align the stack to 16 bytes

    mov     rdi, str1
    mov     rsi, str2
    mov     rdx, BUFF_LEN
    call    memcmp

    mov     rdi, rax
    call    exit
    pop     rbp


section '.data' writeable

str1                db '1509487271'
BUFF_LEN = $ - str1
str2                db '1509487273'

我正在运行 Ubuntu:

$ uname -a
Linux freedom 4.13.0-43-generic #48~16.04.1-Ubuntu SMP Thu May 17 12:56:46 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

为了组装和运行上面的代码,我使用了以下命令:

$ fasm strange_memcmp.asm && ld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -melf_x86_64 strange_memcmp.o -o strange_memcmp.out && ./strange_memcmp.out 
flat assembler  version 1.71.51  (16384 kilobytes memory)
3 passes, 803 bytes.
$ echo $?
0

我预计memcmp 将返回一个不是0 的值,因为缓冲区不同。

我尝试更改两个缓冲区。如果我设置:

str1 = '2509487271'
str2 = '1509487273'

我得到一个返回值 1。

如果我设置:

str1 = '1409487271'
str2 = '1509487273'

我得到一个返回值 0。 似乎 memcmp 只关心偶数位置的字符:0、2、4、...等。

我有一种奇怪的感觉,我错误地调用了 memcmp。这可能与 Linux x64 abi 有关,但我不知道可能是什么问题。任何想法表示赞赏!

编辑:根据 Raymond 的回答,该过程的返回值与掩码相加。

为了修复上面的代码,我添加了两条指令:

neg     rax
sbb     rax, rax

在拨打memcmp之后。

【问题讨论】:

  • 您的电话看起来正确。老实说,我不确定问题是什么。
  • 顺便说一句,堆栈在进入_start 时按 16 对齐。 push 会使它错位。它不是一个函数;所以它不同于通常的对齐前-call 情况。
  • 您使用的是什么 glibc 版本? 实际 memcmp 返回值是多少? (ltrace ./a.out 是一种简单的检查方法,或者使用strace 查看传递给sys_exit_group 的arg)。在我的 Arch Linux 系统上,我将您的代码移植到了 NASM。使用14094872711509487273,我得到memcmp 返回-1,所以我的进程退出状态是255。glibc memcmp 通过将字节扩展到int 并减去它们来返回,所以低字节是如果int 返回值非零,则始终非零。
  • @Peter Cordes:感谢 _start 的建议。我想确定我理解:我可以直接从 _start 调用 libc 函数,而无需对齐任何东西吗?我想我必须推送 8 字节大小的东西。

标签: assembly x86-64 fasm


【解决方案1】:

您将从memcmp 返回的64 位值直接传递给exit,但the value is ANDed with 0xFF before being returned to the parentmemcmp 可能返回一个非零值,例如 512,但系统会将其截断为 0。

【讨论】:

  • 你救了我的命!
猜你喜欢
  • 2012-07-14
  • 1970-01-01
  • 2012-11-28
  • 2021-08-17
  • 2015-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多