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

本文为个人原创,欢迎转载,但请务必在明显位置注明出处!

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位检测的方法进行了介绍,希望对大家的学习开发工作有所帮助。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,056评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,842评论 2 378
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,938评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,296评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,292评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,413评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,824评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,493评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,686评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,502评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,553评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,281评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,820评论 3 305
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,873评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,109评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,699评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,257评论 2 341

推荐阅读更多精彩内容