CN1650264A - 用于修改一个内核模块以便在多个内核版本上运行的设备和方法 - Google Patents

用于修改一个内核模块以便在多个内核版本上运行的设备和方法 Download PDF

Info

Publication number
CN1650264A
CN1650264A CNA038083973A CN03808397A CN1650264A CN 1650264 A CN1650264 A CN 1650264A CN A038083973 A CNA038083973 A CN A038083973A CN 03808397 A CN03808397 A CN 03808397A CN 1650264 A CN1650264 A CN 1650264A
Authority
CN
China
Prior art keywords
kernel
module
goal systems
compiling
symbol
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CNA038083973A
Other languages
English (en)
Inventor
托马斯·汉达尔
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
CA Inc
Original Assignee
Computer Associates Think Inc
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Computer Associates Think Inc filed Critical Computer Associates Think Inc
Publication of CN1650264A publication Critical patent/CN1650264A/zh
Pending legal-status Critical Current

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/70Software maintenance or management
    • G06F8/71Version control; Configuration management
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/60Software deployment
    • G06F8/65Updates
    • G06F8/656Updates while running

Abstract

一种方法和一个设备,用于改编对应于不同于一个目标系统上的内核的另一个内核版本的一个编译后的内核模块,使之适用于所述目标系统上的所述内核。一个内核分析器从目标系统上的内核中提取一个错误校验措施和一个内核版本标识。一个模块改编元件在编译后的内核模块中插入一个对应于由内核分析器从目标系统上的内核中提取出的错误校验措施的错误校验参数,并且用由内核分析器从目标系统上的内核中提取的内核版本标识替换编译后的内核模块中的一个版本标识。

Description

