admin 管理员组文章数量: 1087652
2024年12月20日发(作者:reactnative两行折叠)
吾爱破解安卓逆向入门教程(五)
引用: 软件:计算管家 v3.4目标:破解授权会员
目标软件验证方法:软件获取设备号号后调用支付宝进行付
费,付费成功后会返回对应参数,点击授权按钮后即完成付
费用户授权。
实战目标:点击授权按钮直接授权成功,小雨之前也做过3.3
的分析,我的手段比较简单,适合新手
软件界面:0x0 脱壳
本软件v3.3使用的爱加密壳,v3.4使用的360壳,不过对于
那些大鸟们来说,什么壳都没用,目前我们处于smali阶段,
不介绍壳的脱法,不像pc破解一上来就告诉你如何脱壳,后
面阶段,将会由@PoJie_小雨 给大家讲述脱壳实战。0x1 运
行软件找关键点
我们首先来到付费页面,如下图:开头中我已经讲过这个软
件的验证流程,既然这样,我们直接点击授权按钮观察有什
么关键点软件提示我们并没有获取授权,那么这类文字通常
会以文本形式写在,对应的布局文件或者以
unicode形式写在smali中,对于游戏来说,这类可能是以图
片形式放在图片文件,或者自定义格式的文件,甚至是通过
网络获取的,我们了解之后,先尝试第一种,直接搜索
AndroidKiller载入apk嗯,直接搜索到了,减少了我们很多
的工作量,那么,文本都有对应的id,我们再次搜索这个id,
等等,我们好像发现了更重要的东西我们看到了授权成功的
文字,那么我们换思路,直接搜索授权成功的id我们这里看
到了这个神奇的数字,新手相信都不知道这个玩意是怎么来
的,那么这里我稍微普及下,apk在编写时,开发工具都会
对源代码自动编译,生成对应的标示符,通过这些标示符,来
引用对应的资源,详细一点的可以阅读这篇文章
/s/blog_0x2 尝
试破解
我们接着搜索0x7f080100,发现两处可疑处分别点进去看
看,顺便我们也记下授权失败的标示符,0x7f080102,这里
我们可以方便我们判断这里我们看到的就是授权失败时弹
出的对话框,我们找到它的标签是:cond_1,接着我们向上翻,
看到哪些跳转会跳到:cond_1,我们来到方法的开始这是个接
收信息的方法,通常是由handler实现的,我们大体可以知
道,在付费成功后,会想这个函数传递一个message,这个
方法就是判断传入的message的值,通过这个值来判断是否
付费成功,这里我们看到一个cond_3,我们找到:cond_3,
这里我们看到,获取res资源中的0x7f08011a,并转换为string
类型,再传入到Alertdialog的message中,我们看看它到底
调用了什么资源看到是这个,看来跟我们破解无关,跳过,
我们就直接针对这两个跳转即可如果v1<=0或者
v1>v2,则跳转到:cond_1,我们不让它跳,在pc破解中,
我们有两种方法,一种是设置为相反的跳转,另一种就是nop
掉,lez对应的就是ge,不过这种方法不保险,我推荐第二
种,不走跳转,直接向下走if函数中的代码,我们删除这两
条即可,另一个smali修改方法类似,稍有出入接收传入的
message,判断v0是否等于0x1b207,不等的话,跳转
到:cond_2,我们观察到,如果跳转的话,就会越过成功提示
的方法,我们不能让它跳,nop掉,下面一个跳转到:cond_1
的判断也一并删除,保存,打包测试。嗯,提示成功,那么
我们测试下付费用户的功能是否能够正常使用ok,付费主题
可以使用,说明我们破解成功了,那是不是就结束了呢?当
我们退出程序再进入的时候发现主题丢了,什么鬼?来到付
费页面,发现授权按钮又可以点击了,之前我们注意到,授
权成功后,按钮就会呈现灰色不可点击的状态,那说明了什
么,这个程序有重启验证!0x3 突破重启验证
之前我们在尝试破解时,在成功函数中看到了这段信息,如
果是付费状态,“isDefaultTheme”的值是v1,在方法首可以
看到v1定义的是1,这里是个putBoolean,即通过
写入了true,那么我们通过分析发现,
我们是在重启后丢失授权信息的,那验证方法肯定在第一个
显示的页面被调用,我们找到程序的主页面所在的类,来到
下,我们尝试搜索“isDefaultTheme”,
结果搜到好几个[mw_shl_code=java,true].method static
synthetic d(Llongbin/helloworld/HelloWorldActivity;)V
.locals 6 .prologue
.line 3763
iget-object v0, p0,
Llongbin/helloworld/HelloWorldActivity;->cc:Landroid/cont
ent/SharedPreferences; const-string v1, 'alipay_appid'
const-string v2,
'89d43e35dd25de5d2ce9334f2624d6a61345893a'
invoke-interface {v0, v1, v2},
Landroid/content/SharedPreferences;->getString(Ljava/lang/
String;Ljava/lang/String;)Ljava/lang/String;
move-result-object v1 const-string v0, '' :try_start_0
iget-object v2, p0,
Llongbin/helloworld/HelloWorldActivity;->cb:Landroid/cont
ent/SharedPreferences; const-string v3, 'WWxoT2JnPT0='
const-string v4, '' invoke-interface {v2, v3, v4},
Landroid/content/SharedPreferences;->getString(Ljava/lang/
String;Ljava/lang/String;)Ljava/lang/String;
move-result-object v2 invoke-static {v2},
Llongbin/helloworld/hm;->b(Ljava/lang/String;)Ljava/lang/S
tring;
:try_end_0
.catch Ljava/io/UnsupportedEncodingException;
{:try_start_0 .. :try_end_0} :catch_0 move-result-object
v0 :goto_0
iget-object v2, p0,
Llongbin/helloworld/HelloWorldActivity;->cb:Landroid/cont
ent/SharedPreferences; const-string v3, 'font_size'
const-string v4, '28' invoke-interface {v2, v3, v4},
Landroid/content/SharedPreferences;->getString(Ljava/lang/
String;Ljava/lang/String;)Ljava/lang/String;
move-result-object v2 iget-object v3, p0,
Llongbin/helloworld/HelloWorldActivity;->cb:Landroid/cont
ent/SharedPreferences; const-string v4, 'isDefaultTheme'
const/4 v5, 0x0 invoke-interface {v3, v4, v5},
Landroid/content/SharedPreferences;->getBoolean(Ljava/lan
g/String;Z)Z move-result v3 invoke-static {v0},
Llongbin/helloworld/m;->f(Ljava/lang/String;)Ljava/lang/Str
ing; move-result-object v0 invoke-virtual {v0, v1},
Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0 if-eqz v0, :cond_0 const-string v0, '24'
invoke-virtual {v2, v0},
Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0 if-eqz v0, :cond_0 if-eqz v3, :cond_0
new-instance v1, Llongbin/helloworld/gb; const v0,
0x7f090027 sget-object v2, Llongbin/helloworld/n;->h:[I
invoke-direct {v1, p0, v0, v2},
Llongbin/helloworld/gb;-><init>(Llongbin/helloworld/
HelloWorldActivity;I[I)V sget-object v0,
Llongbin/helloworld/n;->h:[I :goto_1
new-instance v2, Landroid/app/AlertDialog$Builder;
invoke-direct {v2, p0},
Landroid/app/AlertDialog$Builder;-><init>(Landroid/c
ontent/Context;)V new-instance v3, Llongbin/helloworld/cg;
invoke-direct {v3, p0, v0},
Llongbin/helloworld/cg;-><init>(Llongbin/helloworld/
HelloWorldActivity;[I)V invoke-virtual {v2, v1, v3},
Landroid/app/AlertDialog$Builder;->setAdapter(Landroid/w
idget/ListAdapter;Landroid/content/DialogInterface$OnClickLis
tener;)Landroid/app/AlertDialog$Builder; new-instance v0,
Llongbin/helloworld/ch; invoke-direct {v0, p0},
Llongbin/helloworld/ch;-><init>(Llongbin/helloworld/
HelloWorldActivity;)V invoke-virtual {v2, v0},
Landroid/app/AlertDialog$Builder;->setOnCancelListener(L
android/content/DialogInterface$OnCancelListener;)Landroid/a
pp/AlertDialog$Builder; invoke-virtual {v2},
Landroid/app/AlertDialog$Builder;->show()Landroid/app/Al
ertDialog; return-void :cond_0
new-instance v1, Llongbin/helloworld/gb; const v0,
0x7f090026 sget-object v2, Llongbin/helloworld/n;->g:[I
invoke-direct {v1, p0, v0, v2},
Llongbin/helloworld/gb;-><init>(Llongbin/helloworld/
HelloWorldActivity;I[I)V sget-object v0,
Llongbin/helloworld/n;->g:[I goto :goto_1 :catch_0
move-exception v2 goto :goto_0
.end method[/mw_shl_code]
比如这样的,通过观察,我们发现这些方法都只是调用了
isDefaultTheme的布尔值,也就是说,这些并不会改变我们
的授权状态,我们需要找到的是会更改布尔值的函数,即
putBoolean,我们逐个排查,经过筛选后,我们找到了唯一
一个那其中的v2就是它经过判断后重新赋予的值,我们找
到这个值是什么,向上翻我们看到此处定义的是0,即false,
那找到病因了,我们就该下药了 A.方法1:在传值之前更改
v2的值,考虑到不影响整个程序的运行,不建议修改方法开
始时的v2值,我们仅在此处修改B.方法2:
不让程序进行赋值,即跳过这个判断流程,我们找到这个函
数体的标签,即:cond_3,根据尝试破解中的手段,跳过这个
标签即可。我们只找到一个,nop掉,为保证程序一定会能
跳过此处,建议是nop掉if-nez v3的同时,将下方的if-eqz v0,
改成goto :cond_4,这样程序就一定不会走:cond_3这个
分支,isDefaultTheme的布尔值就一定会真,好,打包测试
我们退出后重开程序,依然是灰色状态,说明我们真正授权
成功拉!作业:
(295.05 KB)
(下载次数: 443, 2015-8-8 17:29 上传)下载积分: 吾爱币 -1
CB
非常简单的一个例子,相信你在学完前面无课后这对你来说
根本不是问题,欢迎发帖进行分析,有加分哦
版权声明:本文标题:吾爱破解安卓逆向入门教程(五) 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1734760936a1586789.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论