Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux:从32位用户模式程序检测64位内核(长模式)_Linux_Kernel_32 Bit_Mode - Fatal编程技术网

Linux:从32位用户模式程序检测64位内核(长模式)

Linux:从32位用户模式程序检测64位内核(长模式),linux,kernel,32-bit,mode,Linux,Kernel,32 Bit,Mode,检测32位用户模式程序是否在64位内核上运行(即系统是否处于“长模式”)的最佳和最可靠的方法是什么?如果可能的话,我宁愿不调用外部程序(或者必须加载任何内核模块) 注意:我想检测是否正在使用64位内核(或者CPU是否处于长模式),而不仅仅是检测是否存在64位处理器(/proc/cpuinfo告诉我这一点,而不是检测是否正在使用64位处理器) 如果uname是32位编译的,或者使用了setarch i686,则内核会伪造32位处理器。调用uname()函数,检查返回的机器字符串,对于64位Inte

检测32位用户模式程序是否在64位内核上运行(即系统是否处于“长模式”)的最佳和最可靠的方法是什么?如果可能的话,我宁愿不调用外部程序(或者必须加载任何内核模块)

注意:我想检测是否正在使用64位内核(或者CPU是否处于长模式),而不仅仅是检测是否存在64位处理器(
/proc/cpuinfo
告诉我这一点,而不是检测是否正在使用64位处理器)

如果
uname
是32位编译的,或者使用了
setarch i686
,则内核会伪造32位处理器。

调用
uname()
函数,检查返回的
机器
字符串,对于64位Intel平台,该字符串将是
x86_64

逆转使用
setarch
效果的一种方法是重置个性:

#include <stdio.h>
#include <sys/utsname.h>
#include <sys/personality.h>

int main()
{
    struct utsname u;

    personality(PER_LINUX);

    uname(&u);
    puts(u.machine);
    return 0;
}
编辑:固定代码以反转
setarch
的效果


.

如果为其配置了内核,则可以从/proc/config.gz读取内核配置

zcat /proc/config.gz | grep CONFIG_64BIT
# CONFIG_64BIT is not set
我不确定您需要它的可移植性有多高-它看起来不像是一个超级常见的配置选项。

假设uname()是欺骗,仍然有几种机制。一种方法是检查任何内核符号的地址宽度

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  char *inputline = malloc(1024);
  char *oinputline = inputline;
  int fd = open("/proc/kallsyms", O_RDONLY);
  int numnibbles = 0;
  if (fd == -1) {
      perror("open");
      free(inputline);
      exit(1);
  }
  read(fd, inputline, 1024);
  close(fd);
  while(!isspace(*inputline)) {
      numnibbles++;
      inputline++;
  }
  printf("%dbit\n", numnibbles*4);
  free(oinputline);
  exit (0);
}
#包括
#包括
#包括
#包括
#包括
int main(int argc,字符**argv){
char*inputline=malloc(1024);
char*oinputline=输入行;
int fd=打开(“/proc/kallsyms”,仅限ordu);
int numnibbles=0;
如果(fd==-1){
佩罗(“公开”);
免费(输入线);
出口(1);
}
读取(fd,输入线,1024);
关闭(fd);
而(!isspace(*inputline)){
numnibbles++;
inputline++;
}
printf(“%dbit\n”,numnibbles*4);
免费(在线);
出口(0);
}

您可以查看例如
/proc/vmallocinfo
,看看地址是32位还是64位,只能由root读取,对吗?
/proc/kallsyms
是默认的世界可读的替代方法。这类方法有效,但如果我使用
setarch
运行程序,例如,
setarch i686./uname
它会打印i686。这是正确的行为,不是吗?您正在显式更改进程所看到的体系结构。我真正想做的是找出CPU是否处于长模式。@Atomies:嗯,CPU在运行32位进程时没有处于长模式。。。
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  char *inputline = malloc(1024);
  char *oinputline = inputline;
  int fd = open("/proc/kallsyms", O_RDONLY);
  int numnibbles = 0;
  if (fd == -1) {
      perror("open");
      free(inputline);
      exit(1);
  }
  read(fd, inputline, 1024);
  close(fd);
  while(!isspace(*inputline)) {
      numnibbles++;
      inputline++;
  }
  printf("%dbit\n", numnibbles*4);
  free(oinputline);
  exit (0);
}