新理念大学英语学习大厅是一个在线英语学习软件。软件有一个计时器,记录学生的学习时间。只有达到规定的学习时间才能通过学习并开启相应的单元测试。一旦窗口失活,如切换到别的程序或者最小化,计时器就会停止。对于想利用英语课干点小事的同学来说,这确实是个不幸的消息。
用PostMessage发送WM_SETFOCUS消息可以骗过大厅的计时器。这种方法占用一定的系统资源,同时会影响大厅的正常使用,出现如菜单无法弹出等情况。详情请看我的博客:
http://kqwd.blog.163.com/blog/static/41223448200910411380776/
对主程序分析发现该软件为.Net编写。遂准备修改其代码,达到暴力破解的目的。其中不涉及到特殊的技巧,
本文用于.Net破解初学者了解破解.Net程序的一般步骤。(希望不要被大虾BS...)
首先用Reflector反编译,查看程序的代码。发现该软件未采取任何的保护措施,代码可读性很高。查看主窗体的代码,看到这样两段:
private void MainForm_Deactivate(object sender, EventArgs e)
{
this.PreActivate = this.tTimer.Enabled;
this.tTimer.Enabled = false;
}
private void MainForm_Activated(object sender, EventArgs e)
{
this.tTimer.Enabled = this.PreActivate;
}
可见窗口失活时,软件禁用了计时器控件tTime.这么简单吗?马上动手吧!
用ildasm.exe反汇编。ildasm.exe是微软官方的.Net程序的反汇编程序。随VS一同安装。VS2008中默认路径在C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\ildasm.exe
用ildasm.exe打开主程序,然后点文件-转储。导出il代码和资源文件。
为了测试导出的正确性,我们打开VS的命令行,进入il文件的目录,输入
ilasm /exe /resource=*.res *.il
其中**为你导出的文件名
对导出的il进行汇编,重新生成exe。发现生成的exe运行正常(果然很弱,没有强名称保护)。
我尝试着将this.tTimer.Enabled = false;改为this.tTimer.Enabled = true;
在IL中搜索MainForm_Deactivate,找到方法的代码(行:3873)
.method private hidebysig instance void
MainForm_Deactivate(object sender,
class [mscorlib]System.EventArgs e) cil managed
{
// 代码大小 32 (0x20)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldarg.0
IL_0003: ldfld class [System.Windows.Forms]System.Windows.Forms.Timer LearningCenter.MainForm::tTimer
IL_0008: callvirt instance bool [System.Windows.Forms]System.Windows.Forms.Timer::get_Enabled()
IL_000d: stfld bool LearningCenter.MainForm::PreActivate
IL_0012: ldarg.0
IL_0013: ldfld class [System.Windows.Forms]System.Windows.Forms.Timer LearningCenter.MainForm::tTimer
IL_0018: ldc.i4.0
IL_0019: callvirt instance void [System.Windows.Forms]System.Windows.Forms.Timer::set_Enabled(bool)
IL_001e: nop
IL_001f: ret
} // end of method MainForm::MainForm_Deactivate
将红字部分改为IL_0018: ldc.i4.1
即为将false替换为true。测试发现,在学习状态中,计时器确实可以不停,但在大厅首页时,程序在失活时出错。看窗口激活时的方法,发现其用PreActivate这个布尔变量来记录是否该开启计时器。而修改后,程序一旦失活就开启计时器,因此出错。
我们直接去掉窗口失活时关闭计时器的代码不是也行吗?将斜体部分(0012-0019)注释掉.重新用ilasm编译。再次试用,破解成功!
给同学试用后,反映程序在5分钟不操作会弹出离线的对话框,计时器再次停止。看来还不是很完美。再看计时器的代码。有这样一段:
if (this.CurrentPoint != Cursor.Position)
{
this.CurrentPoint = Cursor.Position;
this.PointTime = 0;
}
else
{
this.PointTime++;
}
if (this.PointTime > WinContext.AFKTime)
{
this.tTimer.Enabled = false;
MessageBox.Show("您目前处于暂离状态,点击确定继续学习", this.Text);
this.PointTime = 0;
this.tTimer.Enabled = true;
}
鼠标不动时,PointTime就会增加,加到AFKTime后,计时器就会停止。尝试将this.tTimer.Enabled = false;改为true.时间到后发现计时器虽然不停,但提示对话框会每秒蹦出一个。还是把this.PointTime++;改成0比较好。
在IL中搜索tTimer_Tick(行:3810),片段如下:
IL_013a: nop
IL_013b: ldarg.0
IL_013c: dup
IL_013d: ldfld int32 LearningCenter.MainForm::PointTime
IL_0142: ldc.i4.1
IL_0143: add
IL_0144: stfld int32 LearningCenter.MainForm::PointTime
IL_0149: nop
IL_014a: ldarg.0
IL_014b: ldfld int32 LearningCenter.MainForm::PointTime
IL_0150: ldsfld int32 LearningCenter.WinContext::AFKTime
IL_0155: cgt
IL_0157: ldc.i4.0
IL_0158: ceq
IL_015a: stloc.2
IL_015b: ldloc.2
IL_015c: brtrue.s IL_0192
将IL_0142: ldc.i4.1改为IL_0142: ldc.i4.0
重新编译。试用发现一切正常。至此爆破成功
小插曲:
tTimer_Tick的第一句就是this.LearnTime++;
对应IL有这么一段:
IL_0000: nop
IL_0001: ldarg.0
IL_0002: dup
IL_0003: ldfld int32 LearningCenter.MainForm::LearnTime
IL_0008: ldc.i4.1
IL_0009: add
IL_000a: stfld int32 LearningCenter.MainForm::LearnTime
把1008这句改成IL_0008: ldc.i4.s 10
这样就可以让时间以原来10倍的速度增长了~~!不过出于安全考虑(不要被老师发现啊*¬_*),没有这么做。
[课程]FART 脱壳王!加量不加价!FART作者讲授!