用于修改一个内核模块以便在 多个内核版本上运行的设备和方法
相关申请
本发明要求了共同转让的美国临时申请60/373120的优先权,该申请是在2002年4月17日提出的,其标题为“用于修改一个内核模块以便在多个内核版本上运行的设备和方法”。
技术领域
本发明涉及计算机操作系统。尤其地,本发明涉及改编一个内核模块使之适合于一个目标系统的一个操作系统内核。
背景技术
一个操作系统是一个或多个使得操作计算机硬件可用的计算机程序(例如,指导一台计算机执行一个或多个任务的计算机指令集合)。DOS、Windows、Mac、UNIX和Palm是某些操作系统族。
操作系统的主要功能是管理计算机的资源。资源可包括,例如,处理器、存储器(例如内存、硬盘等)、输入/输出设备(例如打印机、监视显示器等)以及通信设备(例如调制解调器、网络接口等)。资源管理任务包括,例如,提供由多个用户对于数据和其他资源的共享,处理握手和其他网络通信任务等。
诸如资源管理的操作系统功能通过是以对一般计算机用户透明的方式执行的。例如,虽然大多数用户没有意识到这一点,但一个操作系统作为一方面的计算机资源和另一方面的一个用户可使用的应用程序(例如文字处理器、电子表格、网络浏览器等)之间的一个接口。操作系统也具有其他功能,例如提供一个用户接口、对未被授权的用户保护访问权限和数据、从系统错误中恢复等。
一个操作系统内核是一个操作系统的核心或中心元件。一个内核的功能可包括进程管理、进程间通信、中断处理、支持存储器分配/重新分配、支持输入/输出活动、系统安全措施等。这些功能中的每一个都包括许多任务。例如,安全任务可包括访问控制、记录和监控、存储和文件系统管理以及网络和调制解调器通信监控等。
Linux是UNIX操作系统家族的一个成员,它可在多种计算机平台上运行,包括具有一个x86处理器的个人计算机。Linux是UNIX的一个免费的可随意更改的实施方式。特别地,一个Linux内核的源代码对公众是广泛可用的,并且一直在被改进或修改。随着对Linux内核的改进和/或其他更改的实现以及被公众广泛采用,新的Linux版本被发布出来。一个公开发布的Linux内核版本可由一个相应分配的内核版本标识所标识。
与某些其他操作系统内核相似,一个Linux内核通常由多个内核模块组成。一个内核模块是一个用于执行一个或多个相应的内核任务的程序。一个内核版本可以是根据其上将要安装内核版本的特定系统选择的内核模块的一个组合。两个内核版本的不同之处可在于(a)一个版本中具有另一个版本没有的附加模块和/或(b)版本各自的两个模块执行相同的一个或多个任务但是是通过不同的方法(但是可能是同样符合要求的)。
当一个新的内核模块被添加到一个操作系统内核中(或替换其中的一个现有模块)时,具有新模块的内核可能需要被重新编译。编译一个内核是一项耗时的任务。对于诸如Linux这样多个内核版本被积极使用的操作系统,一个新的(例如,防火墙)内核模块可能要经历多个内核编译,对应于要添加新模块的多个(定制的或公开发布的)内核版本。
Linux提供了可加载的内核模块的动态链接。即使当一个内核使用可动态链接的内核模块时,每个可动态链接的内核模块都被编译成一个可加载的模块。虽然将加载一个新的可动态链接的内核模块的内核可能不需要被重新编译,新的可动态链接的内核模块通常被编译多次(在某些情况下是数百次),每次编译提供一个被各个(发布的或定制的)内核版本可动态链接的一个相应的可加载模块。多次编译是耗时的,并且引起许多不必要的存储消耗。
发明内容
本申请提供了一个内核模块修改设备,用于为一个目标系统上的一个内核改编一个编译后的内核模块,该编译后的内核模块对应于不同于目标系统上的内核的另一个内核版本。在一个实施方式中,设备包括一个内核分析器和一个模块改编元件。内核分析器从目标系统上的内核中提取一个错误校验措施和一个内核版本标识。模块改编元件在编译后的内核模块中插入一个对应于由内核分析器从目标系统上的内核中提取出的错误校验措施的错误校验参数,并且用由内核分析器从目标系统上的内核中提取的内核版本标识替换编译后的内核模块中的一个版本标识。
本申请还提供了一种方法,用于为一个目标系统上的一个内核改编一个编译后的内核模块,该编译后的内核模块对应于不同于目标系统上的内核的另一个内核版本。根据一个实施方式,该方法包括从目标系统上的内核中提取一个错误校验措施和一个内核版本标识,在编译后的内核模块中插入一个对应于由内核分析器从目标系统上的内核中提取出的错误校验措施的错误校验参数,并且用从目标系统上的内核中提取的内核版本标识替换编译后的内核模块中的一个版本标识。所述插入错误校验参数的编译后的内核模块可为一个可加载的Linux内核模块和/或二进制。其中插入了错误校验参数并且带有从目标系统上的内核提取的内核版本标识的修改、编译后的内核模块可加载到目标系统的内核中。
根据另一个实施方式,错误校验措施可包括一个或多个从目标系统上的内核中提取的校验和。该方法可进一步包括在编译后的内核模块中查找一个符号表,并且对于符号表中的每个符号名称,执行一个符号名称分析。符号名称分析可包括将符号名称与目标系统上的内核中的符号相比较。如果符号名称与目标系统上的内核中的一个符号相匹配,则与匹配的符号相关的一个校验和将被提取出,并被附加到编译后的内核模块的符号表的符号名称中。该方法还可包括在分析符号名称后调整符号表的一个或多个偏移量。
附图说明
从以下参考附图的详细说明中将更容易理解本申请的特征,在附图中:
图1显示了根据本申请的一个实施方式的一个内核模块修改设备的框图;
图2显示了根据本申请的一个实施方式的一种方法的流程图,该方法用于改编对应于不同于目标系统上的内核的另一个内核版本的一个编译后的内核模块,使之适用于一个目标系统上的一个内核。
图3显示了根据本申请的一个实施方式的一种方法的流程图,该方法用于改编对应于另一个Linux内核版本的一个编译后的Linux内核模块,使之适用于一个目标系统上的一个Linux内核。
图4显示了根据本申请的一个实施方式的一种用于分析符号名称的方法的流程图。
具体实施方式
本申请提供了用于修改一个内核模块以便在多个内核版本上运行的工具(以方法和设备的形式)。这些工具可实施在存储在一个计算机可读介质和/或经过一个计算机网络或其他传输介质传输的一个软件工具(例如,一个或多个计算机程序)中。执行软件工具的计算机或计算机系统可为目标系统。
根据图1所示的一个实施方式的一个内核模块修改设备10,为一个目标系统上的一个内核改编一个编译后的内核模块,该编译后的内核模块对应于不同于目标系统上的内核的另一个内核版本。设备10包括一个内核分析器11和一个模块改编元件12。内核分析器和模块改编元件可为一个软件工具中的模块或代码段。
参照图1和2说明了根据一个实施方式的一种方法,该方法用于为一个目标系统上的一个内核改编一个编译后的内核模块,该编译后的内核模块对应于不同于目标系统上的内核的另一个内核版本。内核分析器元件11从目标系统内核5中提取一个错误校验措施5a和一个内核版本标识5b(步骤S21)。模块改编元件12在编译后的内核模块20中插入一个对应于由内核分析器从目标系统上的内核中提取出的错误校验措施的错误校验参数(步骤22),并且用从目标系统上的内核中提取的内核版本标识替换编译后的内核模块20中的一个版本标识(步骤S23)。
插入错误校验参数的编译后的内核模块可为一个可加载的Linux内核模块和/或二进制。其中插入了错误校验参数并且带有从目标系统上的内核提取的内核版本标识的修改、编译后的内核模块可加载到目标系统的内核中。
从目标系统内核提取的版本标识可以是一个版本号码或另一个版本标识(例如一个或多个符号)。
从目标系统内核提取的错误校验措施可为一个或多个校验和。当错误校验措施是一个校验和时,插入编译后的内核模块中的错误检验参数可以与所述错误校验措施相同或互补,或者来自于错误校验措施。校验和方法在现有技术中是已熟知的。为清楚起见,本发明不提供对于这种方法的一个详细讨论。在任何情况下,具有根据从目标系统内核提取的错误校验措施获取的错误校验参数的修改后的内核模块应该符合内核的错误校验标准。
以下说明了一个Linux内核的一个示例性实施方式。但是,应当理解,本发明的主题可应用到其他类型的操作系统内核中。
内核模块修改设备可为一个软件工具,用于修改一个特定内核版本的一个编译后的Linux内核模块,并且产生一个适用于加载到一个目标系统上的一个不同的内核版本的修改后的内核模块。修改包括对于内核模块的一个符号表头中的一个符号表和内核模块的模块信息段中的一个版本标识的修改。
Linux内核模块可被编译成一个称为可执行和可链接格式(ELF)的格式。ELF格式具有许多段和头,它们描述模块/可执行文件的正确执行和链接信息。这些段包括符号表和模块信息段。
一个编译后的内核模块中的一个符号表是用于内核模块中的标识符(即符号,例如名称、标签等)、标识符在模块中的位置以及标识符属性的一个列表。在一个Linux内核模块的符号表中,一个校验和被附在每个符号名称的末尾。校验和值可用于在模块被插入一个目标内核中时验证内核模块使用相同的符号原形、处理器操作代码等。如果这些值是不同的,则内核确定存在未解析的符号,并且中止加载内核模块的进程。为了应对此问题,可从内核模块的符号中删除校验和,并且用存储在目标内核中的校验和替换它。校验和替换使得模块能在没有任何未解析的符号错误的情况下被加载。
以下参考图3和4说明一种方法,用于为一个目标系统上的一个Linux内核改编一个编译后的Linux内核模块,其中该编译后的Linux内核模块对应于另一个Linux内核版本。
ELF格式内核模块的段头被工具读取并解析(步骤S31)。工具根据段头信息查找内核模块中的符号表的一个偏移量,并且该偏移量被用于查找内核模块中的符号表(步骤S32)。然后符号表被工具读取和解析(步骤S33)。从符号表信息确定被称为一个“字符串表”的符号名称在模块中存储的一个偏移量(步骤S34)。然后从字符串表每次读取和分析一个符号名称(步骤S35)。
字符串表中的符号名称的分析可通过以下方法执行(图4)。选择字符串表中的一个符号名称(步骤S351)。校验选中的符号名称以确定是否附加了一个校验和(步骤S352)。如果没有找到校验和(步骤S352),则跳过该符号名称并且选择下一个符号名称。如果符号名称包括一个附加的校验和(步骤S352),则剥去校验和(步骤S353),并且将剩下的名称与目标系统上的内核中的符号相比较(步骤S354)。如果发现一个匹配(步骤S354),则提取附加到目标系统内核中被匹配符号上的一个校验和,并且将它附加到内核模块的字符串表中所选中的符号名称(步骤S355)。如果未发现匹配(步骤S354),则生成一条错误消息,表示存在一个未解析的符号(步骤S356),并且符号名称分析程序不继续进行。否则,继续此过程直到已校验并修改了所有符号名称(步骤S357)。如果发生了对字符串表的一个修改(步骤S358),则字符串表的大小可能已经变了。因此,可能需要调整ELF格式头的偏移量以反映字符串表大小的变化(步骤S359)。
以下伪代码描述此过程:
WHILE MORE SYMBOLS

       IF SYMBOL CONTAINS CHECKSUM

              STRIP CHECKSUM FROM SYMBOL

              SEARCH RUNNING KERNEL FOR STRIPPED SYMBOL

              IF MATCH FOUND

                    APPEND CHECKSUM FOUND ONTO SYMBOL NAME

                    STORE SYMBOL NAME WITH NEW CHECKSUM IN NEW MODULE

                    RECORD SIZE CHANGE OF SYMBOL
 
                    ELSE
 
                          DISPLAY ERROR AND EXIT

                    END IF

              END IF

        END WHILE

        MODIFY ELF FORMAT HEADER OFFSETS TO REFLECT STRING TABLE SIZE

    CHANGE
