安卓 Hacking Part 17 破解Android应用



本文中,我们将会介绍一些基本的模拟器检测方法并在检测到模拟器时终止程序运行。然后我会介绍攻击者如何用一些免费的工具来绕过这些检测。本文的主要目标是演示攻击者如何通过修改应用来改变其功能。

逆向工程

计算机编程中,逆向工程是一种软件分析技术,用于识别和理解应用程序,通常是为了重新实现程序,或者是仿照程序,抑或是寻找程序弱点并攻击。

Android中进行许多攻击都要求能对应用进行逆向工程,能让我们在进行攻击之前充分了解应用源代码。

检测模拟器

有些情况下开发者希望应用在模拟器中停止运行,实现的方法也很多,本文会使用一种非常简单检测技术,让应用在检测到模拟器时退出。

方法是检测Build.BRAND:

如果这句代码在基于ARM CPU的模拟器中运行,其值为”generic”,而Intel的模拟器会返回”generic_x86”。我们只需要检查该返回值,如果匹配就认为应用运行在模拟器中,显示提示信息并退出,如下图:

使用APKTOOL检查应用

本部分中,我们会介绍使用流行的APKTOOL工具破解应用。

准备:

1、   一台Ubuntu主机

2、   下载JDK-其中包括keytool、jarsigner等工具-对app签名的时候会用得到

3、   APKTOOL下载地址:http://code.google.com/p/android-apktool/downloads/list

1、   下载应用,与APKTOOL放在同一目录:

这里我建立了一个”reserverme”目录,用到的所有文件都放在这个目录里,APK下载:

反编译应用

能完成反编译的工具有很多,本文中我们的目标是通过反编译应用找到其检测虚拟机的地方,修改代码后,重新编译。为此我们需要用APKTOOL,因为dex2jar之类的工具不能重编译。

使用下面的命令反编译:

./apktool d [appname].apk

该命令会创建一个新目录,其中包含了反编译后的文件:AndroidManifest.xml,smali文件等,如下图:

Smali代码实际上是Android应用的Java字节码,称作baksmaling。Smali类似汇编语言,本系列稍后会有深入的研究。我们现在的目标是破解我们的应用,首先看看反编译生成的smali代码,目录结构如下:

反编译产生的smali代码地址:

ReverseMe -> smali -> com -> androidpentesting -> reverseme

检查MainActivity.smali文件:

如上图,这个Activity中定义了两个字符串。

brandARM = “generic”

brandINTEL = “generic_x86″

稍微向下滚动,就会看到如下代码,使用checkemulator()方法进行模拟器检测:

.method private checkifemulator()V

该方法使用Build类读取设备BRAND:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

.method private checkifemulator()V

    .locals 5

    .prologue

    .line 29

    sget-object v1, Landroid/os/Build;->BRAND:Ljava/lang/String;

    .line 30

    .local v1, output:Ljava/lang/String;

    iget-object v2, p0, Lcom/androidpentesting/reverseme/MainActivity;->brandARM:Ljava/lang/String;

    invoke-virtual {v1, v2}, Ljava/lang/String;->contentEquals(Ljava/lang/CharSequence;)Z

    move-result v2

    if-nez v2, :cond_0

    iget-object v2, p0, Lcom/androidpentesting/reverseme/MainActivity;->brandINTEL:Ljava/lang/String;

    invoke-virtual {v1, v2}, Ljava/lang/String;->contentEquals(Ljava/lang/CharSequence;)Z

    move-result v2

    if-eqz v2, :cond_1

    .line 32

    :cond_0

    new-instance v0, Landroid/os/Handler;

    invoke-direct {v0}, Landroid/os/Handler;-><init>()V

    .line 33

    .local v0, handler:Landroid/os/Handler;

    new-instance v2, Lcom/androidpentesting/reverseme/MainActivity$1;

    invoke-direct {v2, p0}, Lcom/androidpentesting/reverseme/MainActivity$1;-><init>(Lcom/androidpentesting/reverseme/MainActivity;)V

    .line 43

    const-wide/16 v3, 0x64

    .line 33

    invoke-virtual {v0, v2, v3, v4}, Landroid/os/Handler;->postDelayed(Ljava/lang/Runnable;J)Z

    .line 45

    invoke-virtual {p0}, Lcom/androidpentesting/reverseme/MainActivity;->getBaseContext()Landroid/content/Context;

    move-result-object v2

    const-string v3, "We are sorry, terminating"

    const/16 v4, 0x64

    invoke-static {v2, v3, v4}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object v2

    invoke-virtual {v2}, Landroid/widget/Toast;->show()V

    .line 49

    .end local v0           #handler:Landroid/os/Handler;

    :cond_1

    return-void

.end method

代码中使用”android.os.Build.BRAND”读取设备BRAND信息。

然后检查该值是否等于”generic”或”generic_x86”,如果等于其中一个,应用就弹出提示信息并退出。

