导出 IDA 符号 做逆向和 pwn 题时总会发现一些符号被stripped掉的ELF文件,使用GDB调试时由于没有符号导致识别困难而且断点麻烦, 这时候就想把IDA中识别到的或者用户自己定义的函数名(或者其他符号)导出到ELF文件的SYMTAB中,在Github上找到一个适用于 IDA 7.0 ~ 7.3 的插件 https://github.com/BlackVS/IDA-exportsymbols 做了一些小小的工作让其支持 IDA 7.4+ 并且优化了一下GUI界面:
https://github.com/FrnkPsycho/ida-exportsymbols
用法说明什么的都写在README里了
PWN 题环境准备 pwninit -> 将 xxx_patched 文件用 IDA 打开 -> 如果想要导入符号则使用上面提到的 exportsymbols
pwninit 之前:
1 2 3 4 > ldd hacknote linux-gate.so.1 (0xf7f2e000) libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7c00000) /lib/ld-linux.so.2 (0xf7f30000)
pwninit(如果文件夹下只有一个ELF和libc动态库则不需要带参数) 注意如果不要在VMware虚拟机的Windows共享文件夹下执行操作,否则symlink会失败(因为Windows的文件系统不支持Linux的软链接):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 > pwninit --bin hacknote bin: hacknote libc: ./libc_32.so.6 fetching linker https://launchpad.net/ubuntu/+archive/primary/+files//libc6_2.23-0ubuntu5_i386.deb unstripping libc https://launchpad.net/ubuntu/+archive/primary/+files//libc6-dbg_2.23-0ubuntu5_i386.deb eu-unstrip: cannot find matching section for [13] '.text' eu-unstrip: cannot find matching section for [14] '__libc_freeres_fn' eu-unstrip: cannot find matching section for [15] '__libc_thread_freeres_fn' eu-unstrip: cannot find matching section for [16] '.rodata' eu-unstrip: cannot find matching section for [17] '.stapsdt.base' eu-unstrip: cannot find matching section for [18] '.interp' eu-unstrip: cannot find matching section for [19] '.eh_frame_hdr' eu-unstrip: cannot find matching section for [20] '.eh_frame' eu-unstrip: cannot find matching section for [21] '.gcc_except_table' eu-unstrip: cannot find matching section for [22] '.hash' eu-unstrip: cannot find matching section for [23] '.tdata' eu-unstrip: cannot find matching section for [24] '.tbss' eu-unstrip: cannot find matching section for [25] '.init_array' eu-unstrip: cannot find matching section for [26] '__libc_subfreeres' eu-unstrip: cannot find matching section for [27] '__libc_atexit' eu-unstrip: cannot find matching section for [28] '__libc_thread_subfreeres' eu-unstrip: cannot find matching section for [29] '.data.rel.ro' eu-unstrip: cannot find matching section for [30] '.dynamic' eu-unstrip: cannot find matching section for [31] '.got' eu-unstrip: cannot find matching section for [32] '.got.plt' eu-unstrip: cannot find matching section for [33] '.data' eu-unstrip: cannot find matching section for [34] '.bss' warning: failed unstripping libc: eu-unstrip exited with failure: exit status: 1 setting ./ld-2.23.so executable symlinking ./libc.so.6 -> libc_32.so.6 copying hacknote to hacknote_patched running patchelf on hacknote_patched
遇到一些无法 unstrip libc 的情况一般不用管
将 xxx_patched
文件导入IDA,添加用户自定义的函数名称:
选择想要导出的段,保存为ELF文件。
使用GDB就能看到自定义的函数名了:
同时因为我们patch了ELF,用ldd看到libc已经指向了刚才生成的软链接:
1 2 3 4 > ldd hacknote_patched linux-gate.so.1 (0xf7ef8000) libc.so.6 => ./libc.so.6 (0xf7d3e000) ./ld-2.23.so => /lib/ld-linux.so.2 (0xf7efa000)
vmmap 发现libc/ld不再使用系统路径下的libc/ld:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 pwndbg> vmmap LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA Start End Perm Size Offset File 0x8046000 0x8048000 rw-p 2000 0 /home/frnks/temppwn/hacknote/hacknote_patched 0x8048000 0x8049000 r-xp 1000 2000 /home/frnks/temppwn/hacknote/hacknote_patched 0x8049000 0x804a000 r--p 1000 2000 /home/frnks/temppwn/hacknote/hacknote_patched 0x804a000 0x804b000 rw-p 1000 3000 /home/frnks/temppwn/hacknote/hacknote_patched 0xf7d84000 0xf7f31000 r-xp 1ad000 0 /home/frnks/temppwn/hacknote/libc_32.so.6 0xf7f31000 0xf7f32000 ---p 1000 1ad000 /home/frnks/temppwn/hacknote/libc_32.so.6 0xf7f32000 0xf7f34000 r--p 2000 1ad000 /home/frnks/temppwn/hacknote/libc_32.so.6 0xf7f34000 0xf7f35000 rw-p 1000 1af000 /home/frnks/temppwn/hacknote/libc_32.so.6 0xf7f35000 0xf7f3a000 rw-p 5000 0 [anon_f7f35] 0xf7f3a000 0xf7f3e000 r--p 4000 0 [vvar] 0xf7f3e000 0xf7f40000 r-xp 2000 0 [vdso] 0xf7f40000 0xf7f62000 r-xp 22000 0 /home/frnks/temppwn/hacknote/ld-2.23.so 0xf7f62000 0xf7f63000 rw-p 1000 0 [anon_f7f62] 0xf7f63000 0xf7f64000 r--p 1000 22000 /home/frnks/temppwn/hacknote/ld-2.23.so 0xf7f64000 0xf7f65000 rw-p 1000 23000 /home/frnks/temppwn/hacknote/ld-2.23.so 0xff7ee000 0xff80f000 rw-p 21000 0 [stack]
因为该题是libc 2.23,所以没有tcache,分配又释放发现chunk都在fastbins而非tcachebins:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 pwndbg> heap pwndbg will try to resolve the heap symbols via heuristic now since we cannot resolve the heap via the debug symbols. This might not work in all cases. Use `help set resolve-heap-via-heuristic` for more details. Free chunk (fastbins) | PREV_INUSE Addr: 0x91bf000 Size: 0x10 (with flag bits: 0x11) fd: 0x00 Free chunk (fastbins) | PREV_INUSE Addr: 0x91bf010 Size: 0x30 (with flag bits: 0x31) fd: 0x00 Free chunk (fastbins) | PREV_INUSE Addr: 0x91bf040 Size: 0x10 (with flag bits: 0x11) fd: 0x91bf000 Free chunk (fastbins) | PREV_INUSE Addr: 0x91bf050 Size: 0x30 (with flag bits: 0x31) fd: 0x91bf010 Top chunk | PREV_INUSE Addr: 0x91bf080 Size: 0x20f80 (with flag bits: 0x20f81) pwndbg> bins fastbins 0x10: 0x91bf040 —▸ 0x91bf000 ◂— 0x0 0x30: 0x91bf050 —▸ 0x91bf010 ◂— 0x0 unsortedbin empty smallbins empty largebins empty
提示 pwndbg will try to resolve the heap symbols via heuristic now since we cannot resolve the heap via the debug symbols.
是因为题目提供的libc一般不带调试符号,pwndbg 采用了一些技术推测出了堆相关数据的位置。如果没能推测出则可以通过下载对应glibc版本并导入 .debug
文件夹,具体参考: https://www.cnblogs.com/9man/p/17741818.html `
gdb 我用的是 pwngdb 环境,下载pwndbg和Pwngdb,将 ~/.gdbinit
的内容改为如下即可,注意更改路径。
1 2 3 4 5 6 7 8 9 10 11 12 13 > cat ~/.gdbinit source ~/pwndbg/gdbinit.py source ~/Pwngdb/pwngdb.py source ~/Pwngdb/angelheap/gdbinit.py set disable-randomization on #set follow-fork-mode child define hook-run python import angelheap angelheap.init_angelheap() end