接下来修改模块信息段。模块信息段保存了为其编译内核模块的内核版本的标识信息。嵌入在模块信息中的是一个版本标识,它被目标系统上的内核的内核版本标识所替换。对版本标识的修改使得内核模块能够在没有内核版本不匹配的错误消息的情况下被加载到目标系统上的内核中。
上述ELF格式解析(步骤S31)也生成对模块的模块信息段的一个偏移量(步骤S32)。读取和分析模块信息段(步骤S36)以查找与模块信息段相关的一个字符串表的一个偏移量(与符号名称字符串表不同)(步骤S37)。模块信息字符串表被读取和解析(步骤S38)。然后在字符串表中查找版本标识。例如,在一个编译后的Linux内核模块中,版本标识在字符串“kernel_version=”之后(步骤S39)。当发现此字符串时,为其编译Linux内核模块的内核版本的版本标识在版本“=”号之后。接下来,用目标系统的内核版本标识替换版本标识,其中目标系统的内核版本标识可从例如目标系统上的一个“uname”系统调用中获得。版本标识修改可改变字符串表大小(步骤S41)。因此,需要重新计算字符串表大小,并且修改ELF头偏移量以反映字符串表大小的一个变化(步骤S42)。
修改后的内核版本字符串被写出,作为新的内核模块(步骤S43)。修改后的内核模块可加载到目标系统上的内核中。
以下源代码是用于一个示例性的软件工具的。
/************************************************************/

    /*Linux Kernel Module Modification program to allow a       */

    /*kernel module compiled for another kernel version to      */

  /*insert and run on the current kernel version.             */

  /*The kernel versions may be fairly close.                  */

  /*Also,it is checked that the                              */

  /*kernel subsystem that is being utilized has not changed   */

  /*much between the two versions that this module is being   */

  /*modified to and from.                                     */

  /*                                                          */

  /*File :modify.c                                           */

  /*                                                          */

  /*Compile :gcc modify.c.get_Ksym.c-o mod                   */

  /*Usage :./mod<old_module><new_module>mod                  */

  /************************************************************/

  #include<stdio.h>

  #include<stdlib.h>

  #include<string.h>

  #include<fcntl.h>

  #include<sys/types.h>

  #include<sys/stat.h>

  #include<sys/utsname.h>

  #include<elf.h>

  #include<unistd.h>

  char*getKsym(char*);

  /*************************************************************

     readDataFromFile

     This function takes a file descriptor,offset and size

     as arguments.It basically allocates a buffer of size

     ″size″and then goes to the specified ″offset″of the

     file descriptor and copies reads into the buffer from
        <!-- SIPO <DP n="8"> -->
        <dp n="d8"/>
     the file descriptor.

     Returns a pointer to the newly allocated buffer with

     the data.

  **************************************************************/

  void*readDataFromFile(int fd,off_t offset,size_t bytes)

  {

    void*buffer;

    buffer=(void*)malloc(bytes);

    if(!buffer)

      return NULL;

    if(lseek(fd,offset,SEEK_SET)!=offset)

    {    

      perror(″lseek″);

      free(buffer);

      return NULL;

    }    

    if(read(fd,buffer,bytes)!=bytes)

   {
 
     perror(″read″);

     free(buffer);

     return NULL;

   }

   return buffer;

  }

  /*Symbol structure to keep track of symbols

   *during modification of symbol table

   */

  struct symbol_type

  {

    char name[256];

    unsigned int old_index;

    unsigned int new_index;

  };

  int main(int argc,char*argv[])

  {

    int fd;    

    FILE*log_fp;

    int I,k;

    Elf32_Ehdr*hdr;

    Elf32_Shdr*shdr;

    Elf32_Sym*symtab

    int symtab_string_link;

    char*symtab_strings,*symtab_strings2;
        <!-- SIPO <DP n="9"> -->
        <dp n="d9"/>
  char*elf_names,*modinfo;

  int symtab_strings_size,new_symtab_strings_size,modinfo_size;

  int offset=0,size =0,curindex;

  char*ptr;

  struct symbol_type*new_strings;

  int file_delta,modinfo_delta;

  char*entire_file,*new_file;

  struct stat buf;

  int symtab_offset_index,modinfo_offset_index;

  /*Check proper number of arguments*/

  if(argc<3)

  {

    printf(″\nUsage :%s module new_module\n\n″,argv[0]);

     return 1;

  }

  /* Open the log file */

  log_fp=fopen( ″mod.log″,″w″);
  
  if(!log_fp )

  {

     perror(″fopen:mod.log″);

     return 1;

  }

   /* Start the log file header */

  fprintf(log_fp,″\n***************************************\n″);

  fprintf(log_fp,″Starting Modification of %s\n″,argv[1]);
 
  fprintf(log_fp,″***************************************\n″);

  fprintf(log_fp,″\nInput File:%s\nOutput File:%s\n\n″,
argv[1],argv[2]);

  /* Open the original kernel module for reading */

  fd=open(argv[1],O_RDONLY);

  if(fd<0)

  {

     perror(″open″);

     fclose(log_fp);

     return 1;

  }

  /* Read the ELF Header data */

  if((hdr=(Elf32_Ehdr*)readDataFromFile(fd,0,sizeof<br/>
(Elf32_Ehdr)))==NULL)
   {

   fclose(log_fp);

   close(fd);
        <!-- SIPO <DP n="10"> -->
        <dp n="d10"/>
    return-1;

    }

  /*Read the ELF Section Header data*/

  shdr=(Elf32_Shdr*)readDataFromFile(fd,hdr->e_shoff,
hdr->e_shentsize*hdr->e_shnum);

  /**First,the modinfo section where the kernel_version is
held is modified**/    

  /*Read the string table for the section headers*/

  elf_names=(char*)readDataFromFile(fd,shdr[hdr-
>e_shstrndx].sh_offset,

                                   shdr[hdr-
>e_shstrndx].sh_size);

  printf(″\nModifying Kernel Version Information...\n″);

  fprintf(log_fp,″\nModifying Kernel Version Information...\n″);

  /*Search the section header table for″.modinfo″section*/

  for(i=0;i<hdr->e shnum;i++)

  {    

    if(strcmp(elf_names+shdr[i].sh_name,″.modinfo″)==0
)

    {

      struct utsname buf;

      char*modinfo_data,*old_ptr,*new_ptr;

      modinfo_size=0;

      modinfo_offset_index=i;

         /*Grab the current kernel version*/

      if(uname(&buf))

      {

        perror(″uname″);

        return 1;

      }

      /*Get some memory and read module string table into it*/

      new_ptr=modinfo=(char*)malloc(strlen(
buf.release)+shdr[i].sh_size);

      modinfo_data=(char*)readDataFromFile(fd,
shdr[i].sh_offset,
shdr[i].sh_size);

      ptr=modinfo_data;

       /*Find the kernel_version string in the string table*/
        <!-- SIPO <DP n="11"> -->
        <dp n="d11"/>
    while(ptr<(modinfo_data+shdr[i].sh_size))

    {

      if(strstr(ptr,″kernel_version=″))

    {

         /*String found,so replace with buf.release from
uname*/

      sprintf(new_ptr,″kernel_version=%s″,buf.release);

      new_ptr+=strlen(″kernel_version=″)+strlen(
buf.release)+1;

      modinfo_size+=strlen(″kernel_version=″)+strlen(
buf.release)+1;

      }

      else

      {

        strcpy(new_ptr,ptr);

        new_ptr+=strlen(ptr)+1;

        modinfo_size+=strlen(ptr)+1;

      }

      ptr+=strlen(ptr)+1;

    }

    fprintf(log_fp,″Changing Kernel Version
kernel_version=%s\n″,buf.release);

     /*Calculate string table size difference*/

     modinfo_delta=modinfo_size-shdr[i].sh_size;

     break;
  
    }

  }

  fprintf(log_fp,″Modinfo Delta :%d\n″,modinfo_delta);

  /**find the symbol table**/

  printf(″\nModifying Symbol Table Information...\n″);

  fprintf(log_fp,″\nModifying Symbol Table Information...\n\n″);

  for(i=0;i<hdr->e_shnum;i++)

     if(shdr[i].sh_type==SHT_SYMTAB)

     {
 
       symtab_offset_index=i;

       symtab_string_link=shdr[i].sh_link;

       break;

     }

   /*Found the symbol table,so read the symbol table string
table*/
   symtab_strings=(char*)readDataFromFile(fd,
        <!-- SIPO <DP n="12"> -->
        <dp n="d12"/>
shdr[symtab_string_link].sh_offset,
shdr[symtab_string_link].sh_size);

  symtab_strings_size=shdr[symtab_string_link].sh_size;
  symtab=(Elf32_Sym*)readDataFromFile(fd,
shdr[i].sh_offset,shdr[i].sh_size);

  close(fd);

  /*Allocate space for the symbol structure so we may keep track
of the symbols*/

  new_strings=(struct symbol_type*)malloc(5000*sizeof(
struct symbol_type));

  ptr=symtab_strings;
  offset=0;

  i=0;

  size=0;

  new_symtab_strings_size=0;

  /*Go through the symtab strings and compare them to the ones
in the kernel*/

  while(ptr<symtab_strings+
shdr[symtab_string_link].sh_size  )

 {

   char*it=(char*)0x1;

   /*Look for the symbol structure associated with symbol name
to see

    *if this symbol is undefined...If it is undefined,then

    *it is matched to the kernel...If it is defined,it is
part of the module,

    *so we leave it alone...

    */

  for(k=0;k<shdr[symtab_offset_index].sh_size/sizeof(
Elf32_Sym);k++)

    if(symtab[k].st_name==(int)(ptr-symtab_strings))

      if(ELF32_ST_TYPE(symtab[k].st_info)==STT_NOTYPE)

      {

        it=getKsym(ptr);

        break;

      }

  /*If the symbol was not found as UNDEF(STT_NOTYPE),then we
take the

   *original symbol name.

   */

  if(it==(char*)0x1)
        <!-- SIPO <DP n="13"> -->
        <dp n="d13"/>
    it=ptr;

  if(!it)

  {

    printf(″\nUnresolved Symbol...%s\nExiting...\n\n″,ptr);

    fprintf(log_fp,″\nUnresolved Symbol...%s\nExiting...\n\n″,
ptr);

    return 1;

  }

  /*Store them away in a temporary spot,one by one*/

  strcpy(new_strings[i].name,it);

  new_symtab_strings_size+=strlen(it)+1;

  /*Store in the log the change we made*/

  if(strcmp(it,ptr)!=0)

  {

    fprintf(log_fp,″%-30s ->%-30s\n″,ptr,it);

    free(it);

  }
  
  new_strings[i++].old_index=size;

  size+=strlen(ptr)+1;

  ptr+=strlen(ptr)+1;
  }
  /*Now that we have our own copy of the symbols with new
checksums,we dont need the original string table*/
  free(symtab_strings);
  /*Now we create our own version of symtab_strings,to put in
our new module*/
  symtab_strings2=(char*)malloc(new_symtab_strings_size*
sizeof(char));
  memset(symtab_strings2,0,new_symtab_strings_size*sizeof(
char));
  ptr=symtab_strings2;
  curindex=0;
  for(offset=0;offset<i;offset++)
  {

  strcpy(ptr+curindex,new_strings[offset].name);

  new_strings[offset].new_index=curindex;

  curindex+=(strlen(ptr+curindex)+1);
  }
  /**Fix up the symbol table indeces for the name table in the

   symtab section header
  **/
        <!-- SIPO <DP n="14"> -->
        <dp n="d14"/>
     for(k=0;k<shdr[symtab_offset_index].sh_size/sizeof(
Elf32_Sym);k++)
  {

    if(symtab[k].st_name !=0)

    {

      int index; 

      for(index=1;index<i;index++)

        if(symtab[k].st_name==new_strings[index].old_index)

          symtab[k].st_name=new_strings[index].new_index;

    }
  }
  /*Calculate the new size of the string table*/
  file_delta=new_symtab_strings_size-symtab_strings_size;
  fprintf(log_fp,″\nSymtab Strings Delta:%d\n″,file_delta);
  /**We now have all of the new symbol names with new checksums,

  *and also the new kernel version...

    *We are now going to write out the new module

    */
  /*Read the entire old module,so we can spot modify*/
  fd=open(argv[1],O_RDONLY);
  stat(argv[1],&buf),
  entire_file=(char*)malloc(buf.st_size);
  read(fd,entire_file,buf.st_size);
  close.(fd);
  free(hdr);
  free(shdr);
  /*Set the pointers for the ELF Header and Section Header*/
  hdr=(Elf32_Ehdr*)entire_file;
  shdr=(Elf32_Shdr*)(entire_file+hdr->e_shoff);
  /**set the new size of the symtab string table**/
  shdr[symtab_string_link].sh_size=new_symtab_strings_size;
  /**Copy over the new symbol string table over the old one**/
   memcpy((char*)entire_file+
shdr[symtab_string_link].sh_offset,

          (char*)symtab_strings2,new_symtab_strings_size);
  /**Copy over the new symtab section header,with the new
offsets**/
        <!-- SIPO <DP n="15"> -->
        <dp n="d15"/>
    memcpy((char*)entire_file+
shdr[symtab_offset_index].sh_offset,

          (char*)symtab,shdr[symtab_offset_index].sh_size
);
  /**Allocating memory for a new file,including size for
possible

  *growth of string table forthe module info section and

  *symbol table sections
  **/
  new_file=(char*)malloc(buf.st_size+file_delta+
modinfo_delta);
  /**Copy over the portions of the file,piece by piece.*/
  memcpy(new_file,entire_file,
shdr[modinfo_offset_index].sh_offset);
  memcpy(new_file+shdr[modinfo_offset_index].sh_offset,
modinfo,modinfo_size);    
  memcpy(new_file+shdr[modinfo_offset_index].sh_offset+
modinfo_size,

         entire_file+shdr[modinfo_offset_index].sh_offset+

           shdr[modinfo_offset_index].sh_size,

         buf.st_size-shdr[modinfo_offset_index].sh_offset-

           shdr{modinfo_offset_index].sh_size);
  /**Change the offsets for the section headers ...**/
  hdr={Elf32_Ehdr*)new_file;
  /*Find the new section header table offset*/
  if(shdr[symtab_string_link].sh_offset<hdr->e_shoff)

  hdr->e_shoff+=file_delta;
  if(shdr[modinfo_offset_index].sh_offset<hdr->e_shoff)

  hdr->e_shoff+=modinfo_delta;
  /*Grab the section header table*/
  shdr=(Elf32_Shdr*)(new_file+hdr->e_shoff);
  /*Modify the size of the modinfo section size,

  since we changed the kernel version*/
  shdr[modinfo_offset_index].sh_size+=modinfo_delta;
  /*Modify the rest of the section header offsets*/
  for(i=0;i<hdr->e_shnum;i++)
  {    

  if(shdr[symtab_string_link].sh_offset<shdr[i].sh_offset)

    shdr[i].sh_offset+=file_delta;
        <!-- SIPO <DP n="16"> -->
        <dp n="d16"/>
  if(shdr[modinfo_offset_index].sh_offset<shdr[i].sh_offset
)

    shdr[i].sh_offset+=modinfo_delta;
  }
  fprintf(log_fp,″\nSection Header Offsets modified...\n″);
  /**Open up and output the new module**/
  fd=open(argv[2],O_WRONLY|O_CREAT|O_TRUNC);
  if(fd<0)
  {

  perror(″open″);

  return 1;
  }
  write(fd,new_file,buf.st_size+file_delta+modinfo_delta
);
  close(fd);
  /**Free all of our memory**/
  free(new_file);
  free(new_strings);
  free(entire_file);
  free(modinfo);
  free(elf_names);
  /**Work is done;-)...New module now runs on current kernel
**/
  printf(″\n%s->%s Completed...\n\n″,argv[1],argv[2]);
  fprintf(log_fp,″\n%s->%s Completed...\n\n″,argv[1],argv[2]
);
  fclose(log_fp);
  return 0 ;    
}
/************************************************************/
/*Linux Kernel Module Modification program to allow a       */
/*kernel module compiled for another kernel version to      */
/*insert and run on the current kernel version.             */
/*The kernel versions may be fairly close.                  */
/*Also,it should be checked that the                       */
/*kernel subsystem that is being utilized has not changed   */
/*much between the two versions that this module is being   */
/*modified too and from.                                    */
/*                                                          */
/*File:get_Ksym.c                                          */
/*                                                          */
/*Compile:gcc modify.c get_Ksym.c-o mod                    */
        <!-- SIPO <DP n="17"> -->
        <dp n="d17"/>
