吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 21924|回复: 19
收起左侧

[Android 原创] 实验app-授权KEY破解

[复制链接]
PJ头狼 发表于 2016-8-18 22:11
实操了一个小实验apk,加深对smali语法的学习,并分享一下分析过程,大神请绕过~~~

针对授权KEY方式的app破解

实验app:freeapp.apk

这是一个程序中本身是具备完整功能的app(进入专业版界面),现在是只提供了免费版功能(只有免费版界面),当给用户提供一个拥有授权KEY的apk文件,让其安装上该授权文件,便可获得高级版功能或专业版功能(进入高级版界面或专业版界面)

各个功能版本界面如下图

                                                                                                                                          
   
   
   现在,想在没有拿到授权KEY的情况下,使程序跳过对授权KEY的检查,直接获得软件高级版/专业版

首先是运用apktool对apk进行反编译来得到smali反汇编代码


接着找到onCreate()方法所在的文件并在文件中确定其位置,这个程序的onCreate()可以在MainAcitity.smali文件中找到,代码如下

.method publiconCreate(Landroid/os/Bundle;)V
   .locals 4
   .param p1, "savedInstanceState"    # Landroid/os/Bundle;
   .prologue
   const/4 v3, 0x0
   .line 24

invoke-super{p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V

   .line 25
   const/high16 v2, 0x7f030000
  invoke-virtual {p0, v2}, Lcom/droider/free/MainActivity;->setContentView(I)V

一开始这些是activity创建以及加载布局

接下来的这几行便有了第一处跳转的判断,通过执行checkappKey()方法后,对其返回值进行判断是否要进行跳转
   .line 27
   const/4 v0, 0x0
   .line 28
   .local v0, "resID":I

invoke-direct{p0}, Lcom/droider/free/MainActivity;->checkappKey()Z

   move-result v2
   if-nez v2, :cond_2

先不具体查看checkappKey()方法是怎么检查的,当v2等于0时,就不跳转到cond_2,直接继续往下

.line29

   const v0, 0x7f040001  #这里其实是字符串ID: Android安全软件免费版
#接下来的代码便是以这个字符串ID来设置为activity的标题,也就是说上一步如果没有跳转的话,便是进入免费版界面
   :cond_0
   :goto_0
   invoke-virtual {p0, v0}, Lcom/droider/free/MainActivity;->getString(I)Ljava/lang/String;
   move-result-object v1
   .local v1, "titleString":Ljava/lang/String;
   invoke-virtual {p0, v1}, Lcom/droider/free/MainActivity;->setTitle(Ljava/lang/CharSequence;)V
    …....   #这里省略部分代码,都是像下边这样对Button的布局
    …...
    .line 39
   const v2, 0x7f070002
   invoke-virtual {p0, v2},Lcom/droider/free/MainActivity;->findViewById(I)Landroid/view/View;
   move-result-object v2
   check-cast v2, Landroid/widget/Button;
    iput-object v2, p0, Lcom/droider/free/MainActivity;->btn_pro:Landroid/widget/Button;
   
#上边如果一直保持一开始的没有跳转,v0还是0x7f040001:免费版
   .line 50
   const v2, 0x7f040002    #这里是字符串ID:Android安全软件高级版
   if-ne v0, v2, :cond_3  #而由于v0还是0x7f040001所有跳转到cond_3

#如果没有跳转的话便是执行下边几行,可以看出是将高级版本按钮呈现出来

iget-objectv2, p0, Lcom/droider/free/MainActivity;->btn_advanced:Landroid/widget/Button;

invoke-virtual{v2, v3}, Landroid/widget/Button;->setVisibility(I)V

   .line 57
#其实上边如果跳转到cond_3的话,由于v0是0x7f040001,又会跳回到下边的cond_1,也就是跳过了上边对高级版按钮的设置
   :cond_1
    :goto_1
   iget-object v2, p0, Lcom/droider/free/MainActivity;->btn_free:Landroid/widget/Button;
   new-instance v3, Lcom/droider/free/MainActivity$1;
   invoke-direct {v3, p0},Lcom/droider/free/MainActivity$1;-><init>(Lcom/droider/free/MainActivity;)V

invoke-virtual{v2, v3}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V

   …....
   …....
    invoke-virtual {v2, v3},Landroid/widget/Button;->           
    setOnClickListener(Landroid/view/View$OnClickListener;)V   .line 86
   return-void
#跳回到cond_1后便是像上边这样对按钮的监听事件进行设置,然后便是return,onCreate()方法返回,这也就是免费版的执行过程

那如果从一开始就在checkappKey()方法返回结果后,成功跳转,便来到了cond_2,这里则是通过getAppKey()方法对KEY进行获取,并通过decryptAppKey()方法对KEY值进行解密
   :cond_2
   const v2, 0x7f030001

invoke-direct{p0, v2}, Lcom/droider/free/MainActivity;->getAppKey(I)Ljava/lang/String;

    move-result-object v2

invoke-direct{p0, v2}, Lcom/droider/free/MainActivity;->decryptAppKey(Ljava/lang/String;)I

   move-result v0    #v0的值将有可能是0/高级版字符串ID/专业版字符串ID
   if-nez v0, :cond_0  #如果非0,v0的值便保持高级/专业版的ID返回到cond_0
   
#回到cond_0,便是像上边写的进行button的布局,并通过v0的值来判断是否能够进入到高级/专业版的按钮呈现设置
   .line 33
   const v0, 0x7f040001   #如果不跳转,v0的值便设为免费版字符串ID
   goto :goto_0  #再跳回到cond_0下边的goto_0继续button的布局

而上边还有一处便是是否跳转到cond_3,上边是假设v0=0x7f040001,那当v0在获取KEY后,其值是0x7f040002/0x7f040003即高级/专业:
   const v2, 0x7f040002    #这里是字符串ID:Android安全软件高级版

if-nev0, v2,:cond_3 #如果v0是0x7f040003(专业) 则也跳转到cond_3


#如果没有跳转的话便是执行下边几行,可以看出是将高级版本按钮呈现出来

iget-objectv2, p0, Lcom/droider/free/MainActivity;->btn_advanced:Landroid/widget/Button;

invoke-virtual{v2, v3}, Landroid/widget/Button;->setVisibility(I)V


那cond_3处是这样的:
:cond_3
   const v2, 0x7f040003  #字符串ID:Android安全软件专业版
   if-ne v0, v2, :cond_1    #当v0=0x7f040003而非0x7f040001便不会跳转
#下边便是没有跳转执行的几行,没错,是对高级按钮以及专业按钮功能的呈现,便进入了专业版界面
   .line 53
   iget-object v2, p0, Lcom/droider/free/MainActivity;->btn_advanced:Landroid/widget/Button;

invoke-virtual{v2, v3}, Landroid/widget/Button;->setVisibility(I)V

   iget-object v2, p0, Lcom/droider/free/MainActivity;->btn_pro:Landroid/widget/Button;

invoke-virtual{v2, v3}, Landroid/widget/Button;->setVisibility(I)V

   goto :goto_1    #按钮呈现完好便继续回到goto_1,进行按钮监听事件的设置
.end method

这就是免费版/高级版/专业版界面进入的实现过程,主要的关键突破点便是首先在checkappKey()方法上检查通过,然后在跳转后decryptAppKey()在返回ID是返回空/高级字符串ID/专业字符串ID,也即就是最后决定v0的值为0x7f040001/0x7f040002/0x7f040003

所以想要破解该程序,使进入高级版/专业版,就是要先跳过checkappKey()方法

invoke-direct{p0}, Lcom/droider/free/MainActivity;->checkappKey()Z

    move-result v2
    if-nez v2, :cond_2
这里直接将对方法的调用直接删除掉,然后保证v2的值不等于0,便跳转到cond_2
    const  v2,0x01
    if-nezv2,:cond_2

然后便是来到cond_2处
   :cond_2
   const v2, 0x7f030001
    invoke-direct{p0, v2}, Lcom/droider/free/MainActivity;->getAppKey(I) Ljava/lang/String;
   move-result-object v2
    invoke-direct{p0, v2}, Lcom/droider/free/MainActivity;->decryptAppKey (Ljava/lang/String;)I
   move-result v0    #v0的值将有可能是0/高级版字符串ID/专业版字符串ID
   if-nez v0, :cond_0  #如果非0,v0的值便保持高级/专业版的ID返回到cond_0

这里也直接将getAppKey()/decryptAppKey()两个方法的调用删除掉,然后当想进入高级版界面则将v0的值设为 0x7f040002,想进入专业版便将v0设为 0x7f040003
   :cond_2

const v00x7f040002  /  const v0 0x7f040003

if-nezv0, :cond_0

当代码修改完成后保存,再使用apktool进来刚刚反编译成的目录,打包为apk,在该目录下的dist目录便可找到生成的apk文件


在运用jarsigner对其重签名(前提得先创建一个keystore)


在MainActivity.smali文件也有上边三个方法调用的反汇编代码,其中checkappKey()方法中是通过调用getAppKey()方法来确定是否能获取KEY,成功返回1,否为0
而getAppKey()方法则是通过其中的createPackageContxt()方法来创建授权KEY文件的Context,然后通过这个Context来访问授权KEY文件的资源,也即就是加密的字符串,通过decryptAppKey()方法来解密返回字符串。
一个程序要通过createPackageContext()方法来获取其他程序的Context,再通过Context来访问其他程序的资源,需要拥有相同的用户ID与签名,用户ID是一个字符串标识,在AndroidManifest.xml文件的manifest标签中将属性android:sharedUserId=”xxx.xxx.xxx”,当两个程序拥有相同的用户ID,便会运行在同一个进程空间,资源可以相互访问;如果签名也相同,则还可以相互执行软件包之间的代码。

crackme.zip

434.01 KB, 下载次数: 108, 下载积分: 吾爱币 -1 CB

文章的pdf和实验apk

免费评分

参与人数 1热心值 +1 收起 理由
yule5216 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2016-8-19 10:21
图片没上传?我这边都无法显示。
侧耳i 发表于 2016-8-19 11:20
本帖最后由 侧耳i 于 2016-8-19 11:40 编辑

为什么没有图片,请迅速补图,顶大神

凉米饭 发表于 2016-8-19 11:21
牵走天涯 发表于 2016-8-19 11:21
可以,收藏一波,学习
我是一只小小白 发表于 2016-8-19 11:34
看不到图片  这TM就很尴尬了
jasidy 发表于 2016-8-19 11:39
谢谢楼主提供好工具。
我来看看看 发表于 2016-8-19 14:16
学习一下
 楼主| PJ头狼 发表于 2016-8-19 21:51
我将图片直接复制到贴子里,不知道怎么没显示,不过图不重要,压缩包里有pdf
吾爱丶筱豪 发表于 2016-8-21 21:22
有加密咋整不会脱壳  查了下是百度加固
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-1 12:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表