- 1、.eh_frame信息中cie的Augmentation字段为空:
Oracle Linux 6.5
# readelf -wf oracle | more Contents of the .eh_frame section: 00000000 00000014 00000000 CIE Version: 1 Augmentation: "" Code alignment factor: 1 Data alignment factor: -8 Return address column: 16
正常为”zR”:
$ readelf -wf /usr/sbin/sshd Contents of the .eh_frame section: 00000000 0000000000000014 00000000 CIE Version: 1 Augmentation: "zR"
- 2、elf段的加载地址不为0:
Oracle Linux 6.5
Address - Offset = loadoffset = 0x00000035fb15aaec - 0x0015aaec # readelf -S /lib64/libc-2.12.so There are 78 section headers, starting at offset 0x1d6140: Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [17] .eh_frame_hdr PROGBITS 00000035fb15aaec 0015aaec 00000000000065ec 0000000000000000 A 0 0 4 [18] .eh_frame PROGBITS 00000035fb1610d8 001610d8 0000000000025994 0000000000000000 A 0 0 8
计算时补偿loadoffset:
int unw_get_unwind(...) { rva += module_unwinds->elf_load_offset; }
一般系统下,Address – Offset = 0 = 0x000000000018e8fc – 0x0018e8fc
$ readelf -S /lib64/libc-2.17.so There are 76 section headers, starting at offset 0x20d380: Section Headers: [Nr] Name Type Address Offset Size EntSize Flags Link Info Align [19] .eh_frame_hdr PROGBITS 000000000018e8fc 0018e8fc 0000000000006acc 0000000000000000 A 0 0 4 [20] .eh_frame PROGBITS 00000000001953c8 001953c8 000000000002a3c4 0000000000000000 A 0 0 8
- 3、elf的一个segment被映射到多个vma:
centos 7.7 :
$ fc-ctl cp add /usr/lib64/firefox/firefox $ fc-ctl cp enable
根据vma的vm_pgoff来计算pc在section中的偏移:
int unw_get_unwind(...) { if(vma && ip > vm->vm_start) rva = ip -vm->vm_start + (vm->vm_pgoff * _PAGE_SIZE); }
- 4、libc更新以后,某些进程还继续使用的是旧的libc,这些文件被标注成deleted
升级libc,centos7.7:
yum install glibc-devel.i686 libgcc.i686
把unwind cache的主key值由path改为uuid,这样可以同时存储两份同名的unwind信息。
- 5、unwind fde信息中有 length为0的情况,造成item rbtree中有两个相同pc值的情况
32bit的ld:
$ readelf -wF ~/fc/ld-2.17.so 00001648 0000001c 0000164c FDE cie=00000000 pc=00015ea0..00015ebe LOC CFA ra 00015ea0 esp+4 c-4 00015ea0 esp+12 c-4 00015ea1 esp+16 c-4 00015ea2 esp+20 c-4 00015ea3 esp+24 c-4 00015eb1 esp+20 c-4
修改:
static void computed_state(...) { /* 在调试中发现unwind信息中有pc重复的情况会造成红黑树中存在两个key值相同的节点,造成查找出错。 这里丢弃掉length=0的节点 例如: readelf -wF /home/ipu/fc/ld-2.17.so (32位系统) 00001648 0000001c 0000164c FDE cie=00000000 pc=00015ea0..00015ebe LOC CFA ra 00015ea0 esp+4 c-4 00015ea0 esp+12 c-4 */ if (0 == unwind.base.length) return; }
- 6、clone 函数 unwind信息被分成两段的调试
centos7.7:
$ ps -ef | grep rsyslogd root 1740 1 0 05:00 ? 00:01:33 /usr/sbin/rsyslogd -n $ sudo service rsyslog stop $ gdb /usr/sbin/rsyslogd $ b main $ r -n $ b clone $ c $ ni $ b *0x7ffff6aa4851 $ ni
规避修改:
int unw_get_unwind(...) { _read_lock(&_r_unwind_lock); u = (unwind_item_t *)sym_search_by_range(&module_unwinds->root, rva-5) ; _read_unlock(&_r_unwind_lock); _trAssert_return(!u, (*state = &u->state, _SUCCESS)) ; }
- 7、unwind expression需要计算
32bit elf取栈
- 8、unwind信息中的所有指令为nop
[ipu@localhost code]$ md5sum /usr/lib64/libc-2.17.so 0b612f0ec4bed223ca59e4172 /usr/lib64/libc-2.17.so [ipu@localhost code]$ md5sum /usr/lib/systemd/systemd-journald 1abe893e8cbd2bf8053e205f81fff479 /usr/lib/systemd/systemd-journald [ipu@localhost code]$ - [ Stack Info ] : - [Depth] [Result] [VA] [RVA] [Sym] [Img] 0 0 7F432CA4B5C7 F75C7 ftruncate64+7 /usr/lib64/libc-2.17.so 1 55F33FB8F1A8 C1A8 sub_B1E0+FC8 /usr/lib/systemd/systemd-journald 2 55F33FB91A3F EA3F sub_E880+1BF /usr/lib/systemd/systemd-journald - [Stack API] : ftruncate64+7(F75C7)
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/207094.html原文链接:https://javaforall.net