/*Usage:./mod<old_module><new_module>                  */
/************************************************************/
#include<stdio.h>
#include<stdlib.h>  
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<errno.h>
/*************************************************/
/*getKsym                                        */
/*                                               */
/*This function takes in a symbol name and       */
/*checks to see if a checksum is included in     */
/*the name.If no checksum is found,the          */
/*original name is returned.If a checksum is     */
/*found,it is stripped off and the current      */
/* kernel is searched for this symbol name       */
/*using/proc/ksyms.If found,it                  */
/*replaces the old checksum with the new one     */
/*and return the new name.If not found,NULL     */
/*is returned.                                   */
/*************************************************/
char*getKsym(char*name)
{
  FILE* fp;
  char Symbol[256];
  char StripSymbol[256];
  char*new_symbol=NULL;
  char temp[20];    
  /*check to see if checksum is present*/
  if(strstr(name,″_R″)&& strlen(strstr(name,″_R″))
==10)

  strncpy(StripSymbol,name,strlen(name)-10);
  else

  return name;
  /*strip off the checksum*/
  StripSymbol[strlen(name)-10]=′\0′;
  /*open up the/proc/ksyms*/
  fp=fopen(″/proc/ksyms″,″r″);
  if(!fp)
  {

  perror(″open:/proc/ksyms″);

  return NULL;
  }
        <!-- SIPO <DP n="18"> -->
        <dp n="d18"/>
    /*Loop through the /proc/ksyms for the symbol*/

    while(fgets(Symbol,256,fp))

    {

      char*ptr;

      char*tempSymbol;

      tempSymbol=(char*)malloc(256);

      Symbol[strlen(Symbol)-1]=′\0′;

      strcpy(tempSymbol,Symbol+9);

      /*See if we have a possible match*/

      if(!strstr(tempSymbol,StripSymbol))

        continue;

      /**Check to see if this has a hash**/

      ptr=strstr(tempSymbol,″_R″);

      if(!ptr)

        continue;

      if(strlen(ptr)!=10)

        continue;

      /**The hash is stripoped off so we can check the exact symbol

   name**/

      /*This is an exact check for a match after the preliminary

   checks*/

       tempSymbol[strlen(tempSymbol)-10]=′\0′;

       if(strcmp(tempSymbol,StripSymbol)!=0)

         continue;

       /**We found a match,so go ahead and append the new

          *checksum onto the old symbol name

          *and return it.

          */

        free(tempSymbol);

      new_symbol=malloc(strlen(Symbol+9)+1);

      strcpy(new_symbol,Symbol+9);

      break;

    }

    fclose(fp);

    return new_symbol;

  }
