所以我有一个新的花哨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
Run Code Online (Sandbox Code Playgroud)
如果没有在旧机器上调试,我就没有想法了.
对于 ubuntu 16.04 amd64 上附带的 glibc 2.23,我的二进制 kludge(1 位补丁)的改编完全是出于同样的原因。软件包libc6 (2.23-0ubuntu7)是从https://packages.ubuntu.com/xenial/amd64/libc6下载的,并编辑了文件 ld-2.23.so(保留原始文件的副本,或将修补后的文件保存到不同的路径中,并将您自己的二进制文件的 INTERP 部分更改为使用不同的路径):
83 3D 5B C9 20 00 06 cmpl $0x6, smth...
7E 21 jle some_forward_label
B8 07 00 00 00 mov $0x7, %eax
31 C9 xor %ecx,%ecx
0F A2 cpuid
Run Code Online (Sandbox Code Playgroud)
有代码:get_common_indeces调用if (cpu_features->max_cpuid >= 7) __cpuid_count (7, 0, ...from __get_cpu_features。cpuid 的 EAX=7 叶子包含检测 AVX2 支持并启用它所需的所有信息,因此我只是跳过片段cpuid eax=0x7,ecx=0并将其结果更改0x7e 0x21为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。
如果您的根文件系统可能是在没有 eax=7 cpuid leaf 支持的情况下(预 Intel Core CPU)或在模拟此类预 Intel Core CPU 的虚拟机中启动的 CPU(“Pentium D 8xx / 9xx"、Pentium 4、Pentium M - 将失败)。
您可以将修补文件放在名称长度等于或小于原始路径/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. 然后使用相同的十六进制编辑器将程序可执行文件(ELF)的字符串“/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2”替换为“/lib_x86_64-linux-gnu_ld-linux-noAVX2”。 so.2”,或使用包中的patchelfpatchelf 工具:
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
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
839 次 |
| 最近记录: |