当前位置: 首页 > 面试题库 >

编译一个静态二进制文件,该代码中有一个函数gethostbyname

孔正文
2023-03-14
问题内容

如何解析编译静态二进制文件,其中的代码包含函数gethostbyname,并且如果编译时未发出如下警告:

警告:在静态链接的应用程序中使用’gethostbyname’要求在运行时需要glibc版本中用于链接的共享库

我用命令在ubuntu 12.04上编译:

$ gcc -static lookup.c -o lookup

这是lookup.c的代码:

  /* lookup.c */

  #include <stdio.h>
  #include <unistd.h>
  #include <stdlib.h>
  #include <string.h>
  #include <errno.h>
  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <netdb.h>

  extern int h_errno;

  int main(int argc,char **argv) {
     int x, x2;
     struct hostent *hp;

     for ( x=1; x<argc; ++x ) {
        hp = gethostbyname(argv[x]);
        if ( !hp ) {
           fprintf(stderr,
                   "%s: host '%s'\n",
                   hstrerror(h_errno),
                   argv[x]);
           continue;
        }

        printf("Host %s : \n" ,argv[x]);
        printf(" Officially:\t%s\n", hp->h_name);
        fputs(" Aliases:\t",stdout);
        for ( x2=0; hp->h_aliases[x2]; ++x2 ) {
           if ( x2 ) {
              fputs(", ",stdout);
             }
        fputs(hp->h_aliases[x2],stdout);
        }     
        fputc('\n',stdout);
        printf(" Type:\t\t%s\n",
               hp->h_addrtype == AF_INET
               ? "AF_INET" : "AF_INET6");
        if ( hp->h_addrtype == AF_INET ) {
           for ( x2=0; hp->h_addr_list[x2]; ++x2 ) {
              printf(" Address:\t%s\n",
                     inet_ntoa( *(struct in_addr *)
                      hp->h_addr_list[x2]));
           }
        }
     putchar('\n');
     }
     return 0;
  }

我想检查是否$ file lookup将获得如下输出:

查找:ELF 32位LSB可执行文件,Intel 80386版本1(GNU / Linux),静态链接,用于GNU / Linux
2.6.24,BuildID [sha1] = 0x6fcb2684ad8e5e842036936abb50911cdde47c73(未剥离)

不是这样的:

查找:ELF 32位LSB可执行文件,Intel 80386版本1(SYSV),动态链接(使用共享库),用于GNU / Linux
2.6.24,BuildID [sha1] = 0xf9f18671751927bea80de676d207664abfdcf5dc(未剥离)

如果您建议使用注释,则我必须不使用static,因为我知道的每个Linux都使用不同的libc,希望您无需注释。为什么我坚持静态?因为我需要强制使用静态文件,所以二进制文件必须是静态文件,而不是动态文件。

我有2个多星期的时间在寻找这个,但到目前为止还没有成功。

感谢您帮助我解决我的重任。


问题答案:

您要的将非常困难。

。基本上,getaddrinfo/之下gethostbyname是glibc的NSS层。这使系统管理员可以说“使用DNS将主机名解析为IP地址”,或“使用LDAP”,或“不使用除/etc/hosts”以外的任何内容。该控件在运行时;sysadmin可以随时更改将主机名解析为IP的方式。

由于这种灵活性,glibc中的所有名称解析调用都使用帮助程序库(基本上是插件)来完成繁琐的解析工作。有一个用于LDAP寻址的共享库,一个用于文件的共享库,一个用于DNS的共享库,一个用于YP的共享库,依此类推。

如果要使程序100%静态链接,则必须转到其他位置(NOT
gethostbyname)才能将主机名转换为IP地址。您可以使用诸如uDNS之类的解析器库(不是确切的解析器库-
可以使用类似的工具)来执行此操作,但是请记住, 在配置为不使用DNS的系统上,二进制文件做不到正确的事情

相反,我建议您仅使程序保持(技术上)动态链接。如果您真的想确保它可以在任何平台上运行,甚至可以glibc附带二进制文件-
尽管这样做需要LGPL一致性。保留此动态链接仅意味着您将无法在glibc版本错误的系统上工作-并不是一个巨大的兼容性问题。

说到许可证合规性,值得注意的是,如果您静态链接glibc,则很可能必须交付 整个应用程序
的源代码才能符合glibc的LGPL许可证。我不是律师,这也不是合格的法律建议,但是阅读LGPL可以很清楚地知道,静态链接的应用程序glibc必须是开源的。



 类似资料:
  • 问题内容: 我试图用Java编写一个宁静的Web服务,该服务将包含一些字符串参数和一个二进制文件(pdf)参数。 我知道如何做字符串,但是我却挂在二进制文件上了。有什么想法/例子吗? 这是我到目前为止的 由于我已经发布了此链接,因此删除了具有答案的链接,因此这是我的实现。 问题答案:

  • 问题内容: 我知道PHP在服务器上运行之前先被编译为字节码,然后可以缓存该字节码,这样就不必每次访问Web时都重新解释整个脚本。 但是,您可以“编译” PHP代码并上载一个二进制文件,该文件将由字节码解释器运行吗? 问题答案: 提出这个问题后,Facebook推出了 适用于PHP的HipHop, 这可能是迄今为止测试最完善的PHP编译器(它运行着世界十大网站之一)。但是,Facebook停止使用H

  • 试图编译多文件包。需要通过进行编译,同时通过一个文件同时编译所有其他文件(大约4个其他.Java文件)?我已经尝试使用了extend和等语句。 我使用了不同的编译方法和参数,但尝试只插入和 摘要:试图一次编译多个Java文件,通过Java编译单个文件。 主文件的当前代码:

  • 一个trait中的静态函数可以调用同一trait中的另一个静态函数吗?假设我有以下特点: 那不行。代码不能在这里编译。 此外,没有类型让我使用完全限定的语法,如

  • 问题内容: 我想做的是将我的代码发送到远程服务器,该服务器可能安装了不同的python版本和/或可能没有我的应用程序所需的软件包。 现在,要实现这种可移植性,我必须使用解释器和代码来构建可重定位的virtualenv。这种方法存在一些问题(例如,由于无法按预期工作,您必须手动将一堆库复制到virtualenv中),并且通常速度较慢。 从理论上讲,有一种方法可以静态地自行构建python。 我想知道

  • 我想为我的游戏创建一个简单的倒计时,当游戏开始时,我想每秒调用这个函数: 我试过这个: 但应用程序不幸停止,第二次调用run函数 3周前,我刚刚开始使用android开发和静态编程语言,到目前为止,我对它了解最多。 在Xcode中使用swift时,我使用了这一行,我认为类似的东西也适用于Kotlin