微信SDK中含有的支付功能怎么去掉?

一、说在前面的话

这两天遇到一个特别让我DT的问题,估计大家通过标题就能知道问题了。没错,就是在应用中集成了微信SDK后,它自动支持了微信分享、登录、收藏、支付等功能。这一点没啥,TM的关键点就是在上传到应用宝时,他们既然提示了未通过,问题如下:
在这里插入图片描述
我集成微信SDK,主要是想使用登录和分享功能,支付功能压根不是我想集成的,但是这两个功能也没有单独的SDK,这就很让人DT了,关键这两个平台都是腾讯的,他们是要闹那样呀,不知道一家人要相亲相爱吗。尽给我们添麻烦,算了不说,吐槽没有用,继续搬砖吧

二、炁体源流(回归主题)

接入的流程在这里就不说了,不知道请自行查看教程
现在我们怀疑他们是根据特定的关键字以作为是否具有支付功能。而微信SDK中的支付关键字为PayReq,而在集成微信SDK时,他们明确说明在 proguard.cfg需要配置:

-keep class com.tencent.mm.opensdk.** {
    *;
}

-keep class com.tencent.wxop.** {
    *;
}

-keep class com.tencent.mm.sdk.** {
    *;
}

但是我反编译时,并未发现他们有携带相关的so库,那为什么需要keep那么多包中的类那,我就把所有防混淆的配置全部移除,并验证登录功能发现完全没有问题,我找了好多手机都验证完全没有问题。
然后提交到应用宝后台后,果然通过了,看来他们就是根据一些Pay关键字做的校验。自此问题。。。

在上线后之前未注意的点暴露了问题,那就是主要使用两个功能点:登录分享,而当时只是测试了登录并未测试分享,所以就出问题了。
既然这样那肯定是不该混淆的类被混淆了,那我们就通过微信SDK源码分析吧。

我们在编写分享时代码一般如下:

   LocalBroadcastManager.getInstance(mContext).registerReceiver(wxBroadcastReceiver, new IntentFilter(Constants.WX_OPTIONS_RESULT_ACTION));
        //初始化 WXImageObject 和 WXMediaMessage 对象
        WXImageObject imgObj = new WXImageObject(bitmap);
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = imgObj;

        //构造一个Req
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = String.valueOf(System.currentTimeMillis());
        req.message = msg;
        req.scene = shareFlag == 0 ? SendMessageToWX.Req.WXSceneSession : SendMessageToWX.Req.WXSceneTimeline;
        //调用api接口,发送数据到微信
        iwxapi.sendReq(req);

也就是说主要的关键接口是IWXAPI,而它的实现类是BaseWXApiImplV10,那我就看它的sendReq具体实现:

 public boolean sendReq(BaseReq var1) {
     ...
                } else {
                    com.tencent.mm.opensdk.modelmsg.SendMessageToWX.Req var3;
                    int var4;
                    if (var1.getType() == 2 && d.a(var4 = (var3 = (com.tencent.mm.opensdk.modelmsg.SendMessageToWX.Req)var1).message.getType())) {
                        WXWebpageObject var9;
                        if (this.getWXAppSupportAPI() < 620756993) {
                            (var9 = new WXWebpageObject()).webpageUrl = var2.getString("_wxminiprogram_webpageurl");
                            var3.message.mediaObject = var9;
                        } else if (var4 == 46 && this.getWXAppSupportAPI() < 620953856) {
                            (var9 = new WXWebpageObject()).webpageUrl = var2.getString("_wxminiprogram_webpageurl");
                            var3.message.mediaObject = var9;
                        } else {
                            WXMiniProgramObject var8 = (WXMiniProgramObject)var3.message.mediaObject;
                            var8.userName = var8.userName + "@app";
                            String var5;
                            if (!d.b(var5 = var8.path)) {
                                String[] var11;
                                if ((var11 = var5.split("\\?")).length > 1) {
                                    var5 = var11[0] + ".html?" + var11[1];
                                } else {
                                    var5 = var11[0] + ".html";
                                }

                                var8.path = var5;
                            }
                        }

                        if (var3.scene != 3 && var3.scene != 1) {
                            var3.scene = 0;
                        }

                        var1.toBundle(var2);
                    }

                    Args var7;
                    (var7 = new Args()).bundle = var2;
                    var7.content = "weixin://sendreq?appid=" + this.appId;
                    var7.targetPkgName = "com.tencent.mm";
                    var7.targetClassName = "com.tencent.mm.plugin.base.stub.WXEntryActivity";
                    if (var1.getType() == 2) {
                        try {
                            String var10 = this.getTokenFromWX(this.context);
                            var7.token = var10;
                        } catch (Exception var6) {
                            Log.e("MicroMsg.SDK.WXApiImplV10", "getTokenFromWX fail, exception = " + var6.getMessage());
                        }
                    }

                    return MMessageActV2.send(this.context, var7);
                }
            } else {
                return this.sendPayReq(this.context, var2);
            }
        }
    }

我们从中并未发现混淆后会导致不可用的地方。
那就继续看发送类型的model类:SendMessageToWX,我们会发现其中有一处:

      public void toBundle(Bundle var1) {
            super.toBundle(var1);
            var1.putAll(Builder.toBundle(this.message));
            var1.putInt("_wxapi_sendmessagetowx_req_scene", this.scene);
            var1.putInt("_wxapi_sendmessagetowx_req_media_type", this.message.getType());
            var1.putString("_wxapi_sendmessagetowx_req_use_open_id", this.userOpenId);
        }

我们在继续查看Builder.toBundle(this.message) 的源码:

       public static Bundle toBundle(WXMediaMessage var0) {
            Bundle var1;
            (var1 = new Bundle()).putInt("_wxobject_sdkVer", var0.sdkVer);
            var1.putString("_wxobject_title", var0.title);
            var1.putString("_wxobject_description", var0.description);
            var1.putByteArray("_wxobject_thumbdata", var0.thumbData);
            if (var0.mediaObject != null) {
                var1.putString("_wxobject_identifier_", pathNewToOld(var0.mediaObject.getClass().getName()));
                var0.mediaObject.serialize(var1);
            }

            var1.putString("_wxobject_mediatagname", var0.mediaTagName);
            var1.putString("_wxobject_message_action", var0.messageAction);
            var1.putString("_wxobject_message_ext", var0.messageExt);
            return var1;
        }

这时大家可能已经发现了病毒的所在了,没错就是它:pathNewToOld(var0.mediaObject.getClass().getName())

pathNewToOld方法的源码:

  private static String pathNewToOld(String var0) {
            if (var0 != null && var0.length() != 0) {
                return var0.replace("com.tencent.mm.opensdk.modelmsg", "com.tencent.mm.sdk.openapi");
            } else {
                Log.e("MicroMsg.SDK.WXMediaMessage", "pathNewToOld fail, newPath is null");
                return var0;
            }
        }

那既然知道了问题的所在了,那就直接防止modelmsg包下的所有类不被混淆即可了。所以我们只需要在proguard.cfg中配置如下即可:

-keep class com.tencent.mm.opensdk.modelmsg.** {
    *;
}

自此问题就真的解决了。奥利给

三、总结

移除在proguard.cfg中配置的:

-keep class com.tencent.mm.opensdk.** {
    *;
}

-keep class com.tencent.wxop.** {
    *;
}

-keep class com.tencent.mm.sdk.** {
    *;
}

只需要在proguard.cfg中配置:

-keep class com.tencent.mm.opensdk.modelmsg.** {
    *;
}

即可,这是凝结的精华,需要慢慢领悟

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值