以上特定实施方式是描述性的,并且可以在不背离本发明的精神或附录的权利要求书的范围的情况下在这些实施方式上引入许多变体。在本发明和附录的权利要求书的范围内,不同的描述性的实施方式的元件和/或特征可彼此结合和/或彼此替换。
例如,虽然在上述实施方式中,版本标识修改在符号表修改之后,但是模块信息修改也可在错误校验调整之前。又例如,虽然软件工具可在目标系统上运行,但如果目标系统的内核版本标识是已知的并且目标系统上的内核的错误校验措施也是可用的,则内核模块修改设备也可被改编为适于在除目标系统外的一个系统上(具有至少一个处理器和一个程序存储设备)运行。
在阅读了2002年4月17日提出申请的美国临时申请60/373120号后,具有本领域一般技术者可很容易了解到其他变体,该申请在此处被完全结合进来作为参考。

Claims (21)

1.一个内核模块修改设备,用于为一个目标系统上的一个内核改编一个编译后的内核模块,该编译后的内核模块对应于不同于所述目标系统上的所述内核的另一个内核版本,该设备包括:
一个内核分析器,可用于从所述目标系统上的所述内核中提取一个错误校验措施和一个内核版本标识;以及
一个模块改编元件,适用于在所述编译后的内核模块中插入一个对应于由内核分析器从目标系统上的内核中提取出的错误校验措施的错误校验参数,并且用由内核分析器从目标系统上的内核中提取的内核版本标识替换所述编译后的内核模块中的一个版本标识。
2.权利要求1的设备,其中向其中插入错误校验参数的编译后的内核模块是二进制的。
3.权利要求1的设备,其中向其中插入了错误校验参数并带有从目标系统上的内核中提取的内核版本标识的修改、编译后的内核可以加载到所述目标系统上的所述内核中。
4.权利要求1的设备,其中错误校验措施包括一个或多个被所述内核分析器从所述目标系统上的所述内核中提取的校验和。
5.权利要求1的设备,其中内核分析器在所述编译后的内核模块中查找一个符号表,并且对于符号表中的每个符号名称,执行一个符号名称分析。
6.权利要求5的设备,其中由内核分析器执行的符号名称分析可包括将所述符号名称与所述目标系统上的所述内核中的多个符号相比较。
7.权利要求6的设备,其中如果符号名称与所述目标系统上的所述内核中的一个符号相匹配,则内核分析器提取与匹配的符号相关的一个校验和,并且模块改编元件将提取出的校验和附加到所述编译后的内核模块的符号表的所述符号名称中。
8.权利要求5的设备,其中在所述多个符号名称被分析后,模块改编元件调整符号表的一个或多个偏移量。
9.权利要求1的设备,其中编译后的内核模块是一个可加载的Linux内核模块。
10.一种方法,用于为一个目标系统上的一个内核改编一个编译后的内核模块,该编译后的内核模块对应于不同于所述目标系统上的内核的另一个内核版本,该方法包括:
从所述目标系统上的所述内核中提取一个错误校验措施和一个内核版本标识;
在所述编译后的内核模块中插入一个对应于由内核分析器从所述目标系统上的内核中提取出的错误校验措施的错误校验参数;以及
用从所述目标系统上的内核中提取的内核版本标识替换所述编译后的内核模块中的一个版本标识。
11.权利要求10的方法,其中向其中插入错误校验参数的所述编译后的内核模块是二进制的。
12.权利要求10的方法,其中向其中插入了错误校验参数并且带有从所述目标系统上的内核提取的内核版本标识的所述修改、编译后的内核模块可加载到所述目标系统的所述内核中。
13.权利要求10的方法,其中提取的错误校验措施包括一个或多个从所述目标系统上的所述内核中提取的校验和。
14.权利要求10的方法进一步包括在所述编译后的内核模块中查找的一个符号表,并且对于符号表中的每个符号名称,执行一个符号名称分析。
15.权利要求14的方法,其中符号名称分析包括将所述符号名称与所述目标系统上的内核中的多个符号相比较。
16.权利要求15的方法,其中如果符号名称与所述目标系统上的内核中的一个符号相匹配,则与匹配的符号相关的一个校验和被提取出,然后被附加到所述编译后的内核模块的符号表的所述符号名称中。
17.权利要求14的方法,其中在分析所述多个符号名称后调整符号表的一个或多个偏移量。
18.权利要求10的方法,其中所述编译后的内核模块是一个可加载的Linux内核模块。
19.一个系统,包括:
一个处理器;以及
一个可由系统读取的程序存储设备,它有形地实现一个可由机器执行以执行权利要求10的方法的指令的程序。
20.一个可由一台机器读取的程序存储设备,它有形地实现一个可由机器执行以执行权利要求10的方法的指令的程序。
21.实现在一个传输介质中的一个计算机数据信号,它实现了可由一台计算机执行以执行权利要求10的方法的指令的程序。
CNA038083973A 2002-04-17 2003-04-17 用于修改一个内核模块以便在多个内核版本上运行的设备和方法 Pending CN1650264A (zh)

