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

发布于 2024-11-06 01:38:10 字数 302 浏览 3 评论 0原文

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

注意:我想检测是否正在使用 64 位内核(或者实际上,CPU 是否处于长模式),而不仅仅是是否存在支持 64 位的处理器(/proc/cpuinfo 告诉我这一点,但没有告诉我是否正在使用 64 位功能)。

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

What's the best and most reliable way to detect if a 32-bit user mode program is running on a 64-bit kernel or not (i.e. if the system is in 'long mode')? I'd rather not call external programs if possible (or have to load any kernel modules).

Note: I want to detect whether a 64-bit kernel is being used (or really, whether the CPU is in long mode), not simply if a 64-bit capable processor is present (/proc/cpuinfo tells me that but not whether the 64-bit capability is being used).

The kernel fakes a 32-bit processor if uname is compiled 32-bit or if setarch i686 is used.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

烂柯人 2024-11-13 01:38:10

调用 uname() 函数并检查返回的 machine 字符串,对于 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;
}

这在 32 位模式下编译并在 64 位系统上运行时显示正确的结果:

$ gcc -m32 -o u u.c
$ ./u
x86_64
$ setarch i686 ./u
x86_64

编辑:将代码固定为setarch 的反向效果。

参考

Call the uname() function and check the returned machine string, which will be x86_64 for a 64-bit Intel platform.

One way of reversing the effect of the use of setarch is to reset the personality:

#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;
}

This shows the right results when compiled in 32-bit mode and run on a 64-bit system:

$ gcc -m32 -o u u.c
$ ./u
x86_64
$ setarch i686 ./u
x86_64

EDIT: Fixed code to reverse effect of setarch.

Reference.

玩物 2024-11-13 01:38:10

假设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);
}

Assuming that uname() is cheating, there are still several mechanisms. One way is to check the width of the address of any of the kernel symbols.

#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);
}
江湖彼岸 2024-11-13 01:38:10

如果内核已配置,您可以从 /proc/config.gz 读取内核配置,

zcat /proc/config.gz | grep CONFIG_64BIT
# CONFIG_64BIT is not set

我不确定您需要它的可移植性 - 它似乎不是一个超级常见的配置选项。

If the kernel is configured for it, you can read the kernel config from /proc/config.gz

zcat /proc/config.gz | grep CONFIG_64BIT
# CONFIG_64BIT is not set

I'm not sure how portable you need it to be- it doesn't seem like a super common config option.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文