好友
阅读权限25
听众
最后登录1970-1-1
|
元亨利之贞
发表于 2013-5-13 20:16
本帖最后由 元亨利之贞 于 2013-5-13 22:37 编辑
这次拿到一个新的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将会自动打开该文件,并且定位到该字符出现的位置,定位到该方法的开始位置,详细请看代码的注释
[C] 纯文本查看 复制代码
@可以看到注册的方法名称为s,参数为Lcom/forace/Bqimen/BqimenActivity/BqimenDa
@teInputActivity,背后的V为无返回值
@另外值得注意的是字段synthetic ,该字段是编译器合成的,非作者添加的,也就是如果
@你使用java DeCompiler进程查看
@Java级别的源码时,这些代码是看不到的,这也就是之前我搜索“成功”之类的字符串搜索不到的原因
.method static synthetic s(Lcom/forace/Bqimen/BqimenActivity/BqimenDateInputActivity;)V
(5)既然找到了源头,我们就顺藤摸瓜往下看看 作者到底做了什么,代码如下,详情请看注释
第一段代码:
[C] 纯文本查看 复制代码
.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
@程序的关键
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,如果相等,则不跳转那么下执行提示“网络异常”
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时会执行以下代码:
[C] 纯文本查看 复制代码
: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
@调用了静态方法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
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,虚拟机上就可以安装了,如图就是注册之后的样子,软件注册已经消失
后记:之前我曾强制更改判断网络是否异常的jmp(之前以为这里是关键调)结果发现依旧未注册成功。之后继续跟踪跳转之后的代码发现总是调用异常代码,于是就在想哪里会发生异常,于是便定位到parseInt函数,之后的问题便迎刃而解。
|
免费评分
-
查看全部评分
|