Applications Claiming Priority (2)

Application Number Priority Date Filing Date Title
US37312002P 2002-04-17 2002-04-17
US60/373,120 2002-04-17

Publications (1)

Publication Number Publication Date
CN1650264A true CN1650264A (zh) 2005-08-03

Family

ID=29250968

Family Applications (1)

Application Number Title Priority Date Filing Date
CNA038083973A Pending CN1650264A (zh) 2002-04-17 2003-04-17 用于修改一个内核模块以便在多个内核版本上运行的设备和方法

Country Status (11)

Country Link
US (1) US7076770B2 (zh)
EP (1) EP1495402B1 (zh)
JP (1) JP2005523516A (zh)
KR (1) KR20040099439A (zh)
CN (1) CN1650264A (zh)
AU (1) AU2003222657A1 (zh)
BR (1) BR0309323A (zh)
CA (1) CA2480441A1 (zh)
DE (1) DE60317654T2 (zh)
IL (1) IL164607A0 (zh)
WO (1) WO2003090077A1 (zh)

Cited By (10)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN103312706A (zh) * 2013-06-04 2013-09-18 百度在线网络技术(北京)有限公司 网络访问控制的方法和装置
CN104021023A (zh) * 2014-06-24 2014-09-03 浪潮电子信息产业股份有限公司 一种突破内核模块版本控制解决方法
CN104572235A (zh) * 2014-12-31 2015-04-29 北京奇虎科技有限公司 一种可加载内核模块的编译方法和装置
CN105549965A (zh) * 2015-12-09 2016-05-04 浪潮电子信息产业股份有限公司 一种将驱动集成到不同Linux内核版本的方法
WO2016091071A1 (zh) * 2014-12-11 2016-06-16 北京奇虎科技有限公司 加载Linux内核驱动的方法及装置
CN105893085A (zh) * 2016-03-30 2016-08-24 百度在线网络技术(北京)有限公司 内核模块加载方法和装置
CN106815031A (zh) * 2017-02-22 2017-06-09 百度在线网络技术(北京)有限公司 内核模块加载方法和装置
CN108052327A (zh) * 2017-12-11 2018-05-18 北京奇虎科技有限公司 一种内核模块编译、加载方法及装置
CN111752620A (zh) * 2019-03-26 2020-10-09 阿里巴巴集团控股有限公司 内核模块的处理方法和加载方法
CN113220303A (zh) * 2021-04-21 2021-08-06 北京麟卓信息科技有限公司 一种内核模块的编译方法和系统

