美文网首页安卓
【原创】如何检测Android应用是32位还是64位

【原创】如何检测Android应用是32位还是64位

作者: qiuyi943 | 来源:发表于2016-10-25 19:59 被阅读7705次
    本文为个人原创,欢迎转载,但请务必在明显位置注明出处!
    

    http://www.jianshu.com/p/8686931d31f0

    1、前言

    从Android 4.4宣布支持64位系统以来,各终端方案厂商逐步推出了各自的64位soc解决方案。Google为了兼容之前32位系统的应用,在64位系统上也实现了对32位应用的支持。那么问题就来了,在一个64位系统的Android手机上如何检测应用是运行在32位还是64位环境?本博文将为大家解答这个问题。

    本文会分别对Android系统中的App、Native进程以及动态链接库的32/64位检测方法进行介绍。

    2、检测App

    任何一个Android手机用户对APK文件肯定不会陌生,它是一个Android应用资源的封装文件。当你下载安装一个App之后,从Launcher启动该应用,系统会由Zygote分叉出一个子进程来提供App运行的虚拟机和Runtime环境。与32位系统不同的是,在64系统中会同时存在两个Zygote进程——zygote和zygote64,分别对应32位和64位应用。所以,要进行App的32/64位检测,只需要看它的父进程是哪个Zygote即可。

    下面的例子通过App的PPID信息——2759,检测出了终端系统中所有的64位应用,且该方式无需root权限。

    $ adb shell ps |grep zygote
    root      2759  1     2131692 87052          0 0000000000 S zygote64
    root      2760  1     1574048 53740          0 0000000000 S zygote
    
    $ adb shell ps|grep 2759
    root      2759  1     2131692 87052          0 0000000000 S zygote64
    system    3257  2759  2339956 158936          0 0000000000 S system_server
    radio     3393  2759  1601272 96220          0 0000000000 S com.android.phone
    u0_a85    3407  2759  1564856 88740          0 0000000000 S com.android.inputmethod.latin
    u0_a20    3422  2759  1970228 167288          0 0000000000 S com.android.systemui
    u0_a7     3769  2759  1548288 63384          0 0000000000 S android.ext.services
    u0_a13    3958  2759  1896704 131832          0 0000000000 S com.android.launcher3
    u0_a6     3989  2759  1562416 94060          0 0000000000 S android.process.acore
    u0_a17    4046  2759  1563300 88504          0 0000000000 S android.process.media
    u0_a28    4112  2759  1555640 82004          0 0000000000 S com.android.quicksearchbox
    u0_a64    4157  2759  1554484 72944          0 0000000000 S com.android.calendar
    u0_a57    4215  2759  1572160 83532          0 0000000000 S com.android.email
    u0_a77    4231  2759  1554408 67192          0 0000000000 S com.android.exchange
    u0_a5     4279  2759  1549136 66072          0 0000000000 S com.android.onetimeinitializer
    u0_a10    4299  2759  1552472 74088          0 0000000000 S com.android.providers.calendar
    u0_a94    4325  2759  1869948 112984          0 0000000000 S com.android.soundrecorder
    system    4345  2759  1561180 73680          0 0000000000 S com.sprd.engineermode
    u0_a15    4887  2759  1874612 106196          0 0000000000 S com.android.packageinstaller
    u0_a73    5133  2759  2425904 205912          0 0000000000 S com.android.browser
    

    3、检测Native进程

    Andorid手机开机启动之后,init进程会启动一些后台守护进程。通常,这些进程会对整个Android系统起到重要作用,例如Zygote、MediaServer和ServiceManager等。因为这些Native进程并不是通过安装APK获得,所以上一章节的方法在这里并不适用。我们知道Andorid Framework层以下都是继承自Linux,因此可以采用Linux系统的一些工具和方法来对Native进程进行32/64位系统的检测。

    方法一,通过readelf工具来分析Native进程对应的bin文件,下面以mediaserver为例

    $readelf -h mediaserver 
    ELF Header:
      Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
      Class:                             ELF32
      Data:                              2's complement, little endian
      Version:                           1 (current)
      OS/ABI:                            UNIX - System V
      ABI Version:                       0
      Type:                              DYN (Shared object file)
      Machine:                           ARM
      Version:                           0x1
      Entry point address:               0x1e24
      Start of program headers:          52 (bytes into file)
      Start of section headers:          20980 (bytes into file)
      Flags:                             0x5000000, Version5 EABI
      Size of this header:               52 (bytes)
      Size of program headers:           32 (bytes)
      Number of program headers:         9
      Size of section headers:           40 (bytes)
      Number of section headers:         29
      Section header string table index: 28
    

    从上面的信息中我们看到mediaserver文件的Class字段为ELF32,Machine字段为ARM。由此可知,在Android 64位系统中,mediaserver运行在32位环境中。

    方法二,在运行时通过打印Native进程的内存映射列表(maps)来检测32/64位,这个方法同样也适用于App的32/64位检测。这里以com.android.email为例,从上一章节的进程列表打印可以看到,com.android.email的PID为4215。

    u0_a57    4215  2759  1572160 83532          0 0000000000 S com.android.email
    

    然后,通过proc文件系统便可查询到PID=4215的内存映射列表 (截取片段)

    $adb root
    $adb shell cat /proc/4215/maps
    ......
    71ebcb1000-71ebcb3000 r-xp 00000000 103:15 1453                          /system/lib64/libOpenSLES.so
    71ebcb3000-71ebcb4000 r--p 00001000 103:15 1453                          /system/lib64/libOpenSLES.so
    71ebcb4000-71ebcb5000 rw-p 00002000 103:15 1453                          /system/lib64/libOpenSLES.so
    71ebcb5000-71ebcd5000 r--s 00000000 00:12 282                            /dev/__properties__/u:object_r:logd_prop:s0
    71ebcd5000-71ebcf5000 r--s 00000000 00:12 287                            /dev/__properties__/u:object_r:log_tag_prop:s0
    71ebcf5000-71ebcf6000 r--p 00000000 00:00 0                              [anon:linker_alloc]
    71ebcf6000-71ebcf7000 rw-p 00000000 00:00 0                              [anon:linker_alloc_vector]
    71ebcf7000-71ebcf8000 r--p 00000000 00:00 0                              [anon:linker_alloc]
    71ebcf8000-71ebcf9000 rw-p 00000000 00:00 0                              [anon:linker_alloc]
    71ebcf9000-71ebcfb000 r-xp 00000000 103:15 1452                          /system/lib64/libOpenMAXAL.so
    71ebcfb000-71ebcfc000 r--p 00001000 103:15 1452                          /system/lib64/libOpenMAXAL.so
    71ebcfc000-71ebcfd000 rw-p 00002000 103:15 1452                          /system/lib64/libOpenMAXAL.so
    71ebcfd000-71ebcff000 rw-p 00000000 00:01 22281                          /dev/ashmem/dalvik-indirect ref table (deleted)
    71ebcff000-71ebd00000 r-xp 00000000 103:15 1565                          /system/lib64/libjnigraphics.so
    71ebd00000-71ebd01000 r--p 00000000 103:15 1565                          /system/lib64/libjnigraphics.so
    71ebd01000-71ebd02000 rw-p 00001000 103:15 1565                          /system/lib64/libjnigraphics.so
    71ebd02000-71ebd04000 rw-p 00000000 00:01 22280                          /dev/ashmem/dalvik-indirect ref table (deleted)
    71ebd04000-71ebd05000 r-xp 00000000 103:15 1644                          /system/lib64/libsigchain.so
    71ebd05000-71ebd06000 r--p 00000000 103:15 1644                          /system/lib64/libsigchain.so
    71ebd06000-71ebd07000 rw-p 00001000 103:15 1644                          /system/lib64/libsigchain.so
    ......
    

    从上面的打印中可以看出,com.android.email加载的动态链接库均位于/system/lib64。由此便可判断com.android.email运行于64位环境。需要注意的是这个方法要root权限才能检测。

    4、检测动态链接库(*.so文件)

    如果想要对一个.so文件的进行32/64位检测,那么采用上一章节中的方法一就可以做到。但是,有native开发经验的读者应该知道,64位系统中动态链接库通常会同时存在32位和64位两个版本,它们分别位于/system/lib和/system/lib64路径中。所以,孤立地对某一个.so文件进行32位/64位检测并没有现实意义,应该将其与加载该.so文件的App或Native进程作为一个整体来分析。

    5、后语

    本文分别对Android系统中App、Native进程和动态链接库进行32/64位检测的方法进行了介绍,希望对大家的学习开发工作有所帮助。

    相关文章

      网友评论

        本文标题:【原创】如何检测Android应用是32位还是64位

        本文链接:https://www.haomeiwen.com/subject/yhoruttx.html