一个由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 条评论
登录 后参与评论

相关文章

来自专栏一个会写诗的程序员的博客

第9章 文件IO操作、正则表达式与多线程第9章 文件IO操作、正则表达式与多线程

我们在《第6章 扩展函数与属性》中已经介绍过Kotlin中的类扩展的特性。使用Kotlin的扩展函数功能,我们可以直接为 String 类实现一个 inc() ...

803
来自专栏编码小白

ofbiz实体引擎(四) ModelReader的作用

public class ModelReader implements Serializable { public static final Stri...

2718
来自专栏平凡文摘

面试问烂的 Spring AOP 原理、SpringMVC 过程

Spring AOP ,SpringMVC ,这两个应该是国内面试必问题,网上有很多答案,其实背背就可以。但今天笔者带大家一起深入浅出源码,看看他的原理。以期让...

772
来自专栏后端之路

MyBatis插件小知识点

背景 mybatis作为一款十分优秀的orm框架在大量的互联网应用中得到使用。其提供了比较完善的插件扩展机制 通常我们会使用插件做到许多共通的事情 比如 慢sq...

2379
来自专栏博客园

.NET面试题解析(06)-GC与内存管理

转自:http://www.cnblogs.com/anding/p/5260319.html

702
来自专栏一个会写诗的程序员的博客

《Kotlin 程序设计》第十二章 Kotlin的多线程

Kotlin 1.1 introduced coroutines, a new way of writing asynchronous, non-blockin...

691
来自专栏debugeeker的专栏

《coredump问题原理探究》Linux x86版3.2节栈布局之函数桢

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

541
来自专栏coolblog.xyz技术专栏

Spring IOC 容器源码分析 - 创建原始 bean 对象

本篇文章是上一篇文章(创建单例 bean 的过程)的延续。在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程。本篇文章,我们就从战术的层...

1935
来自专栏行者常至

struts2中用jquery、ajax实现下拉框的级联

- 这个地方不添加任何东西,因为我是用的通配符,所以,我在PostAction.java 类中增加了一个postajax()方法(你的方法名叫什么都可以,...

783
来自专栏androidBlog

一步步拆解 LeakCanary

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/de...

591

扫码关注云+社区