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

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 18873|回复: 34
上一主题 下一主题
收起左侧

[Android 原创] <名刊会>逆向破解手记:qq&新浪微博授权登录验证的分析和破解

  [复制链接]
跳转到指定楼层
楼主
spguangz 发表于 2015-11-24 12:07 回帖奖励
<名刊会>是一款看杂志的手机app。我们不仅可以在软件的书籍里学到知识,还可以在其破解的过程中学到其他东西哦。
它有3个破解点:
1.破解微博授权登录验证
2.破解qq授权登录验证
3.破解会员特权

如图,从qq或新浪微博快速登录时都会对安装包进行验证。
就像2道门,一旦验证失败,我将被拒于门外。
所以先破掉它们。


1.第一道门--微博授权登录验证

安装二次打包过的安装包,点击微博登录。
会发现不能登录并有错误提示:sso package or sign error
说明已被发现安装包是假货了。

在smali里搜索该提示,无果。应该是网络验证了。

1-1 微博授权登录验证破解方法一

淡然在<开心消消乐>简单的逆向破解过程一文中提到:
一般来说,一个程序要想支持QQ和新浪微博的接口登录,都必须事先将自己签名的MD5放到接口的后台官网来申请登录SDK,如果签名不一致则拒接登录。所以要解除它们的登录限制,可在反编译的SDK的Smali文件中,让它读取正版包的签名信息。
所以这里用到的方法是常用的"自定义验证包路径"具体操作如下:
1.把真包改名为123.apk,然后放到sdcard里。即路径为/sdcard/123.apk
2.搜索pm/PackageManager;->getPackageInfo
3.自定义安装包路径,并将getPackageInfo改为getPackageArchiveInfo,
   意思是根据自定义的路径读取该apk的签名。
一个修改好的例子如下:
[XML] 纯文本查看 复制代码
iget-object v2, v2, Landroid/content/pm/ResolveInfo;->activityInfo:Landroid/content/pm/ActivityInfo;

    iget-object v2, v2, Landroid/content/pm/ActivityInfo;->packageName:Ljava/lang/String;

    const-string v2, "/sdcard/123.apk"
    //自定义安装包路径

    .line 61
    const/16 v3, 0x40

    :try_start_0
    invoke-virtual {v1, v2, v3}, Landroid/content/pm/PackageManager;->getPackageArchiveInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;
//修改为getPackageArchiveInfo

move-result-object v1

因为是破解微博的登录验证,所以只在带有weibo的smali里修改即可。

回编译--测试--可以成功登录了。

1-2 微博授权登录验证破解方法二

1-1的方法略显麻烦,所以探索出一种简单点的方法。
就是通过运行真包和假包,在登录微博时分别进行抓包操作,分析两者的差异


明显感觉key_hash就是关键了,进行搜索。

还记得刚才那句错误提示吗?sso package or sign error
所以直接改带有sso字眼的那个smali,令key_hash为真包的key_hash即可。
[XML] 纯文本查看 复制代码
const-string v1, "key_hash"

    iget-object v2, p0, Lcom/sina/weibo/sdk/auth/sso/b;->i:Lcom/sina/weibo/sdk/auth/a;

    invoke-virtual {v2}, Lcom/sina/weibo/sdk/auth/a;->e()Ljava/lang/String;

    move-result-object v2
    
    const-string v2, "62b2279963932cb2c4c50116c3370c14"
    //令读取到的key_hash为真包的key_hash

    invoke-virtual {v0, v1, v2}, Lcom/sina/weibo/sdk/net/h;->b(Ljava/lang/String;Ljava/lang/String;)V

或者通过修改跳转,跳过key_hash的验证也行:
[XML] 纯文本查看 复制代码
if-ne v1, p2, :cond_2
    //改为goto :cond_2,以跳过key_hash的验证

    const-string v1, "packagename"

    iget-object v2, p0, Lcom/sina/weibo/sdk/auth/sso/b;->i:Lcom/sina/weibo/sdk/auth/a;

    invoke-virtual {v2}, Lcom/sina/weibo/sdk/auth/a;->d()Ljava/lang/String;

    move-result-object v2

    invoke-virtual {v0, v1, v2}, Lcom/sina/weibo/sdk/net/h;->b(Ljava/lang/String;Ljava/lang/String;)V

    .line 109
    const-string v1, "key_hash"

    iget-object v2, p0, Lcom/sina/weibo/sdk/auth/sso/b;->i:Lcom/sina/weibo/sdk/auth/a;

    invoke-virtual {v2}, Lcom/sina/weibo/sdk/auth/a;->e()Ljava/lang/String;

    move-result-object v2  

    invoke-virtual {v0, v1, v2}, Lcom/sina/weibo/sdk/net/h;->b(Ljava/lang/String;Ljava/lang/String;)V

    .line 112
    :cond_2
    new-instance v1, Ljava/lang/StringBuilder;


