我有意在我的代码中生成了SIGSEGV以学习在各种实用程序下调试它,例如 catchsegv , gdb , valgrind & PMAP 。我故意在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()调用&amp;之前使用PROT_READ进行READ。 memcpy()尝试在其上写入内容,从而出现SEGFAULT。
使用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寄存器中写入?
感谢任何帮助。如果需要更多信息,请告诉我。
答案 0 :(得分:0)
RDI
是作为目的地传递给memcpy
的参数。在您的情况下,似乎在映射区域中偏移2。您没有提供您使用的memcpy
电话。
CL
保存源内存区域的第一个字节,它已由故障前面的指令加载:movzbl (%rsi),%ecx
。我假设您知道CL
是ECX
的低8位(而RCX
的低32位)。