一个由proguard与fastJson引起的血案

更新微信sdk导致ComposeData中的内部类ComposeDataSender方法被混淆

根本原因,fastjson使用姿势不对。

问题描述:

一个发件人列表里,应当呈现的数据(这里命名为ComposeData)为空

(1)业务逻辑层

获取发件人列表时,如果Composedata超时,会从网络重新拉取Json格式的ComposeData,拉取后利用FastJson的toString()方法,将ComposeData写入DB。

混淆情况下,toString()生成的json字符串会缺少alias字段。

定位问题到FastJson的toString()

(2)FastJson层

FastJson执行JSON类的toString()方法时,

对普通的Object对象(这里是ComposeDataSender),会将这个对象当做JavaBean对象处理,

在JavaBeanSerializer中,找到这个对象的getter方法

来确定要生成的Json格式数据中,K-V的值。

在JavaBeanSerializer中打log,发现不混淆时,getter有4个(getNick(),getAlias(),getType(),getSignvalid()),混淆后,只找到一个getter(getType())。

定位问题到getter方法

(3)混淆后的ComposeDataSender

反编译没问题的旧包和有问题的新包,

发现, 旧包的ComposeDataSender有getAlias()和getType()方法和一个被混淆后的return this.XXX方法(混淆前为getNick()方法)

新包的ComposeDataSender有getType()方法和两个被混淆后的return this.XXX方法(混淆前为getNick(),getAlias()方法)

导致发件人列表为空的原因:

获取发件人列表时,依赖于需要读取DB中的各个别名帐号的aliastype

旧包中,getAlias()和getType()方法没有混淆,toString()时存入DB的数据是可用的(实际上,nick字段在4.1.1也丢失了,但由于没有使用到这个字段,不会引起问题)

新包中,getType()方法没有混淆,其他getter被混淆,toString()存入DB的数据只有type(丢失了nick,alias),所以在获取发件人列表时,alias为空

(4)新包丢失alias分析

在反编译后的旧包所有代码中中查找getAlias()

可以看到mm.sdk.contact中有RContact这个类,包含了getAlias方法,因为是第三方库,其中public的getAlias方法没有被混淆,

因为proguard混淆时,同名的方法(不论是否在同一个类中)是被替换为相同的名字,(可以查看~\build\outputs\mapping\debug\mapping.txt查看混淆时变量和方法的替换规则)

所以,代码中所有getAlias方法都没有被混淆,(相同的情况还可以在ComposeDataSender里看到,accountId属性虽然是私有的,但也没有被混淆)

而新包中,更新了mm.sdk,去掉了RContact这个类,没有getAlias方法,所以ComposeDataSender里的getAlias被混淆

而getType()没有丢失

查找getType()方法,发现在新包或旧包中的很多第三方库中仍然被保留,所以没有被混淆,toString()时仍然可以将type字段正确存入DB

(经实验,把ComposeDataSender里的type名字改为senderType,并相应地改变get方法和set方法,就会被混淆)

(5)解决方案

修改ComposeData toString()方法,原有toString()方法,在处理items这一array对象时,直接往JSONArray中存入了ComposeDataSender对象,

所以toString生成K-V时会依赖于ComposeDataSender的getter方法。

修改为:

往JSONArray中存入JSONObject对象,将K-V信息存入JSONObject,解析时走MapSerializer流程,不需要依赖于ComposeDataSender的getter方法。不会受混淆影响。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏技术博客

Asp.Net Web API 2第十六课——Parameter Binding in ASP.NET Web API(参数绑定)

阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.h...

843
来自专栏屈定‘s Blog

设计模式--动态代理的思考

在一些第三方框架中经常能看到动态代理的案例,尤其是RPC框架,ORM框架等,该篇将分析这些实现的原理,另外延伸在业务中的使用示例.

1213
来自专栏MasiMaro 的技术博文

windows平台调用函数堆栈的追踪方法

在windows平台,有一个简单的方法来追踪调用函数的堆栈,就是利用函数CaptureStackBackTrace,但是这个函数不能得到具体调用函数的名称,只能...

1922
来自专栏c#开发者

BizTalk Orchestration execute Flat file disassembler ReceivePipeline

需求是这样,在一个inbound XML中有个一点节点使用平文件的方式存放,还要解析比如固定长度或根据特殊字符截取字段 也就是需要在流程里面先把输入的XML的节...

36513
来自专栏木木玲

Netty in Action ——— The codec framework

1172
来自专栏大内老A

一个简易版的T4代码生成"框架"

对于企业开发来说,代码生成在某种意义上可以极大地提高开发效率和质量。在众多代码生成方案来说,T4是一个不错的选择,今天花了点时间写了一个简易版本的T4代码生成的...

1987
来自专栏小灰灰

SpringMVC返回图片的几种方式

SpringMVC返回图片的几种方式 后端提供服务,通常返回的json串,但是某些场景下可能需要直接返回二进制流,如一个图片编辑接口,希望直接将图片流返回给前...

47410
来自专栏码洞

基于Netty实现Redis协议的编码解码器

上面是Netty的服务器端基本消息处理结构,为了便于初学者理解,它和真实的结构有稍许出入。Netty是基于NIO的消息处理框架,用来高效处理网络IO。处理网络消...

1721
来自专栏marsggbo

python多线程学习笔记(超详细)

python threading 多线程 一. Threading简介 首先看下面的没有用Threading的程序 import threading,time ...

2058
来自专栏瓜大三哥

文件地址映射之yaffs_GetTnode

yaffs文件系统在更新文件数据的时候,会分配一块新的chunk,也就是说,同样的文件偏移地址,在该地址上的数据更新前和更新后,其对应的flash上的存储地址是...

1846

扫码关注云+社区