gdb 反向调试 avx2
gdb reverse debugging avx2
所以我有一个新奇的 cpu 支持 avx2 指令集。
这很好,但是会破坏 gdb 反向调试。在没有优化的情况下编译时,代码仍然使用共享库,例如调用 memset(),然后调用 memset 的 avx2 优化版本。这很好,但 gdb 记录不支持 avx2。
进程记录不支持地址 0x7ffff690dd80 处的指令 0xc5。
0xc5是这里的vex前缀
反向调试对不支持 avx2 的 cpu 效果很好。如何让 libc 等不使用库调用的 avx2 优化版本,以便我可以使用 gdb 记录、后退等?
我试过了
LD_BIND_NOW=1
LD_HWCAP_MASK=0
compiling with -static
而且没有在旧机器上调试,我没有想法。
对于 ubuntu 16.04 amd64 上发布的 glibc 2.23,有 made exactly for the same reason. Package libc6 (2.23-0ubuntu7)
was downloaded from https://packages.ubuntu.com/xenial/amd64/libc6 的改编和文件 ld-2.23.so 已编辑(保留原件的副本,或保存修补到不同的路径并更改您自己的二进制文件的 INTERP 部分以使用不同的路径):
83 3D 5B C9 20 00 06 cmpl [=10=]x6, smth...
7E 21 jle some_forward_label
B8 07 00 00 00 mov [=10=]x7, %eax
31 C9 xor %ecx,%ecx
0F A2 cpuid
有the get_common_indeces
: if (cpu_features->max_cpuid >= 7) __cpuid_count (7, 0, ...
called from __get_cpu_features
. EAX=7 leaf of cpuid has all info needed to detect AVX2 support and enable it, so I just skipped fragment with cpuid eax=0x7,ecx=0
and saving its results into some parts of memory by changing 0x7e 0x21
into 0x7f 0x21
的代码。
因此,二进制补丁就像将 83 3D xx xx xx xx 06 7E xx B8 07 00 00 00 31 C9 0F A2
(其中 xx 可以是任何字节)替换为 83 3D xx xx xx xx 06 7F xx B8 07 00 00 00 31 C9 0F A2
。您可以使用任何十六进制编辑器或某些二进制差异来执行此操作。在 2.23-0ubuntu7 中,此代码位于 0x0193B0 - 0x0193B9 是 7e,将更改为 7f。
如果你的根 fs 可能以 CPU 启动而没有 eax=7 cpuid 叶支持(pre Intel Core CPU)或在虚拟中,则补丁是愚蠢的并且不要全局使用补丁文件模拟此类预英特尔酷睿的机器 CPU ("Pentium D 8xx/9xx", Pentium 4, Pentium M - will fail).
您可以将补丁文件放在名称长度等于或短于 /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
原始路径(符号链接到 /lib/x86_64-linux-gnu/ld-2.23.so
文件)的路径中。例如 /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
。然后使用相同的 hexeditor 将程序可执行文件 (ELF) 的字符串“/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2”替换为“/lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2”,或使用 patchelf 工具 from the patchelf
package:
cp /lib/x86_64-linux-gnu/ld-2.23.so /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
bless /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
# or any other hex editor
patchelf --set-interpreter /lib_x86_64-linux-gnu_ld-linux-no-AVX2.so.2 ./my_program
所以我有一个新奇的 cpu 支持 avx2 指令集。 这很好,但是会破坏 gdb 反向调试。在没有优化的情况下编译时,代码仍然使用共享库,例如调用 memset(),然后调用 memset 的 avx2 优化版本。这很好,但 gdb 记录不支持 avx2。
进程记录不支持地址 0x7ffff690dd80 处的指令 0xc5。
0xc5是这里的vex前缀
反向调试对不支持 avx2 的 cpu 效果很好。如何让 libc 等不使用库调用的 avx2 优化版本,以便我可以使用 gdb 记录、后退等?
我试过了
LD_BIND_NOW=1
LD_HWCAP_MASK=0
compiling with -static
而且没有在旧机器上调试,我没有想法。
对于 ubuntu 16.04 amd64 上发布的 glibc 2.23,有 libc6 (2.23-0ubuntu7)
was downloaded from https://packages.ubuntu.com/xenial/amd64/libc6 的改编和文件 ld-2.23.so 已编辑(保留原件的副本,或保存修补到不同的路径并更改您自己的二进制文件的 INTERP 部分以使用不同的路径):
83 3D 5B C9 20 00 06 cmpl [=10=]x6, smth...
7E 21 jle some_forward_label
B8 07 00 00 00 mov [=10=]x7, %eax
31 C9 xor %ecx,%ecx
0F A2 cpuid
有the get_common_indeces
: if (cpu_features->max_cpuid >= 7) __cpuid_count (7, 0, ...
called from __get_cpu_features
. EAX=7 leaf of cpuid has all info needed to detect AVX2 support and enable it, so I just skipped fragment with cpuid eax=0x7,ecx=0
and saving its results into some parts of memory by changing 0x7e 0x21
into 0x7f 0x21
的代码。
因此,二进制补丁就像将 83 3D xx xx xx xx 06 7E xx B8 07 00 00 00 31 C9 0F A2
(其中 xx 可以是任何字节)替换为 83 3D xx xx xx xx 06 7F xx B8 07 00 00 00 31 C9 0F A2
。您可以使用任何十六进制编辑器或某些二进制差异来执行此操作。在 2.23-0ubuntu7 中,此代码位于 0x0193B0 - 0x0193B9 是 7e,将更改为 7f。
如果你的根 fs 可能以 CPU 启动而没有 eax=7 cpuid 叶支持(pre Intel Core CPU)或在虚拟中,则补丁是愚蠢的并且不要全局使用补丁文件模拟此类预英特尔酷睿的机器 CPU ("Pentium D 8xx/9xx", Pentium 4, Pentium M - will fail).
您可以将补丁文件放在名称长度等于或短于 /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
原始路径(符号链接到 /lib/x86_64-linux-gnu/ld-2.23.so
文件)的路径中。例如 /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
。然后使用相同的 hexeditor 将程序可执行文件 (ELF) 的字符串“/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2”替换为“/lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2”,或使用 patchelf 工具 from the patchelf
package:
cp /lib/x86_64-linux-gnu/ld-2.23.so /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
bless /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
# or any other hex editor
patchelf --set-interpreter /lib_x86_64-linux-gnu_ld-linux-no-AVX2.so.2 ./my_program