Families Citing this family (16)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7568188B2 (en) * 2003-03-07 2009-07-28 Microsoft Corporation Method for testing a software shim
US7634770B2 (en) * 2003-05-19 2009-12-15 Hewlett-Packard Development Company, L.P. Kernel module interface dependencies
US7954086B2 (en) * 2003-05-19 2011-05-31 Hewlett-Packard Development Company, L.P. Self-describing kernel modules
US20060015860A1 (en) * 2004-07-15 2006-01-19 Sony Corporation And Sony Electronics, Inc. System and method for storing attributes in a file for processing an operating system
US8042188B2 (en) * 2005-07-15 2011-10-18 Sony Corporation Information processing apparatus, information recording medium manufacturing apparatus, information recording medium, method and computer program
US7581141B2 (en) * 2006-03-01 2009-08-25 Sun Microsystems, Inc. Kernel module compatibility validation
US20090271780A1 (en) * 2008-04-24 2009-10-29 Moschip Semiconductor Technology Limited Automatic complete firmware upgrade
US8689206B2 (en) * 2009-03-05 2014-04-01 International Business Machines Corporation Isolating operating system in-memory modules using error injection
KR101042979B1 (ko) * 2009-10-23 2011-06-21 한국항공대학교산학협력단 임베디드 시스템의 신뢰성 평가를 위한 시뮬레이션 커널을 이용하는 오류주입시험 장치
US8914815B2 (en) * 2013-05-18 2014-12-16 Red Hat, Inc. Automated framework for tracking and maintaining kernel symbol list types
CN104679532B (zh) * 2013-11-27 2018-12-11 腾讯科技(深圳)有限公司 内核模块加载方法和装置
CN109992293B (zh) * 2018-01-02 2023-06-20 深圳市宇通联发科技有限公司 Android系统组件版本信息的组装方法及装置
CN111382063B (zh) * 2018-12-30 2023-09-08 贝壳技术有限公司 一种react兼容的校验方法及装置
CN111767072B (zh) * 2019-04-02 2023-03-14 浙江宇视科技有限公司 客户端制作方法及装置
US20220147636A1 (en) * 2020-11-12 2022-05-12 Crowdstrike, Inc. Zero-touch security sensor updates
CN116243971B (zh) * 2023-05-10 2023-07-28 北京麟卓信息科技有限公司 一种基于静态依赖自举的内核无关的模块构建方法

