Android中一个有趣的crash的日志分析

很久前写的一篇文章,发出来以作纪念:)

Android中一个有趣的crash的日志分析

首先看看bugly平台中异常的统计信息,表面上是一个NullPointerException:

发生异常设备统计信息如下图,有意思的是全部都是root过的机器:

接下来看跟踪日志,在最下面可以看到这样的日志,抛出了NullpointerException:

引起异常的是com.lishu.net.LishuNet$2类,从类名看显然是某一个类的内部类。

第一个反应,当然是搜索一下应用的源代码,看看是不是有com.lishu.net.LishuNet这样的类,或者异常。如果有,那自然就是继续分析代码了。经过一番搜索,居然没有找到,看来有点意思。

其次自然想到,应用集成了很多第三方SDK,或许是某个SDK里抛出的异常?不急,解压出所有集成的.jar包,然后批量反编译,导入工具中全局搜一下,有没有这个字符串了。费一番周折发现,还是没有这个字符串。越来越有意思了,代码中没有相关的类,SDK中也没有,奇怪。

回来继续翻看日志上下文,只有如下信息可用,看来是个http访问超时异常:

有问题,这个异常和其他异常不太一样,日志里居然连com.chebada包名都没有显示出来的。也许是统计平台出错了,压根不是我们应用导致的crash?

只有抛异常前打出来的一行日志,看起来有些关系

访问这个网址看看,有时连不上,有时拒绝服务。源代码里也没有这样的网址。

这个时候线索好像真的断了,再搜索日志,看不出来和我们的应用有什么关联。

