检测目标程序ELF bit是32还是64
android操作系统在5.0之后加入了对64位程序的支持,同时兼容运行32位的进程
android的进程绝大部分是zygote父进程fork出来的子进程
zygote进程fork出来的进程是32位进程
zygote64进程fork出来的进程是64位进程
但是有一些在zygote启动之前的进程,那就是init进程fork出来的,都属于64bit进程
zygote进程在fork出子进程之后,更改了进程的名字(setNiceName)
如果想根据进程名找到进程文件,通过读取elf头的方法来判断目标进程的elf bit
不是太理想
通过man proc查阅文档可以知道,解析目标进程的auxv文件可以判断elf bit
内核支持从2.6开始,android的内核版本在这之后,检测auxv文件判断elf bit是可靠的
先上makefile,Application.mk
APP_ABI := arm64-v8a APP_PLATFORM := android-21
只编译64位的版本,如果系统无法跑64位程序,证明整个系统都是32位的
Android.mk
# Copyright (C) 2009 The Android Open Source Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := auxv LOCAL_SRC_FILES := auxv.c LOCAL_ARM_MODE := arm include $(BUILD_EXECUTABLE)
源码auxv.c
#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> /* * Parsing auxv: if you parse the auxv structure yourself (not relying on the dynamic loader), then there's * a bit of a conundrum: the auxv structure follows the rule of the process it describes, so sizeof(unsigned * long) will be 4 for 32-bit processes and 8 for 64-bit processes. We can make this work for us. In * order for this to work on 32-bit systems, all key codes must be 0xffffffff or less. On a 64-bit system, * the most significant 32 bits will be zero. Intel machines are little endians, so these 32 bits follow * the least significant ones in memory. * As such, all you need to do is: * 1. Read 16 bytes from the `auxv` file. * 2. Is this the end of the file? * 3. Then it's a 64-bit process. * 4. Done. * 5. Is buf[4], buf[5], buf[6] or buf[7] non-zero? * 6. Then it's a 32-bit process. * 7. Done. * 8. Go to 1. */ int check_auxv(int pid) { if(pid < 0) { printf("invalid process id\n"); return -1; } char auxv[256]; snprintf(auxv, 256, "/proc/%d/auxv", pid); int fd = open(auxv, O_RDONLY); if(fd < 0) { printf("%s does not exist\nprocess %d maybe running in 32 bit elf mode", auxv, pid); return 0; } const int SIZE = 16; char buf[SIZE]; do { int nread = read(fd, buf, SIZE); if(nread < SIZE) { printf("process %d running in 64 bit elf mode\n", pid); break; } if(buf[4] && buf[5] && buf[6]) { printf("process %d running in 32 bit elf mode @ line %d\n", pid, __LINE__); printf("%x, %x, %x, %x\n", buf[4], buf[5], buf[6], buf[7]); break; } else if(buf[7]) { printf("process %d running in 32 bit elf mode\n", pid); break; } } while(1); close(fd); return 0; } int main(int argc, char* argv[]) { if(argc <= 1) { printf("usage:auxv pid1 [pid2 pid3 ...]\n"); return 0; } int i = 0; for(i = 1; i < argc; ++i) { int pid = atoi(argv[i]); check_auxv(pid); } return 0; }
编译命令
call ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=./Application.mk
目录结构
|---Application.mk |---build.bat |---jni ||---Android.mk ||---auxv.c