Linux:从32位用户模式程序检测64位内核(长模式)
检测32位用户模式程序是否在64位内核上运行(即系统是否处于“长模式”)的最佳和最可靠的方法是什么?如果可能的话,我宁愿不调用外部程序(或者必须加载任何内核模块) 注意:我想检测是否正在使用64位内核(或者CPU是否处于长模式),而不仅仅是检测是否存在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
/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);
}