//省略

回编译--测试--可以成功登录了。

2.第二道门--qq授权登录验证

安装二次打包过的安装包,点击qq登录。
会发现不能登录并提示是山寨版。


先尝试1-1的"自定义验证包路径"的方法,发现并不奏效。
而且通过抓包也找不到关键的信息,所以试试别的方法。
看看log寻找关键,点击qq登录时,有一处红色的log:
Tag: openSDK_LOG
Message: OpenUi, onActivityResult, onError = 100044

搜索OpenUi, onActivityResult, onError =
来到这里:
[HTML] 纯文本查看 复制代码
:cond_3
    const-string v1, "openSDK_LOG"

    new-instance v2, Ljava/lang/StringBuilder;

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

    const-string v3, "OpenUi, onActivityResult,"

    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-static {v1, v2}, Lcom/tencent/open/a/f;->e(Ljava/lang/String;Ljava/lang/String;)V

    .line 158
    const-string v1, "key_error_msg"

    invoke-virtual {p0, v1}, Landroid/content/Intent;->getStringExtra(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v1

    .line 159
    const-string v2, "key_error_detail"

    invoke-virtual {p0, v2}, Landroid/content/Intent;->getStringExtra(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v2

    .line 160
    new-instance v3, Lcom/tencent/tauth/UiError;

    invoke-direct {v3, v0, v1, v2}, Lcom/tencent/tauth/UiError;-><init>(ILjava/lang/String;Ljava/lang/String;)V

    invoke-interface {p1, v3}, Lcom/tencent/tauth/IUiListener;->onError(Lcom/tencent/tauth/UiError;)V

    goto :goto_0

:cond_3最后是调用onError(Lcom/tencent/tauth/UiError;)V,使验证出错。
再往上看几行,看到:
[XML] 纯文本查看 复制代码
:cond_2
    const-string v0, "openSDK_LOG"

    const-string v1, "OpenUi, onActivityResult, onComplete"

    invoke-static {v0, v1}, Lcom/tencent/open/a/f;->b(Ljava/lang/String;Ljava/lang/String;)V

    .line 154
    new-instance v0, Lorg/json/JSONObject;

    invoke-direct {v0}, Lorg/json/JSONObject;-><init>()V

    invoke-interface {p1, v0}, Lcom/tencent/tauth/IUiListener;->onComplete(Ljava/lang/Object;)V

    goto :goto_0

:cond_2最后是调用onComplete(Ljava/lang/Object;)V,即完成验证。
所以在:cond_3的开头,添加一个跳转goto :cond_2。
如此,令本来走到onError的代码,改跳到onComplete,以完成验证。
回编译后,经测试,虽然还会弹出那个错误码提示,但还是能成功登录的。

3.破解会员

两道门都破掉后,接下来开始破解会员。

先看提示:

通过几次搜索后,轻松找到关键:
[XML] 纯文本查看 复制代码
check-cast v0, Lcom/qikan/dy/lydingyue/modal/Content;

    invoke-virtual {v0}, Lcom/qikan/dy/lydingyue/modal/Content;->getId()Ljava/lang/String;

    move-result-object v0

    invoke-virtual {v1, v2, v0}, Lcom/qikan/dy/lydingyue/modal/User;->isValid(Ljava/lang/String;Ljava/lang/String;)Z

    move-result v0
//判断是不是会员

    if-nez v0, :cond_0
//不是会员则往下走,否则跳到:cond_0

    .line 347
    invoke-static {p1}, Lcom/qikan/dy/lydingyue/util/i;->a(Landroid/content/Context;)V
//这是上面的提示框

    .line 358
    :goto_0
    return-void

    .line 351
    :cond_0
    new-instance v0, Landroid/content/Intent;

    const-class v1, Lcom/qikan/dy/lydingyue/activity/ArticleActivity;

//省略

所以,isValid是判断会员的地方。


或者,通过抓包能看到更详细的信息:

{
        "Code": "0000",
        "Msg": "操作成功",
        "AuthCode": "1L0ytR5vziMyG...", //授权码
        "UserName": "spguangzhcbcgd", //用户名
        "Email": "xxxx@qq.com",  //邮箱
        "UserMobile": "",
        "PayItem": "Month",            //支付方式:包月
        "ValidTime": "2015-12-17 0:57:10",  //会员到期时间
        "IsValid": 1,                            //是不是会员:是           "LoginForm": 2                      //登录方式:2
}
最后做如下修改即为会员版了:
[XML] 纯文本查看 复制代码
.method public isValid(Ljava/lang/String;Ljava/lang/String;)Z
    .locals 2

    .prologue
    const/4 v0, 0x1

    .line 228
    iget v1, p0, Lcom/qikan/dy/lydingyue/modal/User;->isValid:I

    if-ne v1, v0, :cond_0

    .line 232
    :goto_0
const/4 v0, 0x1
//强制返回真,一直是会员

    return v0

    :cond_0
    new-instance v0, Ljava/lang/StringBuilder;

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

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

    move-result-object v0

    const-string v1, ","

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

    move-result-object v0

    invoke-virtual {v0, p2}, 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-direct {p0, v0}, Lcom/qikan/dy/lydingyue/modal/User;->isInTen(Ljava/lang/String;)Z

    move-result v0

    goto :goto_0
.end method


至此完成<名刊会>的所有破解。
言不达意,感谢观看!

免费评分

参与人数 18威望 +4 热心值 +18 收起 理由
469164323 + 1 66666666
poca + 1 我很赞同!
淡然出尘 + 1 + 1 我很赞同!
dych1688 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.
13929861564 + 1 吊炸天!
victjack + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
萋小磊 + 1 挺帅的一小伙 可惜是个傻逼
仁二 + 1 好厉害还没看完先顶再说
tredawn + 1 我很赞同!
1485573943 + 1 我很赞同!
chenhuanlin + 1 我很赞同!
就爱玩玩 + 1 热心回复!
myoldid + 1 棒棒的
qtfreet00 + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩.
ai枫 + 1 谢谢@Thanks!
Dlan + 1 我很赞同!
黑桃J + 1 太牛X了!
坛主 + 1 热心回复!

查看全部评分

本帖被以下淘专辑推荐:

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

推荐
淡然出尘 发表于 2016-2-29 15:24
赞一个
-----
那个123.apk不需要完整的apk,这样有点累赘,只需保留其中的AndroidManifest.xml和META-INF文件夹即可;
微博去SSO验证码抓包方法比较赞;
推荐
十一大魔王i 发表于 2016-2-29 12:21
大神,, 在在用改之理反编译008... 提示失败,
代码如下,,  
失败:Exception in thread "main" brut.androlib.AndrolibException: brut.directory.DirectoryException: java.util.zip.ZipException: invalid CEN header (bad signature)
        at brut.androlib.ApkDecoder.hasResources(ApkDecoder.java:293)
        at brut.androlib.ApkDecoder.decode(ApkDecoder.java:91)
        at brut.apktool.Main.cmdDecode(Main.java:165)
        at brut.apktool.Main.main(Main.java:81)
Caused by: brut.directory.DirectoryException: java.util.zip.ZipException: invalid CEN header (bad signature)
        at brut.directory.ZipRODirectory.<init>(ZipRODirectory.java:55)
        at brut.directory.ZipRODirectory.<init>(ZipRODirectory.java:38)
        at brut.androlib.res.util.ExtFile.getDirectory(ExtFile.java:55)
        at brut.androlib.ApkDecoder.hasResources(ApkDecoder.java:291)
        ... 3 more
Caused by: java.util.zip.ZipException: invalid CEN header (bad signature)
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:219)
        at java.util.zip.ZipFile.<init>(ZipFile.java:149)
        at java.util.zip.ZipFile.<init>(ZipFile.java:163)
        at brut.directory.ZipRODirectory.<init>(ZipRODirectory.java:53)
        ... 6 more
沙发
飘零的殇 发表于 2015-11-24 12:11
头像被屏蔽
3#
hellokits 发表于 2015-11-24 12:20
提示: 作者被禁止或删除 内容自动屏蔽
4#
御神箭之翼 发表于 2015-11-24 12:28
简直掉渣了
5#
windwing1883 发表于 2015-11-24 13:03
学习了,多谢分享
6#
蚍蜉撼象 发表于 2015-11-24 13:04
很棒,学习了
7#
395145609zxl 发表于 2015-11-24 17:38
谢谢楼主.支持楼主
8#
就爱玩玩 发表于 2015-11-24 19:11
只能羡慕大神
9#
xugong 发表于 2015-11-24 19:39
大神就是厉害
10#
程维佳 发表于 2015-11-24 23:33 来自手机
长知识了
您需要登录后才可以回帖 登录 | 注册[Register]

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

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

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

GMT+8, 2024-5-15 13:57

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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