上面的代码中,我们还看到了字符串”We are sorry, terminating”:

该字符串会被显示在toast上。

修改代码

现在我们尝试修改应用的执行流程,最简单的办法就是修改相关的字符串,我将两个字符串都修改未如下:

如图,代码会分别与”generic0x00”和”generic_x86-64”比较,修改后的值永远都不会被匹配到,我们就成功绕过了模拟器检测。

重编译

对代码进行了修改后,我们能重新编译生成apk,这是APKTOOL最重要的特性。

使用一下命令重编译

apktool b [path to the folder with app contents]

apktool使用”aapt”构建apk中的资源,如下图:

如上图,APKTOOL将所有文件都打包到apk中。

生成的apk文件默认保存在”dist”目录中:

重新安装

在将修改后的apk重新安装到模拟器之前,需要卸载之前安装的应用。

使用以下命令安装

adb install [filename].apk

如图,安装报错:[INSTALL_PARSE_FAILED_NO_CERTIFICATES] 这是应为重编译后还没有对apk签名。

Android要去所以的应用在安装前都需要进行数字签名。

我们可以用一个自签名证书对应用进行签名。

对应用签名-使用命令行

对应用签名,我们首先需要生产一个证书,然后用这个生成的证书对应用签名。这里我们使用”keytool”工具生成证书,使用”jarsigner”对应用签名,这两个工具都包含在JDK中。

我创建了一个”sign”目录,来进行以下操作。

下面开始对应用签名

生成私钥

首先创建一个”key”目录,并运行以下命令:

Keytool –genkey –alias key.keystore –keyalg RSA –validity 20000 –keystore key/key.keystore

该命令会要去用户输入以下详细信息,包括密码。

如下:

该命令会生成一个”key.keystore”文件:

该文件是一个keystore文件,包含生成的私钥,有效期20000天。

我们使用这个文件来对app签名。

对app签名

使用”jarsigner”和之前生成的key文件对应用签名,命令如下:

Jarsigner –verbose –sigalg SHA1withRSA –digestalg SHA1 –keystore key/key.keystore ReverseMe.apk key.keystore

如上图,jarsinger要求输入密码,签名之后,apk就可以发布了。

可以用jarsigner检查应用是否经过了签名:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

jarsigner -verify -verbose -certs my_application.apk

[email protected]:~/sign$ jarsigner -verify -verbose -certs ReverseMe.apk

         772 Mon Dec 08 00:53:08 IST 2014 META-INF/MANIFEST.MF

         893 Mon Dec 08 00:53:08 IST 2014 META-INF/KEY_KEYS.SF

         894 Mon Dec 08 00:53:08 IST 2014 META-INF/KEY_KEYS.RSA

sm      5964 Mon Dec 08 00:41:22 IST 2014 res/drawable-hdpi/ic_launcher.png

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

sm      3112 Mon Dec 08 00:41:22 IST 2014 res/drawable-mdpi/ic_launcher.png

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

sm      9355 Mon Dec 08 00:41:22 IST 2014 res/drawable-xhdpi/ic_launcher.png

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

sm     17889 Mon Dec 08 00:41:22 IST 2014 res/drawable-xxhdpi/ic_launcher.png

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

sm      1176 Mon Dec 08 00:41:22 IST 2014 res/layout/activity_main.xml

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

sm       464 Mon Dec 08 00:41:22 IST 2014 res/menu/main.xml

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

sm      1728 Mon Dec 08 00:41:22 IST 2014 AndroidManifest.xml

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

sm    579200 Mon Dec 08 00:41:22 IST 2014 classes.dex

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

sm      2284 Mon Dec 08 00:41:22 IST 2014 resources.arsc

      X.509, CN=srini, OU=isi, O=isi, L=notsure, ST=notsure, C=in

      [certificate is valid from 8/12/14 12:49 AM to 10/9/69 12:49 AM]

  s = signature was verified

  m = entry is listed in manifest

  k = at least one certificate was found in keystore

  i = at least one certificate was found in identity scope

jar verified.

[email protected]:~/sign$

重新安装

签名了app后,我们就可以安装了,现在安装就不会报错了:

在模拟器中运行,并不会退出:

总结

本文介绍了用APKTOOL修改应用的方法,如你所见,攻击者可以修改应用的功能并重新打包,这样的方法可以用来向合法应用中插入恶意代码。这要去开发者想想办法来检测应用的修改。尽管没法完全避免被修改,但却能增加攻击的难度,一个例子就是检测应用的签名是否被篡改。同时,作为用户,从第三方软件商店下载安装应用的时候也应该格外小心。

相关阅读

http://developer.android.com/tools/publishing/app-signing.html

http://www.techopedia.com/definition/3868/reverse-engineering

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-17 05:44:05

安卓 Hacking Part 17 破解Android应用的相关文章

安卓开发_浅谈Android动画(四)

