软件制作平台:VS C#.NET
目的:了解VS.NET软件的破解,制作注册机,本文章只做研究使用!!
由于我答应了法语助手的作者,不再发布它的破解补丁文件:),所以本来要写VB.NET的文章改成了这个C#的文章,反正菩提兄写了详细的VB.NET的破解了:)
过程:
找到ILDASM.exe(好像在vs.net的第三张光盘吧),打开!
拖入SpeedII主程序,开始反汇编...OK
找到注册相关的地方(regB_Click 或 启动监测处),打开!
拷贝的代码如下:
由于不做爆破,所以就不显示字节代码了,主要是算法分析(爆破也简单,一两个字节就行了)
.method private hidebysig instance void regB_Click(object sender,
class [mscorlib]System.EventArgs e) cil managed
{
// Code size 331 (0x14b)
.maxstack 5//堆栈 5个
.locals init (char[] V_0,
char[] V_1,
int32 V_2,0
int32 V_3,1
int32 V_4,2
string V_5,
int32 V_6,
bool V_7,
class [mscorlib]System.IO.StreamWriter V_8,
class [mscorlib]System.Exception V_9)
.try
{
IL_0000: ldc.i4.s 20//压入 20
IL_0002: newarr [mscorlib]System.Char//申明数组
IL_0007: stloc.0//char[]=new str0[20]
IL_0008: ldc.i4.s 20//压入 20
IL_000a: newarr [mscorlib]System.Char//申明数组
IL_000f: stloc.1//char[]=new str1[20]
IL_0010: ldarg.0Arg0
IL_0011: ldfld class [System.Windows.forms]System.
Windows.forms.TextBox SpeedIP_II.Reg::userName//很明显,取用户名
IL_0016: callvirt instance string [System.
Windows.forms]System.Windows.forms.Control::get_Text()
IL_001b: callvirt instance char[] [mscorlib]System.String::ToCharArray()
IL_0020: stloc.0//str0=username.tochararray(); 将用户名数组=>str0
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//开始第一组计算
IL_0021: ldc.i4.0//push 0 我按照字符解释为load (下同)
IL_0022: stloc.2//set loc.2=0
IL_0023: br.s IL_0040 jump 40
IL_0025: ldloc.1//load str1
IL_0026: ldloc.2//load loc.2
>>>IL_0027: ldloc.0//load str0
IL_0028: ldloc.2//load loc.2
IL_0029: ldelem.u2//[]
//load str0[loc.2]
/IL_002a: ldloc.2/load loc.2
|IL_002b: ldloc.0// load str0
/ |IL_002c: ldlen// len(str0)
| |IL_002d: conv.i4=======//i4=len(str0)
| \IL_002e: add//add
| /IL_002f: ldloc.0=========// load loc.0
|IL_0030: ldlen// len(loc.0)
| \IL_0031: conv.i4=========//i4=len(loc.0)
\ IL_0032: mul// *
IL_0033: add// +
IL_0034: ldc.i4.s 26// load 26
IL_0036: rem// rem???这是什么
IL_0037: ldc.i4.s 65// load 65
>>>IL_0039: add// add
IL_003a: conv.u2//???
IL_003b: stelem.i2//[]
IL_003c: ldloc.2//load loc.2
IL_003d: ldc.i4.1//1
IL_003e: add//I++
IL_003f: stloc.2//set loc.2=
IL_0040: ldloc.2//load loc.2
IL_0041: ldloc.0//load loc.0
IL_0042: ldlen//求长度
IL_0043: conv.i4//i4=len(name)
IL_0044: blt.s IL_0025//if loc.2<i4 then jump 0025
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
初看上面的代码觉得很乱,和菩提那篇介绍的不很一样,而且没有很多的提示,觉得很难理解
呵呵,后来我才发现了原因,解决的方法比较简单,
这个和那些写的很乱的代码很像,如果对上述代码做个下小小的变化
内容就显而易见了.
变化如下:
IL_0021: ldc.i4.0//push 0 我按照字符ld解释为load (下同)
IL_0022: stloc.2//set loc.2=0
IL_0023: br.s IL_0040 jump 40
IL_0025: ldloc.1//load str1
IL_0026: ldloc.2//load loc.2
{
{
{
IL_0027: ldloc.0//load str0
IL_0028: ldloc.2//load loc.2
IL_0029: ldelem.u2//[]
//load str0[loc.2] arg0
}
{
{
IL_002a: ldloc.2/load loc.2 arg1
{
IL_002b: ldloc.0// load str0 //三行看作一个arg
IL_002c: ldlen// len(str0)
IL_002d: conv.i4=======//i4=len(str0) arg2
}
IL_002e: add//add 运算
//也就是arg1+arg2=>arg1+len(str0)===> arg3
}
{
IL_002f: ldloc.0=========// load loc.0
IL_0030: ldlen// len(loc.0)
IL_0031: conv.i4=========//i4=len(loc.0)
}
arg4=len(str0)
IL_0032: mul// * 运算 fsarg3*arg4=>arg5
}
IL_0033: add// +
}
IL_0034: ldc.i4.s 26// load 26
IL_0036: rem// rem???这是什么 这个就是取模运算啦
//当初还以为是注释语句,哈哈,汇编代码也要注释?呵呵
IL_0037: ldc.i4.s 65// load 65
IL_0039: add// add
}
IL_003a: conv.u2//??? 哦这个就是将上述的结果conv一下
IL_003b: stelem.i2//[] set elem i2?
结合上面的语句不难看出
//IL_0025: ldloc.1//load str1
//IL_0026: ldloc.2//load loc.2
//RESULT
//setelem.i2
//哦,str1[loc.2]=RESULT
IL_003c: ldloc.2//load loc.2
IL_003d: ldc.i4.1//1
IL_003e: add//I++
IL_003f: stloc.2//set loc.2=loc.2+1
//很明显,循环索引值嘛
IL_0040: ldloc.2//load loc.2
IL_0041: ldloc.0//load loc.0
IL_0042: ldlen//求长度
IL_0043: conv.i4//i4=len(name)
IL_0044: blt.s IL_0025//if loc.2<i4 then jump 0025
分析,上述过程之所以看起来很复杂的原因是因为使用了套嵌,也就是编程使用了(),哈哈
所以上述的过程的算法为,VB表示
str0=name
for i=0 to len(str0)-1
str1[lndex]=((str0[index]+(index+len(str0))*len(str0)) mod 26) +65
next
作用是将注册码限制到[A-Z]之间
看懂了这一段的话,下面的两段代码简直和看源代码一样啦
后面不作详细解释,我将各段用空行隔开了,只要记住
数据操作总是这样的形式
push arg1
push arg2
operate
找到两个参数,和一个运算就行了,简单的很,
也就是所说的堆栈操作了,没有寄存器,看起来很别扭:)
就是套嵌看起来很复杂
要是可以做到和vs.net的代码操作一样,可以将代码收缩的话,哈哈!