gdb反向调试avx2 [英] gdb reverse debugging avx2

查看:256
本文介绍了gdb反向调试avx2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有一个支持avx2指令集的新型花式CPU。
这很好,但打破了gdb反向调试。当没有优化编译时,代码仍然使用共享库,例如调用memset(),然后调用memset的avx2优化版本。这很棒,但是gdb记录不支持avx2。



进程记录不支持地址0x7ffff690dd80的指令0xc5。



0xc5是vex前缀。



反向调试对于不支持avx2的cpu很有效。我如何获得libc等不使用avx2优化版本的库调用,所以我可以使用gdb记录,倒退等?



我试过了

  LD_BIND_NOW = 1 
LD_HWCAP_MASK = 0
使用-static编译

在旧机器上进行调试时,我不知道该如何解决。

解决方案

对于在ubuntu 16.04 amd64上发布的glibc 2.23,我的二进制kludge(1 bit补丁) 完全出于同样的原因。软件包 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

有代码 get_common_indeces 0,... __ get_cpu_features 调用。 EAX = cpuid的7个页面有检测AVX2支持并启用它的所有信息,所以我只用 cpuid eax = 0x7,ecx = 0 并通过更改 <$ c将结果保存到内存的某些部分$ c> 0x7e 0x21 转换为 0x7f 0x21

该二进制补丁类似于将 83替换为<$ c $(其中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。



如果您的root fs可能以CPU启动,且没有eax = 7 cpuid叶支持(英特尔酷睿CPU之前)或者在虚拟机中模拟这样的英特尔核心CPU(Pentium D 8xx / 9xx),您可以将修补文件放在名称长度等于或小于原始路径< /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工具 patchelf code> 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
#或任何其他十六进制编辑器

patchelf --set-interpreter /lib_x86_64-linux-gnu_ld-linux-no-AVX2.so.2 ./my_program


So I have a new fancy cpu that supports avx2 instruction set. This is great, but breaks gdb reverse debugging. When compiling with no optimisations code still uses shared libraries, eg calls memset() which then goes and invokes an avx2 optimised version of memset. This is great but avx2 is not supported by gdb record.

process record does not support instruction 0xc5 at address 0x7ffff690dd80.

0xc5 is the vex prefix here.

reverse debugging works great with a cpu that does not support avx2. How do I get libc etc to not use the avx2 optimised versions of library calls so I can use gdb record, step backwards etc?

I've tried

LD_BIND_NOW=1
LD_HWCAP_MASK=0
compiling with -static

And short of debugging on an old machine, I'm out of ideas.

解决方案

For your glibc 2.23 as shipped on ubuntu 16.04 amd64 there is adaptation of my binary kludge (1 bit patch) made exactly for the same reason. Package libc6 (2.23-0ubuntu7) was downloaded from https://packages.ubuntu.com/xenial/amd64/libc6 and file ld-2.23.so was edited (keep copy of the original, or save patched into different path and change INTERP section of your own binary to use different path):

 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

There is code of 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.

So, the binary patch is like replacing 83 3D xx xx xx xx 06 7E xx B8 07 00 00 00 31 C9 0F A2 (where xx may be any byte) into 83 3D xx xx xx xx 06 7F xx B8 07 00 00 00 31 C9 0F A2. You may do this with any Hex Editor or by some binary diff. In 2.23-0ubuntu7 this code is at 0x0193B0 - 0x0193B9 is 7e to be changed into 7f.

The patch it dumb and don't use patched file globally if your root fs may be started with CPU without eax=7 cpuid leaf support (pre Intel Core CPU) or in virtual machine emulating such pre Intel Core CPU ("Pentium D 8xx/9xx", Pentium 4, Pentium M - will fail).

You may put patched file at path which name is equal in length or shorter to the original path of /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 (which symlinks into /lib/x86_64-linux-gnu/ld-2.23.so file). For example as /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2. Then use same hexeditor to replace the string "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2" of your program executable (ELF) into "/lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2", or use patchelf tool 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

这篇关于gdb反向调试avx2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