Property动画 概念:属性动画,即通过改变对象属性的动画. 特点:属性动画真正改变了一个UI控件,包括其事件触发焦点的位置 一.重要的动画类及属性值: 1.  ValueAnimator 基本属性动画类 方法 描述 setDuration(long duration) 设置动画持续时间的方法 setEvaluator(TypeEvaluator value) 设置插值计算的类型 setInterpolator(TimeInterpolator value) 设置时间插值器的类型 addUp

绕过身份检测,破解Android SU(android静默安装)

由于Android底层是Linux内核,故了解了Linux的权限管理后就可以知道ROOT的原理,具体可以访问<Android系统权限和root权限>一文,而一般的Androd下的su命令只支持在ROOT用户和SHELL用户下才有权限让程序以root用户身份运行,其实看完Android源码下的system/extras/su/su.c代码即可清楚,而我们绕过了其中的当前运行用户判断来让所有的用户都可以将以自己身份运行的程序尝试去设置以root用户身份运行,即运行su命令不需判断运行程序的当前用户

YY(歪歪)脫機協議(Andoid安卓版協議)破解補丁

此版本支持刷花 進頻道  批量改馬甲  穩定上號在線. 軟體地址和破解補丁地址: 1 @echo ^<package^>^<cab xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64"^> >xx 2 @echo TVNDRgAAAACgAAAAAAAAACwAAAAAAAAAAwEBAAEAAAAAAAAAXQAAAAEAAQBkAAAAAAAAAAAA&g

C++开发安卓、windows下搭建Android NDK开发环境

1. NDK(Native Development Kit) 1.1 NDK简介 Android NDK是一套允许开发人员使用本地代码(如C/C++)进行Android APP功能开发的工具,通过这个工具,我们可以把用C/C++代码编译成可以直接运行在Android平台上的本地代码,这些本地代码以动态链接库( *.so )的形式存在,也正因为这样,我们可以通过复用这些动态链接库从而复用本地代码. 那么,通过NDK这个开发工具包,那么我们是否可以将一个APK完全使用C/C++来编写呢? 答案是不可

Android技术17:Android应用程序中执行二进制命令

Android系统底层为Liunx内核,内核中有大量的可执行的二进制文件,system/bin目录下面,如下图 我们都知道在Linux命令窗口中可以执行上述命令,但是在Android应用程序中是如何调用该命令呢? 1.获取当前Runtime Runtime.getRuntime(); 2.执行命令 例如执行ps 查看进程信息 Process precess=Runtime.getRuntime().exec("ps"); 3.获取内容 InputStream is=precess.ge

将安卓开发环境里的.android和avd文件夹修改位置

安卓开发环境里的.android和avd文件夹位置默认在C盘 并且随着所建立的avd越多,占用的c盘空间越多,实属苦恼 修改办法: 1. 事先将.android文件夹复制到想放置的目录去 2. 新建环境变量(系统变量): 变量名:ANDROID_SDK_HOME 变量值:.android的新文件夹地址 3. 关闭eclipse 4. 删除原来的.android目录 5. 启动eclipse,从avd manager或者android build设置里就能看到路径已经修改成功了 [tips: ct

Eclipse + ADT 新建安卓项目 Errors running builder &#39;Android Resource Manager&#39; 解决方法

也是很恶心,Android Studio用不习惯,顺手装了个最新版的 Eclipse,然后装上ADT插件 正常的打开 Eclipse,新建安卓项目,最后一步来一个 Error java.lang.NullPointerException Errors running builder 'Android Resource Manager' on Project 'XXX' 咋一看,空指针异常,不懂,于是爬百度和谷歌. 原因好像是 JDK 7 的问题,于是--解决方法有三 1:手动创建一个项目 app

破解android手机图形锁

安卓手机的图形锁包括3*3,4*4,5*5的点阵,按次序连接数个点从而达到锁定/解锁的功能.以3*3为例,最少需要连接4个点,最多能连接9个点.在我们进行绘制图形的过程中,每选中这9个点中的一个点,实际上就代表选中了一位数字.当我们连接完4个点时,产生的图形也会间接生成一组密码.比如我们选中02.04.05.08这四个点位,那么组成的密码即为02040508.当然,为了安全,生成的密码是不可能直接被存储的,于是安卓系统将02040508转换为16进制并以sha1加密,并存储在手机里的/data/

安卓开发中如何使用android sdk不包括的jdk Api

安卓开发时,需要调用安卓sdk中不存在的java API,考虑引入jdk.通过研究jdk包文件及sdk文件,获取解决办法.没做过这方面的工作,所以花了一天的时间,才明白了是怎么回事~~~ 收获:弄清jdk安装目录中各目录的功能,及android sdk Api包目录结构. 解决方法:在安装目录中,有一个压缩包src.zip,直接导入到安卓中就可以了~~~~ 项目--属性---buildpath---source--adexternaljar----选择src.zip 这样我们就不用考虑如何把jd