本帖最后由 myoldid 于 2015-1-21 23:14 编辑
前言:
游戏名称:疯狂的麦咭
游戏版本:2.0.26
游戏类型:我也不知道
此游戏有简单的签名验证,支付判断也不再是Paysuccess,好了,直接开始正题吧。
1. 此游戏也是爱游戏下载的,因为爱游戏,所以直接paysuccess,但是,但是结果很意外,没有对应的方法,只有字符串paysuccess,好直接戳进去看看。根据入代码中的注释修改后,再将调用payfailed的地方,改为调用paysuccess。回编,安装运行。大大的“爱游戏”出来了,但是,大爷的,怎么一下又回桌面了呢?肯定是我打开方式不对,随即换左手戳开,但它也一下回桌面了。看来有问题啊! 然后对原包重签名,安装,也是秒退,那就是有签名验证了。
[Java] 纯文本查看 复制代码
.method public final invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
#v0=(Reference,Ljava/lang/String;);
invoke-virtual {p2}, Ljava/lang/reflect/Method;->getParameterTypes()[Ljava/lang/Class;
move-result-object v1
#v1=(Reference,[Ljava/lang/Class;);
const-string v2, "paySuccess"
const-string v0, "paySuccess" #在这里定义v0为paysuccess,这样v0就和v2相等了,后面的v2也就是0x1,为真
#v2=(Reference,Ljava/lang/String;);
invoke-virtual {v2, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v2
#v2=(Boolean);
if-eqz v2, :cond_0 #当然也可以在这里定义v2为0x1,:cond_0那里有个payCancel的字符串,所以不让他往那里跳
array-length v2, v1
#v2=(Integer);
if-ne v4, v2, :cond_0 #这也要注释掉,不然也会跳到:cond_0。哎,我改的时候没看见,现在才发现,可能这里一改就对了
const-class v2, Ljava/lang/String;
#v2=(Reference,Ljava/lang/Class;);
aget-object v3, v1, v5
#v3=(Null);
if-ne v2, v3, :cond_0 #这也要注释掉,不然也会跳到:cond_0 哎,我改的时候没看见,现在才发现,可能这里一改就对了
iget-object v1, p0, Lcom/talkweb/securitypay/ctpay/b;->a:Lcom/talkweb/securitypay/ctpay/a;
aget-object v0, p3, v5
#v0=(Null);
check-cast v0, Ljava/lang/String;
#v0=(Reference,Ljava/lang/String;);
iget-object v1, v1, Lcom/talkweb/securitypay/ctpay/a;->a:Landroid/os/Handler;
invoke-static {v1, v5, v0}, Lcom/talkweb/common/c;->a(Ljava/lang/Object;ILjava/lang/String;)Z
invoke-static {v4}, Ljava/lang/Integer;->valueOf(I)Ljava/lang/Integer;
move-result-object v0
:goto_0
#v1=(Conflicted);v2=(Conflicted);v3=(Conflicted);
return-object v0
:cond_0
#v1=(Reference,[Ljava/lang/Class;);
const-string v2, "payCancel"
2. 对签名验证这块我不懂,只知道简单的绕过方法。但我知道要搜索signatures,随即搜索。找到了关键的地方,看着挺眼熟的,没错,就是落华无痕中说的那BT种子搜索1.5.7签名校验破解过程简介中提到的样子。很激动的把原包改名后放入download文件夹下,然后定义原包路径。怀着忐忑的心情,安装,运行,偶也,没秒退了。但是在购买时还是没错误提示,也没成功。
[Java] 纯文本查看 复制代码
.method public verifyPackageSignature()Z
.locals 9
.prologue
const/4 v5, 0x0
.line 572
:try_start_0
#v5=(Null);
invoke-virtual {p0}, Lcom/talkweb/securitypay/test/MainActivity;->getPackageManager()Landroid/content/pm/PackageManager;
move-result-object v6
#v6=(Reference,Landroid/content/pm/PackageManager;);
invoke-virtual {p0}, Lcom/talkweb/securitypay/test/MainActivity;->getPackageName()Ljava/lang/String;
move-result-object v7
const-string v7, "/sdcard/download/yb.apk" #在这里定义原安装包路径
#v7=(Reference,Ljava/lang/String;);
const/16 v8, 0x40
#v8=(PosByte);
invoke-virtual {v6, v7, v8}, Landroid/content/pm/PackageManager;->getPackageArchiveInfo(Ljava/lang/String;I)Landroid/content/pm/PackageInfo; #这里将getPackageInfoget改为PackageArchiveInfo,意思就是读取未安装的信息
move-result-object v2
.line 573
.local v2, "info":Landroid/content/pm/PackageInfo;
#v2=(Reference,Landroid/content/pm/PackageInfo;);
iget-object v6, v2, Landroid/content/pm/PackageInfo;->signatures:[Landroid/content/pm/Signature;
const/4 v7, 0x0
#v7=(Null);
aget-object v4, v6, v7
.line 574
.local v4, "sig":Landroid/content/pm/Signature;
#v4=(Null);
invoke-virtual {v4}, Landroid/content/pm/Signature;->toByteArray()[B #这里我不知道是啥意思了,不是转换为字符串
move-result-object v6
invoke-static {v6}, Lcom/talkweb/securitypay/test/MainActivity;->getPublicKey([B)Ljava/lang/String;
move-result-object v3
.line 576
.local v3, "pubKey":Ljava/lang/String;
#v3=(Reference,Ljava/lang/String;);
iget-object v6, p0, Lcom/talkweb/securitypay/test/MainActivity;->PUBLIC_KEY:Ljava/lang/String;
invoke-virtual {v6, v3}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z #猜了下这句,是对比现在和理论签名值。在通过定义原包路径绕过签名成功后,直接改了这里的返回值,也成功了....
move-result v6
const/4 v6, 0x1 #这里直接定义签名对比结果为真
#v6=(Boolean);
if-eqz v6, :cond_0
.line 580
const/4 v5, 0x1
.line 600
.end local v2 # "info":Landroid/content/pm/PackageInfo;
.end local v3 # "pubKey":Ljava/lang/String;
.end local v4 # "sig":Landroid/content/pm/Signature;
:goto_0
return v5
3. 前面通过直接返回真,绕过签名后,但购买还是没成功,没提示。那试试鬼哥,小白yey常常提及的logcat吧。用大神的Androidkiller戳出logcat,在购买的时候出现了两个提示,如图1。20010006和no sim,你妹的,没sim就该被歧视。我得祈祷公司年会让我抽中个MX4,那样就不会被歧视了。没sim,那试试getSimState()定义吧,同时也强制返回46003.等着一切做完后,再搜索了20010006。得到两个结果。戳开第一个,哇,令人激动的东西出来了
图1
4. 什么那么令人激动呢?仔细看。通过文中的注解,很直观了,:sswitch_1就是成功代码,那我们在前面直接让他跳到:sswitch_1那就该成功了。
[Java] 纯文本查看 复制代码
.method public onPayCallback(ILjava/lang/String;Ljava/lang/String;)V
#略#
sparse-switch p1, :sswitch_data_0
goto :sswitch_1 #直接跳到成功
.line 191
:cond_0
:goto_0
:sswitch_0
#v0=(Conflicted);v1=(Conflicted);v2=(Conflicted);
return-void
.line 142
:sswitch_1
#v0=(Uninit);v1=(Uninit);v2=(One);
sget-object v0, Lcom/unity3d/player/UnityPlayer;->currentActivity:Landroid/app/Activity;
.line 143
#v0=(Reference,Landroid/app/Activity;);
const-string v1, " \u652f\u4ed8\u6210\u529f!\n\u62d3\u7ef4\u6e38\u620f\u5ba2\u670d\u7535\u8bdd\uff1a400 118 5668" #支付成功
#####################此处略去1486个字.################
:cond_5
#v2=(One);
iget-object v0, p0, Lcom/talkweb/securitypay/test/MainActivity$1;->this$0:Lcom/talkweb/securitypay/test/MainActivity;
iget-object v0, v0, Lcom/talkweb/securitypay/test/MainActivity;->orderid:Ljava/lang/String;
const-string v1, "20010006"
if-ne v0, v1, :cond_6
.line 167
const-string v0, "_GameData"
const-string v1, "PurchaseCrystal3Success" #水晶3成功
const-string v2, ""
#v2=(Reference,Ljava/lang/String;);
invoke-static {v0, v1, v2}, Lcom/unity3d/player/UnityPlayer;->UnitySendMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
goto :goto_0
#略#
.line 175
:sswitch_2
#v0=(Uninit);v1=(Uninit);v2=(One);
iget-object v0, p0, Lcom/talkweb/securitypay/test/MainActivity$1;->this$0:Lcom/talkweb/securitypay/test/MainActivity;
.line 176
#v0=(Reference,Lcom/talkweb/securitypay/test/MainActivity;);
const-string v1, " \u652f\u4ed8\u5931\u8d25\uff0c\n\u62d3\u7ef4\u6e38\u620f\u5ba2\u670d\u7535\u8bdd\uff1a400 118 5668 " #支付失败
5. 再次回编,安装运行,戳了购买,偶也,提示了成功,也顺利到账,哈哈,又可以愉快的发帖了.就是图二那样的愉快
图2
思考:
1. 此游戏只是个简单的签名验证,并且很直接的给出了对比签名的判断,所以很方便的能绕过,但那句我搞不懂了,麻烦大神给简单解释一下,谢谢了
[Java] 纯文本查看 复制代码
invoke-virtual {v4}, Landroid/content/pm/Signature;->toByteArray()[B #这里我不知道是啥意思了,不是转换为字符串
move-result-object v6
invoke-static {v6}, Lcom/talkweb/securitypay/test/MainActivity;->getPublicKey([B)Ljava/lang/String;
move-result-object v3
2. 此游戏因为没直接给出错误提示,但如果直接搜索“支付成功”也是可行的
|