GCC:在 GCC 版本之间伪装

Posted

技术标签:

【中文标题】GCC:在 GCC 版本之间伪装【英文标题】:GCC: disguising between GCC versions 【发布时间】:2012-03-29 15:48:36 【问题描述】:

这个问题来自this question。

问题是Linux 有一个NVidia 驱动程序,用GCC 4.5 编译。 kernel 是用 GCC 4.6 编译的。好吧,由于GCCs 之间的版本号差异,这些东西不起作用。 (安装程序说驱动程序不起作用 - 详细信息请访问上面的链接)

可以将使用GCC 4.5 编译的二进制文件伪装成使用GCC 4.6 编译的二进制文件吗?如果可以,在什么情况下会好用?

【问题讨论】:

在拒绝加载或崩溃或...时不起作用? 为什么不用 GCC 4.5 重新编译内核? 让我提一下,原来的问题不是我的。安装程序说版本不合适。我在 UNIX/Linux 站点上建议重新编译内核,但我很好奇没有它如何解决问题。将其视为一个抽象问题:如果我们将它伪装成 $progname.$gccversion2,那么 $progname.$gccversion1 什么时候可以工作? 【参考方案1】:

您的问题称为 ABI:应用程序二进制接口。这是一组规则(除其他外),一段代码中的函数如何获取其参数(排序、堆栈上类型的填充)、函数命名,以便链接器可以解析符号和结构中字段的填充/对齐。

GCC 试图在编译器版本之间保持 ABI 稳定,但这并不总是可行的。

例如,GCC 4.4 fixed a bug in packed bit-fields 这意味着旧/新代码无法再使用此功能正确读取结构。如果您将 4.4 之前和之后的版本混合使用,则会发生数据损坏而不会崩溃。

在 4.6 发行说明中没有迹象表明 ABI 已更改,但这是 Linux 内核无法知道的 - 它只是读取用于编译代码的编译器版本,如果前两个数字发生更改,它假定运行代码是不安全的。

有两种解决方案:

    您可以使用与内核相同的编译器来编译 Nvidia 驱动程序。 强烈推荐

    您可以修补二进制文件中的版本字符串。这将欺骗内核加载模块,但有可能导致内部数据结构数据损坏。

【讨论】:

是内核和驱动编译成相同的gcc版本更重要,还是驱动和程序编译更重要,还是三者都需要相同? 这三个都使用相同的 ABI 编译,这一点很重要。您可以毫无问题地使用 4.6 编译内核和使用 4.7 编译程序。

以上是关于GCC:在 GCC 版本之间伪装的主要内容,如果未能解决你的问题,请参考以下文章

爱伪装更新了吗

修改NGINX版本名称伪装任意

爱伪装有些啥功能

常见伪装IP的方法有几种

Ubuntu下多个gcc版本之间的切换

tomcat安全优化