栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

禁用glibc(LD_HWCAP_MASK,/ etc / ld.so.nohwcap)中的AVX优化函数以用于valgrind和gdb记录

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

禁用glibc(LD_HWCAP_MASK,/ etc / ld.so.nohwcap)中的AVX优化函数以用于valgrind和gdb记录

似乎没有直接的运行时方法来修补特征检测。此检测发生在动态链接器(ld.so)的早期。

目前,对链接程序进行二进制修补似乎是最简单的方法。@osgx描述了一种覆盖跳转的方法。另一种方法是伪造cpuid结果。通常,在寄存器ebx,ecx和edx
中返回制造商ID的同时,

cpuid(eax=0)
返回支持的最高功能。我们在glibc
2.25中有以下代码片段:
eax
sysdeps/x86/cpu-features.c

__cpuid (0, cpu_features->max_cpuid, ebx, ecx, edx);if (ebx == 0x756e6547 && ecx == 0x6c65746e && edx == 0x49656e69)  {        }else  {    kind = arch_kind_other;    get_common_indeces (cpu_features, NULL, NULL, NULL, NULL);  }

__cpuid
行将转换为
/lib/ld-linux-x86-64.so.2
/lib/ld-2.25.so
)中的这些说明:

172a8:       31 c0        xor    eax,eax172aa:       c7 44 24 38 00 00 00    mov    DWORD PTR [rsp+0x38],0x0172b1:       00 172b2:       c7 44 24 3c 00 00 00    mov    DWORD PTR [rsp+0x3c],0x0172b9:       00 172ba:       0f a2        cpuid

因此,除了修补分支之外,我们还可以将更

cpuid
改为一条
nop
指令,该指令将导致最后一个
else
分支的调用(因为寄存器将不包含“
GenuineIntel”)。由于最初的
eax=0
cpu_features->max_cpuid
也将为0,
if(cpu_features->max_cpuid >= 7)
也将被绕过。

二进制补丁

cpuid(eax=0)
通过
nop
这个可以用这个工具来完成(x86和x86-64的作品):

#!/usr/bin/env pythonimport reimport sysinfile, outfile = sys.argv[1:]d = open(infile, 'rb').read()# Match CPUID(eax=0), "xor eax,eax" followed closely by "cpuid"o = re.sub(b'(x31xc0.{0,32}?)x0fxa2', b'\1x66x90', d)assert d != oopen(outfile, 'wb').write(o)

等效的Perl变体

-0777
可确保立即读取文件,而不是在换行符处分开记录:

perl -0777 -pe 's/x31xc0.{0,32}?Kx0fxa2/x66x90/' < /lib/ld-linux-x86-64.so.2 > ld-linux-x86-64-patched.so.2# Verify result, should display "Success"cmp -s /lib/ld-linux-x86-64.so.2 ld-linux-x86-64-patched.so.2 && echo 'Not patched' || echo Success

那是容易的部分。现在,我不想替换系统范围内的动态链接器,而是仅使用此链接器执行一个特定程序。当然,可以使用来完成

./ld-linux-x86-64-patched.so.2 ./a
,但是朴素的gdb调用无法设置断点:

$ gdb -q -ex "set exec-wrapper ./ld-linux-x86-64-patched.so.2" -ex start ./aReading symbols from ./a...done.Temporary breakpoint 1 at 0x400502: file a.c, line 5.Starting program: /tmp/a During startup program exited normally.(gdb) quit$ gdb -q -ex start --args ./ld-linux-x86-64-patched.so.2 ./aReading symbols from ./ld-linux-x86-64-patched.so.2...(no debugging symbols found)...done.Function "main" not defined.Temporary breakpoint 1 (main) pending.Starting program: /tmp/ld-linux-x86-64-patched.so.2 ./a[Inferior 1 (process 27418) exited normally](gdb) quit

如何使用自定义elf解释器调试程序中介绍了手动解决方法。它可以工作,但是很遗憾,它是使用的手动操作

add-symbol-file
。不过,应该可以使用GDB捕捉点将其自动化。

一点不二进制链接是一种替代方法

LD_PRELOAD
荷兰国际集团,它定义了自定义程序库
memcpy
memove
等等。这一操作将优先于glibc的程序。功能的完整列表在中提供
sysdeps/x86_64/multiarch/ifunc-impl-list.c
。与glibc 2.25发行版相比,当前的HEAD具有更多的符号,总计(
grep -Po 'IFUNC_IMPL(i, name, K[^,]+' sysdeps/x86_64/multiarch/ifunc-impl-list.c
):

memchr,memcmp, memmove_chk,memmove,memrchr,
memset_chk,memset,rawmemchr,strlen,strnlen,stpncpy,stpcpy,strcasecmp,strcasecmp_l,strcat,strchr,strchpyuln,strrchr,strcmp,strcmpn,strcatnc,
strpbrk,strspn,strstr,wcschr,wcsrchr,wcscpy,wcslen,wcsnlen,wmemchr,wmemcmp,wmemset,
memcpy_chk,memcpy,
mempcpy_chk,mempcpy,strncmp,__ wmemset_chk,



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/370756.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号