首页
论坛
课程
招聘
[原创] apk破解之“异常”破解
2013-5-13 11:21 82018

[原创] apk破解之“异常”破解

2013-5-13 11:21
82018
这次拿到一个新的apk,作者在上一次破解之后已经重写的代码,破解的关键也换了位置了,这次作者主要用到了异常,当在服务器上验证无该用户的数据时就会返回0,然后在调用parseInt方法时就会发生NumberFormatException异常,进而调用处理异常的代码,也就是提示“不成功”

注意:该文章用于技术交流,请不要用于非法破解,本人概不负责,错误疏漏之处还望海涵
  apk下载地址:
  http://pan.baidu.com/share/link?shareid=512221&uk=201738998
  破解工具:这个是一个IDE 集成了反编译,回编,adb等等工具,非常不错 可以玩玩
  标 题: 【下载】APK可视化修改工具:APK改之理(APK IDE)
  作 者: 青椒
  时 间: 2013-04-10,11:03:12
   链 接: http://bbs.pediy.com/showthread.php?t=168001

  视频地址:
http://pan.baidu.com/share/link?shareid=514534&uk=201738998

  apk描述:apk正常安装后,需要注册,点击注册软件后,会有两个按钮,点击找回注册,正常情况下会显示“不成功”
  如图:
  
   
   apk破解过程:
   (1)该apk的文字提示将成为我们的利用对象,注册成功会提示"成功",当然你也可以找不成功,因为代码就在附近

  (2)在apk改之理右上角的"替换和搜索"窗口中输入字符串"成功", 然后在"替换和搜索"窗口的下拉菜单中选择"转换为Uncode"
    点击“搜索全部”按钮

(3)点击搜索之后,在搜索结果窗口中会出现全部出现“成功”的文件,如图,其中选中的文件就是注册模块,也就是
  BqimenDateInputActivity.smali。其中还有一个文件是BqimenDateInputActivityW.smali,这个文件是繁体版的注册模块,我们无需理会(如果你问 为什么这个就是注册的文件,你可以观察该文件中的字符串,以及文件名就可以了解,他就是注册模块)
  
 (4)双击BqimenDateInputActivity.smali将会自动打开该文件,并且定位到该字符出现的位置,定位到该方法的开始位置,详细请看代码的注释
  
 
  @可以看到注册的方法名称为s,参数为Lcom/forace/Bqimen/BqimenActivity/BqimenDa
  @teInputActivity,背后的V为无返回值
 @另外值得注意的是字段synthetic ,该字段是编译器合成的,非作者添加的,也就是如果
 @你使用java DeCompiler进程查看
 @Java级别的源码时,这些代码是看不到的,这也就是之前我搜索“成功”之类的字符串搜索不到的原因
  .method static synthetic s(Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;)V
   


(5)既然找到了源头,我们就顺藤摸瓜往下看看 作者到底做了什么,代码如下,详情请看注释
  第一段代码:
  