还是没有思路,再翻一下其他异常,发现异常列表中有些日志会打出来类似下面的内容,之后再访问上图中的网址(http://120.24.74.141:8080/lishu008AppManager/phone/LogicSimpleAction.action):

总结多个crash日志,发现每次都是先有这个js警告,再访问120.24.74.141域名。

js又是/data/data目录com.chebada包下的脚本,也许,是WebView的访问触发了相关异常,或许是url劫持?也不像。统计平台异常列表中有些并没有报这个js警告,问过服务器相关同事,js也没有访问http://120.24.74.141:8080/lishu008AppManager这样的网址。

不过所有crash日志都有访问http的超时异常。

疑点都集中在http://120.24.74.141:8080/lishu008AppManager这里。

继续万能的百度搜索,lishu008AppManager露出一点端倪。有一个名叫“008神器”的安卓应用引起了我的注意,该下载链接中有lishu008AppManager字样。打开主页看看该应用能干什么,结果吓一跳:

下载一个看看,运行需要root过的机器。 找了一台root过的机器,运行后按提示安装框架、安装模块。期间需要重启几次。

需要的框架、模块都安装好了,再次运行,提示软件到期。卸载重新下载一个破解版的“008神器”,运行后发现,能改的东西还真多,连手机串号也能改:

这个时候看看日志,发现了LishuNet的踪迹:

等等,“008神器”的包名不是com.soft.apk008Tool吗,怎么会报com.lishu.net.LishuNet错误呢?反编译apk安装包,原来,除了com.soft.apk008Tool,还有另一个包com.lishu.net这个包,其中有LishuNet这个类,LishuNet还有一个内部类com.lishu.net.LishuNet$2,继承自Thread:

显然在该线程中触发了NullPointerException异常。往下跟跟,具体打印出异常的地方:

这个就是在连接http://120.24.74.141:8080失败时,比如连接超时、服务器拒绝服务等异常情况下,打印出异常信息的地方了。原来只要连接出错,就会打印出错信息。

除了反编译代码中有com.lishu.net这个包,在 “008神器”安装包的assets文件夹下还发现了Apk008Tool.apk这个安装包,安装后会多一个“008神器工具箱”的应用。再反编译“008神器工具箱”,原来com.lishu.net是“008神器工具箱”的包名,而“008神器”中com.lishu.net包下的代码,都是从Apk008Tool.apk来的,最有可能的就是,“008神器”和“008神器工具箱”是同一个作者开发的。

那是什么触发了异常呢?各种尝试,后来发现运行“008神器”,就会访问网址http://120.24.74.141:8080/lishu008AppManager/phone/LogicSimpleAction.action,接着log中就能看到异常信息,过滤后显示如下图:

原来只要运行“008神器”就会报异常。继续跟踪com.lishu.net.LishuNet:

LishuNet对象调用postMessage()方法,在该方法中new一个LishuNet$2的对象,也就是新建了一个Thread线程,并开始运行。异常就是从这个线程里抛出来的。

那么,哪里调用了LishuNet的postMessage()方法呢?继续搜索,原来是在Apk008Activity的onResume()中:

其他地方也有调:

稍微跟踪一下代码,会发现,在“008神器”启动、启动其他应用、网络状态变化、调用工具箱修改了系统属性值时,验证“008神器”的签名时,等等,都会触发这个线程,调用postMessage()方法,向http://120.24.74.141服务器发送特定数据。以启动“008神器”应用发送的数据为例:

启动时发送的数据是手机的IMEI、系统版本号、系统版本名称。其他不一一列举。

原来异常是和我们的应用没有关系的,可以这样验证:卸载我们的应用,单独运行“008神器”时,log中依然会不停的报com.lishu.net.LishuNet$2的这个异常。

Bugly中报这个异常,极有可能是因为,bugly统计平台的SDK在安卓系统log中恰巧同时检测到了com.chebada,和com.lishu.net.LishuNet抛出的异常,就将两者结合,视为com.chebada的bug了。这也可以解释,为什么几千条LishuNet$2抛出的异常,没有统一的错误信息。后续有时间再反编译看看bugly统计SDK的代码,验证一下。

至于解决方法,实现起来就简单了,既然改不了框架层的东西,就在应用层修改。在应用启动时判断,如果存在“008神器”或“008神器工具箱”,就退出应用。OK,打完收工。

当然,如果使用008神器或者xposed框架接口,在系统服务层API屏蔽了008神器应用,那使用这种方式就不起作用了。

附:

“008神器”工作原理引起了我的好奇,各种改系统功能是怎么实现的呢?经过学习发现,是利用了xposed框架,而xposed框架是需要root权限才能正常运行的,这也解释了为什么报这个crash的设备全部都是root过的了,没有root权限,“008神器”就没法正常工作。

Xposed框架是开源的,不过作者(也是Supersu的作者)好久没有更新了,所以该框架只支持安卓4.0.3-4.4版本的系统,这个可以解释统计平台设备版本分布情况:安卓系统4.4版本以上信息不会报这个异常。

有兴趣的同学可以学习研究下这个框架,框架基本原理是修改了安卓系统的心脏zygote,等于在安卓的Java虚拟机上加了一个接口,这个接口为框架修改系统、提供系统级的服务提供了支持,当然,如果拿来搞破坏,其威力也是相当惊人的,可以在应用不知情的情况下,肆意获取输入的用户名、密码等敏感信息。下图是我写的框架Demo程序运行结果截图,拦截了应用登录页面输入的用户名、密码信息:

经本人实验,不修改第三方应用、不经用户同意,就可以在应用运行时动态拦截、修改应用的数据,并完全可以做到开启后台线程,将用户的数据发送至特定的服务器。

原文地址:https://www.cnblogs.com/areful/p/10399409.html

时间: 2024-11-10 11:39:57

Android中一个有趣的crash的日志分析的相关文章

android中一个评分的控件

RatingBar android中一个评分的控件 如何使用 Android Studio下: dependencies { compile 'com.hedgehog.ratingbar:app:1.0.2' } 1,在XML中 <com.hedgehog.ratingbar.RatingBar android:layout_marginTop="50dp" android:layout_gravity="center" android:id="@

Android 中View的绘制机制源码分析 三

到目前为止,measure过程已经讲解完了,今天开始我们就来学习layout过程,不过在学习layout过程之前,大家有没有发现我换了编辑器,哈哈,终于下定决心从Html编辑器切换为markdown编辑器,这里之所以使用"下定决心"这个词,是因为毕竟Html编辑器使用好几年了,很多习惯都已经养成了,要改变多年的习惯确实不易,相信这也是还有很多人坚持使用Html编辑器的原因.这也反应了一个现象,当人对某一事物非常熟悉时,一旦出现了新的事物想取代老的事物时,人们都有一种抵触的情绪,做技术的

Android 中View的绘制机制源码分析 二

尊重原创:http://blog.csdn.net/yuanzeyao/article/details/46842891 本篇文章接着上篇文章的内容来继续讨论View的绘制机制,上篇文章中我们主要讲解了View的measure过程,今天我们就来学习ViewGroup的measure过程,由于ViewGroup只是一个抽象类,所以我们需要以一个具体的布局来分析measure过程,正如我上篇文章说的,我打算使用LinearLayout为例讲解measure过程,如果你还没有读过上篇文章,那么建议你先

跑健壮性Monkey,出现一次Crash全过程-日志分析-董浩-Dotest

最近带着学生做的某个项目,跑健壮性Monkey,出现一次Crash全过程-日志分析: 准备:搭建adb环境.安装实际测试包:开始: Monkey命令: 1 2 3 4 5 adb shell monkey -p com.**** -v-v-v --throttle 300 --pct-touch  30 --pct-motion 20 --pct-nav 20 --pct-majornav 15  --pct-appswitch 5 --pct-anyevent 5 --pct-trackbal

iOS:crash崩溃日志分析

一.前言: 作为一个合格的iOS开发者,除了具有规范强悍的编码能力外,还应该具有过硬的查错纠错能力.在项目运行时,程序崩溃是不可避免的,遇到这个问题,有时会出现一大堆的crash日志,艹,貌似看不懂呀.其实没有那么可怕,我们可以将这些日志格式化,通过它来快速定位问题的所在,以便迅速搞定它. 二.分析: 首先我们来看一个crash日志,大略的介绍其中的几个重要的关键词: 关键词解释: 2.1. 进程信息第一部分是闪退进程的相关信息: Incident Identifier : 是崩溃报告的唯一标识

Android 中View的绘制机制源码分析 一

尊重原创: http://blog.csdn.net/yuanzeyao/article/details/46765113 差不多半年没有写博客了,一是因为工作比较忙,二是觉得没有什么内容值得写,三是因为自己越来越懒了吧,不过最近我对Android中View的绘制机制有了一些新的认识,所以想记录下来并分享给大家.在之后的几篇博客中,我会给大家分享如下的内容: 1.View中measure(),layout(),draw()函数执行过程分析,带领大家详细分析View的尺寸测量过程,位置计算,并最终

Android中使用Handler造成内存泄露的分析和解决

什么是内存泄露? Java使用有向图机制,通过GC自动检查内存中的对象(什么时候检查由虚拟机决定),如果GC发现一个或一组对象为不可到达状态,则将该对象从内存中回收.也就是说,一个对象不被任何引用所指向,则该对象会在被GC发现的时候被回收:另外,如果一组对象中只包含互相的引用,而没有来自它们外部的引用(例如有两个对象A和B互相持有引用,但没有任何外部对象持有指向A或B的引用),这仍然属于不可到达,同样会被GC回收. Android中使用Handler造成内存泄露的原因 Handler mHand

android中的计步问题及计步传感器分析

今天打开博客,才发现居然有一年多没有写博客了... 最近由于公司要分析android上的计步问题,顺便把计步器在android上的实现跟踪了一下.结果发现悲催的是,android的api19上,是用的硬件本身的计步实现了. android源码中的流程追踪如下: frameworks/base/core/java/android/hardware/Sensor.java 中定义了TYPE_STEP_DETECTOR和TYPE_STEP_COUNTER. 请注意,detector启动后,确认了,才启

Android中使用【microlog4】进行日志存储

在Android项目中需要将一个日志文件到SD卡,以备后续的调试Bug之用. 具体使用如下: 1.下载开源框架 http://code.google.com/p/microlog4android/downloads/list 下载microlog4android-1.0.0.jar和microlog.properties文件 2.建立使用logger对象 private static final Logger logger = LoggerFactory.getLogger(MainActivi