前言

因为老师的手气过于优秀,每次抽学号时总可能会抽到我,于是就有了逆向学校的学号抽取器的想法

分析

目前我们老师使用的学号抽取器多数为3.0和4.0版本(其他的是我魔改的),打开3.0版本,其页面如下

学号抽取器3.0

通过文件名可以得出,其基于”先进安全的”Flash制作,那么我们便可以进行下一步,逆向到.swf文件并研究Flash的语法

给Flash大爷腾个位置

我在研究的过程中,发现我的Windows 11没有Flash插件,一些软件打不开,我也不想去下中国特供Flash,刚好我的笔记本给我爸留了个Windows 7还带Flash,于是就直接在Windows 7上研究。

从.exe提取.swf文件

使用EXE-SWF转换器搞到.swf文件,

软件截图

但是里面有3个版本,装了Flash后我们可以看到第一个是Flash的设置(小时候玩4399右键游戏就可以找到的设置),第二个看不出来,但第三个就是我们所要的源码文件,取消勾选前2个,点击提取就可以提取出.swf文件

更改.swf源代码

代码编辑器安装

接下来我们开始更改.swf的源代码,当然,对于我们来说,我们得搞到一个能更改.swf源代码的玩意,上网搜过后,选定了JPEXS Free Flash Decompiler作为代码编辑器。

该编辑器需要Java 8或更高版本,我们可以在java.com搞到。

打开.swf文件

安装完成后,打开安装好的程序,点击左上角的打开,选择.swf文件,可以看到出来了一个编辑界面

捕获2

可以看到这软件的中文翻译还是挺到位的,一些信息可以一眼就看得明白。

定位到帧

在主页面的右边的SWF预览中,你可以看到.swf文件正在快速播放,下方的进度条提示了当前所在的帧和总帧数,其中,我们的这个学号抽取器一共有6帧,我们需要定位到输出学号的一帧。

按下中间的四边形的暂停按钮,使用左边的下一帧按钮一帧一阵地看,找出输出学号的一帧,如下图所示:

捕获3

虽然没有显示出学号,但是它已经能帮助能我们定位到输出学号的那一帧,记住左手边的帧数(本例为4,注:由1开始计数)

定位并编辑到脚本

前面的步骤已经帮助我们定位到了输出学号的帧,接下来我们就到定位到相应的脚本,展开脚本文件夹,你可能会看到这些文件:

捕获4

其中上面的DefineButton2顾名思义就是按钮,其定义了按下按钮后的一些操作。

但是在本例中我们只需要关注那些frame,这时候使用我们前面得到的输出学号的那一帧(本例为 frame 4),展开它,会看到有个DoAction,继续打开,会看到代码框,但是你很有可能看到一些警告:

捕获5

一般来说我们不能直接更改混淆的代码,因此我们需要把自动反混淆开启。

打开设置->勾选自动反混淆,点击确定即可

然后我们看到AS源代码变成了:

1
2
3
4
5
6
7
8
9
10
11
12
13
if(Number(_root.a) < Number(_root.s))
{
_root.d = Math.round(Math.random() * (s - a) + a) + Number(_root.a);
}
else if(Number(_root.s) < Number(_root.a))
{
_root.d = Math.round(Math.random() * (a - s) + s) + Number(_root.s);
}
else
{
gotoAndStop(6);
}
stop();

咦,这不是我前些天学的C,JavaScript吗?这么跑到这里来了(误),看来他们三个的代码很相似。

于是我们很容易就写出了以下注释(如要编辑AS源代码,请点击下方的编辑ActionScript按钮):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if(Number(_root.a) < Number(_root.s)) //if...elif...else结构用于避免开始大于等于结束值引发的错误
{
_root.d = Math.round(Math.random() * (s - a) + a) + Number(_root.a);
//根据开始与结束值获取到该范围随机数的整数
}
else if(Number(_root.s) < Number(_root.a))
{
_root.d = Math.round(Math.random() * (a - s) + s) + Number(_root.s);
}
//上面是获取随机数的,下面的应该是跳转到第6个帧(输入学号的开始与结束值相同跳转到第六个帧提示报错)
else
{
gotoAndStop(6);
}
stop();

很显然,我们如果想要学号抽取器抽不到我的学号,就要加个while循环来避免抽到我的学号,更改的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
if(Number(_root.a) < Number(_root.s))
{
_root.d = Math.round(Math.random() * (s - a) + a) + Number(_root.a);
while(_root.d == 48)
{
_root.d = Math.round(Math.random() * (s - a) + a) + Number(_root.a);
//如果抽到我的学号就再抽一遍,直到没抽到我的学号为止
}
}
else if(Number(_root.s) < Number(_root.a))
{
_root.d = Math.round(Math.random() * (a - s) + s) + Number(_root.s);
while(_root.d == 48)
{
_root.d = Math.round(Math.random() * (s - a) + a) + Number(_root.a);
}
}
else
{
gotoAndStop(6);
}
stop();

更改完成后点击保存,编译器会自动删除注释,再点击左上角的保存来保存对.swf文件的更改

润色脚本

由于我们就改了输出学号的那一帧,在惊心动魄的第三帧(不断显示新的学号)也能看到我的学号,于是我们得改改第三帧,第三帧的脚本和第四帧差别不是很大,因此我们也很轻松的更改了第三帧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(Number(_root.a) < Number(_root.s))
{
_root.d = Math.round(Math.random() * (s - a) + a) + Number(_root.a);
while(_root.d == 48)
{
_root.d = Math.round(Math.random() * (s - a) + a) + Number(_root.a);
}
}
else if(Number(_root.s) < Number(_root.a))
{
_root.d = Math.round(Math.random() * (a - s) + s) + Number(_root.s);
while(_root.d == 48)
{
_root.d = Math.round(Math.random() * (a - s) + s) + Number(_root.s);
}
}
else
{
gotoAndStop(6);
}
gotoAndPlay(2); //第三帧和第四帧的不同之处

更改关闭时出现的作者名

由于该程序退出时会显示作者名,看起来不爽,我们又没有能力(不想)更改源代码,于是我诞生了一个想法:更改该作者名

捕获7

通过JPEXS Free Flash Decompiler我们可以发现这个图像文件在图形文件夹下的一个DefineShape中,把它拖到桌面,产生了一个shape文件夹,里面是作者的签名图片,后缀为.svg,将其用格式工厂转换为.png格式后发现其分辨率为60x25,于是我们就可以用画图敲出一个签名来了。

因为其分辨率实在太小了,我们可以适当按比例扩大一下分辨率,完后在编辑器右键原来的DefineShape点击替换,替换新的签名即可

打包.swf文件

更改完.swf文件后,我们就得对.swf文件进行打包

使用独立播放器

3.0使用的是独立播放器,于是我们可以搞到一个来进行打包。

搞到像这样的独立播放器

把.swf文件拖进去,点击文件->创建播放器,即可保存为.exe文件

更改图标

为了天衣无缝,我们得给魔改过的.exe换成原来的图标

提取原程序图标

这个简单,用RH修改器或者是GetIconFrom Too就行了

更换.exe图标

这边我用QIcon Changer来更更改图标

(打开文件时任务栏仍然还是Flash独立播放器的图标,但是没人会在意这个:))

后记

本篇所有不含学号抽取器的下载链接:https://pan.baidu.com/s/1M2fWZ6IqyL4ei6wrLe97BQ?pwd=b5mi

想要把这个程序推广出去,还得进入老师的FTP替换原有的学号抽取器,这就是以后的事了。