Family Cites Families (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US5359730A (en) * 1992-12-04 1994-10-25 International Business Machines Corporation Method of operating a data processing system having a dynamic software update facility
US6199203B1 (en) * 1998-07-21 2001-03-06 Hewlett-Packard Company Memory management techniques for on-line replaceable software
US6219828B1 (en) * 1998-09-30 2001-04-17 International Business Machines Corporation Method for using two copies of open firmware for self debug capability
US6477683B1 (en) * 1999-02-05 2002-11-05 Tensilica, Inc. Automated processor generation system for designing a configurable processor and method for the same
US7287259B2 (en) * 2000-04-24 2007-10-23 Microsoft Corporation Isolating assembly versions for binding to application programs

Cited By (14)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN103312706B (zh) * 2013-06-04 2017-05-10 百度在线网络技术(北京)有限公司 网络访问控制的方法和装置
CN103312706A (zh) * 2013-06-04 2013-09-18 百度在线网络技术(北京)有限公司 网络访问控制的方法和装置
CN104021023A (zh) * 2014-06-24 2014-09-03 浪潮电子信息产业股份有限公司 一种突破内核模块版本控制解决方法
WO2016091071A1 (zh) * 2014-12-11 2016-06-16 北京奇虎科技有限公司 加载Linux内核驱动的方法及装置
CN104572235A (zh) * 2014-12-31 2015-04-29 北京奇虎科技有限公司 一种可加载内核模块的编译方法和装置
CN104572235B (zh) * 2014-12-31 2019-02-26 北京奇虎科技有限公司 一种可加载内核模块的编译方法和装置
CN105549965A (zh) * 2015-12-09 2016-05-04 浪潮电子信息产业股份有限公司 一种将驱动集成到不同Linux内核版本的方法
WO2017166447A1 (zh) * 2016-03-30 2017-10-05 百度在线网络技术(北京)有限公司 内核模块加载方法和装置
CN105893085A (zh) * 2016-03-30 2016-08-24 百度在线网络技术(北京)有限公司 内核模块加载方法和装置
CN106815031A (zh) * 2017-02-22 2017-06-09 百度在线网络技术(北京)有限公司 内核模块加载方法和装置
CN106815031B (zh) * 2017-02-22 2020-03-24 百度在线网络技术(北京)有限公司 内核模块加载方法和装置
CN108052327A (zh) * 2017-12-11 2018-05-18 北京奇虎科技有限公司 一种内核模块编译、加载方法及装置
CN111752620A (zh) * 2019-03-26 2020-10-09 阿里巴巴集团控股有限公司 内核模块的处理方法和加载方法
CN113220303A (zh) * 2021-04-21 2021-08-06 北京麟卓信息科技有限公司 一种内核模块的编译方法和系统

Also Published As

Publication number Publication date
IL164607A0 (en) 2005-12-18
US7076770B2 (en) 2006-07-11
CA2480441A1 (en) 2003-10-30
WO2003090077A1 (en) 2003-10-30
EP1495402A1 (en) 2005-01-12
DE60317654T2 (de) 2008-10-30
JP2005523516A (ja) 2005-08-04
BR0309323A (pt) 2007-02-21
EP1495402B1 (en) 2007-11-21
US20040221275A1 (en) 2004-11-04
KR20040099439A (ko) 2004-11-26
AU2003222657A1 (en) 2003-11-03
DE60317654D1 (de) 2008-01-03

Similar Documents

Publication Publication Date Title
CN1650264A (zh) 用于修改一个内核模块以便在多个内核版本上运行的设备和方法
US7124408B1 (en) Binding by hash
US11200047B2 (en) Identifying versions of running programs using signatures derived from object files
JP5208350B2 (ja) 自己記述型ソフトウェアイメージ更新コンポーネント
Sansom et al. Time and space profiling for non-strict, higher-order functional languages
Venner Pro hadoop
US7055146B1 (en) Method and system for dynamically inserting modifications for identified programs
US8479162B2 (en) Method and apparatus for locating memory leak in a program
US6658416B1 (en) Apparatus and method for creating an indexed database of symbolic data for use with trace data of a computer program
US6766511B1 (en) Apparatus and method for performing symbolic resolution of modules using static representations of a trace
CN1648857A (zh) 供软件之用的自动版本管理系统和方法
US20080052701A1 (en) System and method for fine grain method update of an application to provide continuous availability
KR101150032B1 (ko) 비교적 한정된 저장 공간을 갖는 컴퓨팅 디바이스 및 그운영 체제/파일 시스템
EP1172729A2 (en) Apparatus and method for cataloguing symbolic data for use in performance analysis of computer programs
US7191436B1 (en) Computer system utility facilitating dynamically providing program modifications for identified programs
US20060037011A1 (en) Persisting and resolving application assembly binds
US7496615B2 (en) Method, system and article for detecting critical memory leaks causing out-of-memory errors in Java software
US20190171547A1 (en) Resource lifetime analysis using a time-travel trace
US6708169B1 (en) Apparatus and method for generating a merged symbol file for verifying symbolic data
CN112015491B (zh) 实现函数跳转的方法、装置及计算机存储介质
US20060059146A1 (en) Method and system for tracing components of computer applications
CN112099880B (zh) 场景驱动的应用程序约减方法和系统
CN1920826A (zh) 在具有命名空间的文件系统中查找丢失对象的方法和装置
CN103198244A (zh) 保护动态链接库的方法
CN111352631A (zh) 一种接口兼容性检测方法及装置

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C02 Deemed withdrawal of patent application after publication (patent law 2001)
WD01 Invention patent application deemed withdrawn after publication