zoukankan      html  css  js  c++  java
  • 检测目标程序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
    ");
            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
    process %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
    ", pid);
                break;
            }
            
            if(buf[4] && buf[5] && buf[6])
            {
                printf("process %d running in 32 bit elf mode @ line %d
    ", pid, __LINE__);
                printf("%x, %x, %x, %x
    ", buf[4], buf[5], buf[6], buf[7]);
                break;
            }
            else if(buf[7])
            {
                printf("process %d running in 32 bit elf mode
    ", pid);
                break;
            }
        } while(1);
    
        close(fd);
    
        return 0;
    }
    
    int main(int argc, char* argv[])
    {
        if(argc <= 1)
        {
            printf("usage:auxv pid1 [pid2 pid3 ...]
    ");
            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
  • 相关阅读:
    ndk安装
    android studio安装
    navicat15安装及激活
    relative和absolute理解
    meta标签大全
    爆炸、翻转、扭曲、立方、翻页特效
    CSS3-多媒体查询
    CSS3-按钮
    CSS3-图片
    css3-多列
  • 原文地址:https://www.cnblogs.com/jojodru/p/5564059.html
Copyright © 2011-2022 走看看