.method static synthetic s(Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;)V
    .locals 4

    :try_start_0  @添加异常代码
    new-instance v0, Ljava/lang/StringBuilder;  @添加字符串实例

    const-string v1, "QM"  @将QM初始化为QM

    invoke-direct {v0, v1}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V    @用QV初始化字符串
    @获取getIMEI号
    invoke-virtual {p0}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->getIMEI()Ljava/lang/String;

    move-result-object v1

    invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v0
  @得到注册表
    invoke-virtual {p0, v0}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->regetkey(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v1
[COLOR="Red"]@程序的关键

    const-string v0, ""

    new-instance v2, Lorg/apache/http/client/methods/HttpGet;

    invoke-direct {v2, v1}, Lorg/apache/http/client/methods/HttpGet;-><init>(Ljava/lang/String;)V

    new-instance v1, Lorg/apache/http/impl/client/DefaultHttpClient;

    invoke-direct {v1}, Lorg/apache/http/impl/client/DefaultHttpClient;-><init>()V

    invoke-virtual {v1, v2}, Lorg/apache/http/impl/client/DefaultHttpClient;->execute(Lorg/apache/http/client/methods/HttpUriRequest;)Lorg/apache/http/HttpResponse;

    move-result-object v1

    invoke-interface {v1}, Lorg/apache/http/HttpResponse;->getStatusLine()Lorg/apache/http/StatusLine;

    move-result-object v2

    invoke-interface {v2}, Lorg/apache/http/StatusLine;->getStatusCode()I

    move-result v2   @将返回的结果赋给v2
@这段是初始化链接,链接作者服务器的地方,如果找到用户的信息则返回非0的字符串,如果找不到则返回0    

   const/16 v3, 0xc8
   @将v2和0xc8相比,如果不相等则调转到cond_0,如果相等,则不跳转那么下执行提示“网络异常”[/COLOR]    
if-ne v2, v3, :cond_0  
    invoke-interface {v1}, Lorg/apache/http/HttpResponse;->getEntity()Lorg/apache/http/HttpEntity;

    move-result-object v0

    const-string v1, "UTF-8"

    invoke-static {v0, v1}, Lorg/apache/http/util/EntityUtils;->toString(Lorg/apache/http/HttpEntity;Ljava/lang/String;)Ljava/lang/String;
    :try_end_0
    @双层异常,嵌套的异常,如果执行到这里说明网络不通畅,捕获ClientProtocolException异常,执行catch_0,提示网络异
  @常错误403,当catch_0没能处理异常,那么会给catch_1处理
    
    .catch Lorg/apache/http/client/ClientProtocolException; {:try_start_0 .. :try_end_0} :catch_0
    .catch Ljava/io/IOException; {:try_start_0 .. :try_end_0} :catch_1

    move-result-object v0


第二段代码:当网络通畅没什么问题时,也就是if-ne v2, v3, :cond_0  跳转到cond_0时会执行以下代码:

  :cond_0
    invoke-virtual {p0, v0}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->regetkeyafter(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v0
   @程序关键,开始添加异常代码  
   :try_start_1
     
   [COLOR="Red"]@调用了静态方法parseInt,其参数就是上面联网返回的参数v0,当其返回0时将会引发NumberFormatException异常
   @那么处理的代码在哪里呢? 翻到该代码的结尾 可以看到处理其异常的代码就是catch_2分支(已经加红)
    invoke-static {v0}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
   @当返回参数正常没有发生异常时,将其转换为整型后赋值给v0
    move-result v0

    const/4 v1, 0x6
   @将v0与v1比较 如果不相等 就跳转,从下面的代码调用的函数以及提示的uncode代码可以知道下面的代码就是 注册流程
  @因此聪明的是你,马上就可以想到,只要把这段加红的代码删除,那么就会成为注册
    if-ne v0, v1, :cond_1 [/COLOR]   
const/4 v0, 0x1
   @写入注册变量
    iput-boolean v0, p0, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->al:Z

    iget-object v0, p0, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->ag:Landroid/widget/TableLayout;

    const/16 v1, 0x8

    invoke-virtual {v0, v1}, Landroid/widget/TableLayout;->setVisibility(I)V

    const-string v0, "config1my"

    new-instance v1, Ljava/lang/StringBuilder;

    const-string v2, "QM"

    invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

    invoke-virtual {p0}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->getIMEI()Ljava/lang/String;

    move-result-object v2

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v1
   @写入key
    invoke-virtual {p0, v1}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->writekey(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v1

    invoke-virtual {p0, v0, v1}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->writeFileData(Ljava/lang/String;Ljava/lang/String;)V
   @取出相关广告
    iget-object v0, p0, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->aa:Lcom/forace/ad/dd/MyValue;

    iget-object v1, p0, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->aa:Lcom/forace/ad/dd/MyValue;

    iget-object v1, v1, Lcom/forace/ad/dd/MyValue;->MyDB:Landroid/database/sqlite/SQLiteDatabase;

    new-instance v2, Ljava/lang/StringBuilder;

    const-string v3, "insert into config values (\'qm\',\'"

    invoke-direct {v2, v3}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V

    invoke-virtual {p0}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->getIMEI()Ljava/lang/String;

    move-result-object v3

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v2

    invoke-virtual {p0}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->getIMSI()Ljava/lang/String;

    move-result-object v3

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v2

    const-string v3, "\',\'1\',1)"

    invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    move-result-object v2

    invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

    move-result-object v2

    invoke-virtual {v0, v1, v2}, Lcom/forace/ad/dd/MyValue;->ExecuteSQL(Landroid/database/sqlite/SQLiteDatabase;Ljava/lang/String;)I

    iget-object v0, p0, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->aa:Lcom/forace/ad/dd/MyValue;

    const-string v1, "\u6210\u529f"   
    const-string v2, ""

    invoke-virtual {v0, p0, v1, v2}, Lcom/forace/ad/dd/MyValue;->ShowMessage(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)V

    invoke-direct {p0}, Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;->m()V
    :try_end_1
    @处理异常的代码
    .catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_2
    :cond_1
    :goto_0
    return-void


5)将第二段代码中加红的代码删除后,在改之理中的“编译”菜单中,选择“编译生成apk”,改之理会自动完成回编译,以及签名,现在只要把该APK拷贝到手机上安装就可以了。
      或者你可以启动安卓虚拟机,然后选择菜单"ADB"选择安装生成的APK,虚拟机上就可以安装了,如图就是注册之后的样子,软件注册已经消失
   

[培训]12月3日2020京麒网络安全大会《物联网安全攻防实战》训练营,正在火热报名中!地点:北京 · 新云南皇冠假日酒店

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (37)
雪    币: 41
活跃值: 活跃值 (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
一个lorser 活跃值 2013-5-13 11:44
2
0
顶一个啊  支持
雪    币: 233
活跃值: 活跃值 (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
jiangjing 活跃值 1 2013-5-13 13:52
3
0
哎...又砸了一个饭碗.
雪    币: 298
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tedrick 活跃值 2013-5-13 18:27
4
0
哈哈。前几天发现个不能反编译只能IDA的,可能是定义字符超长,smali不识别。
雪    币: 8
活跃值: 活跃值 (18)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
zpsemo 活跃值 2013-5-13 19:23
5
0
不能反编译? 用啥工具? 啥提示?
雪    币: 298
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tedrick 活跃值 2013-5-13 19:52
6
0
直接smali啊~~~IDA跑得起来。换批处理apktool和改之理这种调用的都不行~~

system monitor
WIN8的taskmgr风格
雪    币: 8
活跃值: 活跃值 (18)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
zpsemo 活跃值 2013-5-13 20:34
7
0
求此APK  我观察观察下
雪    币: 298
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tedrick 活跃值 2013-5-13 21:03
8
0
有关键词啊。。。system monitor,外链违法吧?
雪    币: 8
活跃值: 活跃值 (18)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
zpsemo 活跃值 2013-5-14 06:27
9
0
好吧 我玩玩看
雪    币: 494
活跃值: 活跃值 (16)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
鬼谷子c 活跃值 1 2013-5-14 09:09
10
0
比较详细的分析过程,非常好的思路~相当于去掉外围包裹的if判断类于语句,直接走if内的流程~楼主辛苦...
雪    币: 57
活跃值: 活跃值 (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
wf王飞 活跃值 2013-5-14 14:56
11
0
学习了 很牛逼的教程
雪    币: 84
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
janecd 活跃值 2013-5-14 16:25
12
0
可能是定义字符超长,smali不识别

1.为什么反编译会出现这个问题,而程序正常运行时不会报错?
2.指定的路径或文件名太长,是原作者的疏忽所致还是故意这样做的?
雪    币: 0
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
炼狱鬼舞 活跃值 2013-5-14 22:29
13
0
楼主,您好,有一款APk需要反编译,是否可以帮忙。谢谢
雪    币: 136
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
SPL 活跃值 2013-5-16 05:31
14
0
支持一个
雪    币: 231
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
pltj 活跃值 2013-5-16 09:15
15
0
支持一个 好文章
雪    币: 198
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dingk 活跃值 2013-5-17 00:52
16
0
对Android不了解,但看了楼主的分析,感觉很到位,让我这个小白都看起来似乎明白了什么
雪    币: 167
活跃值: 活跃值 (10)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
wdynasty 活跃值 2 2013-5-18 21:28
17
0
看来APK的保护形势很严峻啊,起码自加密、SO都得支持哈!另外一些让工具奔溃的trick也需要!
雪    币: 17
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
青椒 活跃值 2013-5-20 16:59
18
0
好。我把本教程收为apk改之理的使用教程之一
http://www.xiaomiren.net/apkmodifier-index/#down
雪    币: 8
活跃值: 活跃值 (18)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
zpsemo 活跃值 2013-5-20 18:31
19
0
多谢
雪    币: 761
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
赤子Anatta 活跃值 2013-5-23 09:18
20
0
嗯,不错的思路。可否问问LZ是什么职业的呢?
雪    币: 8
活跃值: 活跃值 (18)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
zpsemo 活跃值 2013-5-23 10:56
21
0
打杂的
雪    币: 332
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
poochi 活跃值 2013-5-23 18:33
22
0
不错不错,受教了
雪    币: 298
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tedrick 活跃值 2013-5-26 10:41
23
0
发现另一只~digical calendar~~~~
http://android.d.cn/software/27335.html

目前这种方式smali还搞不定。
另外还见到过使用WIN系统保留名的,可能是混淆自动生成?
雪    币: 8
活跃值: 活跃值 (18)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
zpsemo 活跃值 2013-5-26 14:57
24
0
我看了一下,这个apk被混淆了,编译出来的smail文件很多都变形了
ˮ̸$鷭.smali
ˮ̣$鷭.smali
等等 其中的文件名包含con开头之类的东西,所以回编的话,提示失败:FileStream 将不会打开 Win32 设备(如磁盘分区和磁带机)。请避免在路径中
我的解决方法是 把dex单独拿出来,然后单独编译,这个倒是可以成功编译以及回编
只是文件还是被混淆的,如果分析的话 比较麻烦
雪    币: 298
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
tedrick 活跃值 2013-5-26 16:19
25
0
我说的还不是proguard混淆问题,是和之前的那个apk一样的情况,unknown link section~

sorry,网友提供给我的文件,我给你的是我常去的下载站,应该是下面这个,并不是原版,是国外黑市场XX过的。
http://www.coolapk.com/apk/com.digibites.calendar

之前那个system monitor:
http://www.coolapk.com/apk/com.cgollner.systemmonitor

我指的都是黑市场二次修改后的,是人为保护措施?还是IDA修改了proguard的成品后自然造成的?~~~
游客
登录 | 注册 方可回帖
返回