0

我故意在我的代码中生成了 SIGSEGV,以学习在各种实用程序下调试它,例如catchsegvgdbvalgrindpmap。我故意在mmap'ed文件上使用了memcpy(),该文件具有由mprotect()设置的PROT_READ标志。现在,当我在 gdb 下调试它时,我无法从汇编输出中得出任何结论。我是组装的新手。

细节 -

记忆的东西:

    (gdb) x/35i 0x00002aaaaad55500
    0x2aaaaad55500 <memccpy+32>: jne    0x2aaaaad554e8 <memccpy+8>
    0x2aaaaad55502 <memccpy+34>: mov    %rdi,%rax
    0x2aaaaad55505 <memccpy+37>: retq
    0x2aaaaad55506 <memccpy+38>: nopw   %cs:0x0(%rax,%rax,1)
    0x2aaaaad55510 <memccpy+48>: xor    %eax,%eax
    0x2aaaaad55512 <memccpy+50>: retq
    0x2aaaaad55513:      nop
    0x2aaaaad55514:      nop
    0x2aaaaad55515:      nop
    0x2aaaaad55516:      nop
    0x2aaaaad55517:      nop
    0x2aaaaad55518:      nop
    0x2aaaaad55519:      nop
    0x2aaaaad5551a:      nop
    0x2aaaaad5551b:      nop
    0x2aaaaad5551c:      nop
    0x2aaaaad5551d:      nop
    0x2aaaaad5551e:      nop
    0x2aaaaad5551f:      nop
    0x2aaaaad55520 <__memcpy_chk>:       cmp    %rdx,%rcx
    0x2aaaaad55523 <__memcpy_chk+3>:     jb     0x2aaaaadcb590 <__chk_fail>
    0x2aaaaad55529:      nopl   0x0(%rax)
    0x2aaaaad55530 <memcpy>:     cmp    $0x20,%rdx
    0x2aaaaad55534 <memcpy+4>:   mov    %rdi,%rax
    0x2aaaaad55537 <memcpy+7>:   jae    0x2aaaaad555b0 <memcpy+128>
    0x2aaaaad55539 <memcpy+9>:   test   $0x1,%dl
    0x2aaaaad5553c <memcpy+12>:  je     0x2aaaaad55549 <memcpy+25>
    0x2aaaaad5553e <memcpy+14>:  movzbl (%rsi),%ecx
    => 0x2aaaaad55541 <memcpy+17>:  mov    %cl,(%rdi)
    0x2aaaaad55543 <memcpy+19>:  inc    %rsi
    0x2aaaaad55546 <memcpy+22>:  inc    %rdi
    0x2aaaaad55549 <memcpy+25>:  test   $0x2,%dl
    0x2aaaaad5554c <memcpy+28>:  je     0x2aaaaad55560 <memcpy+48>
    0x2aaaaad5554e <memcpy+30>:  movzwl (%rsi),%ecx
    0x2aaaaad55551 <memcpy+33>:  mov    %cx,(%rdi)

如您所见,SEGFAULT 发生在指令 0x2aaaaad55541 处,这也在 64 位指令指针寄存器 RIP 中指示。

寄存器:

    (gdb) info registers
    rax            0x2aaaaaacf002   46912496267266
    rbx            0x40146a 4199530
    rcx            0x69     105
    rdx            0x1      1
    rsi            0x40146a 4199530
    rdi            0x2aaaaaacf002   46912496267266
    rbp            0x7      0x7
    rsp            0x7fffffffe468   0x7fffffffe468
    r8             0x40146a 4199530
    r9             0x53202c444145525f       5989836176067220063
    r10            0x7fffffffe1f0   140737488347632
    r11            0x2aaaaad55530   46912498914608
    r12            0x2aaaab05eac8   46912502098632
    r13            0x7fffffffe5a0   140737488348576
    r14            0x7fffffffe590   140737488348560
    r15            0x2aaaaaacf000   46912496267264
    rip            0x2aaaaad55541   0x2aaaaad55541 <memcpy+17>
    eflags         0x10202  [ IF RF ]
    cs             0x33     51
    ss             0x2b     43
    ds             0x0      0
    es             0x0      0
    fs             0x0      0
    gs             0x0      0

过程映射:

下面是 gdb 中“info proc mappings”命令的输出。

    [excerpt]
    0x2aaaaaacf000     0x2aaaaaad0000     0x1000          0             /tmp/dst_file
    [/excerpt]

/tmp/dst_file 使用 mmap() 映射到内存中,并在 memcpy() 调用和 memcpy() 尝试在其上写入内容并因此出现 SEGFAULT 之前使用 PROT_READ 将其设为只读。

使用的 Memcpy() 调用:

    memcpy (mmap_start + myfilestat1.st_size, str1, strlen(str1))

mmap_start 是起始地址,myfilestat1.st_size 是新的截断文件大小。str1 是要附加到文件的字符串。

这是我的源代码的一点流程-

    1. Fstat original size of file 
    2. Set Offset of file to grow depending upon strlen() of string to append 
    3. Ftruncate() to grow file size 
    4. Fstat new file size. 
    5. Mmap the newly truncated file 
    6. If segmentation fault need to be generated, call mprotect() to convert to PROT_READ. 
    7. Memcpy() with Orignal fstat size to append contents to text file. 

问题 -

现在我无法理解的是

    0x2aaaaad55541 <memcpy+17>:  mov    %cl,(%rdi)

这条指令到底是做什么的?RDI寄存器包含映射到开始写入的文件的结束地址,为什么RDI地址的值被写入CX寄存器?

任何帮助表示赞赏。如果需要更多信息,请告诉我。

4

1 回答 1

1

RDImemcpy是作为目标传递给的参数。在您的情况下,映射区域中的偏移量似乎为 2。你没有提供memcpy你使用的电话。

CL保存源内存区域的第一个字节,它已被直接在错误之前的指令加载:movzbl (%rsi),%ecx. 我假设您知道这CL是 的低 8 位ECX(又是 的低 32 位RCX)。

于 2013-10-03T12:18:40.520 回答