「逆向分析的艺术」-某驾校驾驶员理论模拟考试系统4.2算法分析+注册机编写
「作者」:孤星琉月「工具」:OllyDBG DeDe
「加壳方式」:无
**** Hidden Message *****
到此前四位结束了
004C25B3 |> 8B45 FC /mov eax, ; 从第五位开始
004C25B6 |. 33DB |xor ebx,ebx
004C25B8 |. 8A5C30 FF |mov bl,byte ptr ds:
004C25BC |. 83FB 30 |cmp ebx,0x30
004C25BF |. 7C0A |jl X潍坊长远.004C25CB ; <0
004C25C1 |. 83FB 37 |cmp ebx,0x37
004C25C4 |. 7F05 |jg X潍坊长远.004C25CB ; >8
004C25C6 |. 83C302 |add ebx,0x2 ; 如果是0-7之间的数字,则加2
004C25C9 |. EB 0D |jmp X潍坊长远.004C25D8
004C25CB |> 83FB 38 |cmp ebx,0x38
004C25CE |. 7C08 |jl X潍坊长远.004C25D8
004C25D0 |. 83FB 39 |cmp ebx,0x39
004C25D3 |. 7F03 |jg X潍坊长远.004C25D8 ; 8-9的话直下一步
004C25D5 |. 83EB 08 |sub ebx,0x8 ; 是字母的话或者大的直接减8
004C25D8 |> 83FB 41 |cmp ebx,0x41 ; Switch (cases 41..5A)
004C25DB |. 7C29 |jl X潍坊长远.004C2606 ; "A"
004C25DD |. 83FB 5A |cmp ebx,0x5A
004C25E0 |. 7F24 |jg X潍坊长远.004C2606 ; “z”
004C25E2 |. 83EB 41 |sub ebx,0x41
004C25E5 |. 83FB 0A |cmp ebx,0xA
004C25E8 |. 7C03 |jl X潍坊长远.004C25ED ; 下面两个字符串也说明了,如果是A-J,则减41,B-Z,则减4B
004C25EA |. 83EB 0A |sub ebx,0xA ; Cases 4B ('K'),4C ('L'),4D ('M'),4E ('N'),4F ('O'),50 ('P'),51 ('Q'),52 ('R'),53 ('S'),54('T'),55 ('U'),56 ('V'),57 ('W'),58 ('X'),59 ('Y'),5A ('Z') of switch 004C25D8
004C25ED |> 83FB 0A |cmp ebx,0xA ; Cases 41 ('A'),42 ('B'),43 ('C'),44 ('D'),45('E'),46 ('F'),47 ('G'),48 ('H'),49 ('I'),4A('J') of switch 004C25D8
004C25F0 |. 7C03 |jl X潍坊长远.004C25F5
004C25F2 |. 83EB 0A |sub ebx,0xA ; 显然这样计算的结果是在0-10了
004C25F5 |> 8D45 F8 |lea eax, ; 之后的值放在变量中去
004C25F8 |. E8 2727F4FF |call 潍坊长远.00404D24
004C25FD |. 80C330 |add bl,0x30 ; 在这时转换成相应的ASCII码值
004C2600 |. 885C30FF |mov byte ptr ds:,bl ;放回到我们真注册码保存的位置
004C2604 |. EB 0C |jmp X潍坊长远.004C2612
004C2606 |> 8D45 F8 |lea eax, ; Default case of switch 004C25D8
004C2609 |. E8 1627F4FF |call 潍坊长远.00404D24 ;如果里面全都是数字,那取相应的位
004C260E |. 885C30FF |mov byte ptrds:,bl ; 直接放进去就好了
004C2612 |> 46 |inc esi
004C2613 |. 83FE 09 |cmp esi,0x9
004C2616 |.^ 75 9B \jnz X潍坊长远.004C25B3到此后四位就处理结束了。
004C2618 |. 8D45 F4 lea eax,
004C261B |. 8B55 F8 mov edx,
004C261E |. E8 8122F4FF call 潍坊长远.004048A4 ;大概是拷贝了一份放在变量3里面了吧
004C2623 |. 8D45 F4 lea eax,
004C2626 |. E8 F926F4FF call 潍坊长远.00404D24 ; System.@UniqueStringA(String;String);
004C262B |. 8B55 F8 mov edx,
004C262E |. 8A5202 mov dl,byte ptrds: ; 变量2的第2位
004C2631 |. 8810 mov byte ptr ds:,dl ; 第0位
004C2633 |. 8D45 F4 lea eax,
004C2636 |. E8 E926F4FF call 潍坊长远.00404D24
004C263B |. 8B55 F8 mov edx,
004C263E |. 8A5204 mov dl,byte ptrds: ; 第四位换第4
004C2641 |. 8850 01 mov byte ptr ds:,dl ; 换第1
004C2644 |. 8D45 F4 lea eax,
004C2647 |. E8 D826F4FF call 潍坊长远.00404D24
004C264C |. 8B55 F8 mov edx,
004C264F |. 8A5207 mov dl,byte ptrds: ; 7
004C2652 |. 8850 02 mov byte ptr ds:,dl ; 换2
004C2655 |. 8D45 F4 lea eax,
004C2658 |. E8 C726F4FF call 潍坊长远.00404D24
004C265D |. 8B55 F8 mov edx,
004C2660 |. 8A12 mov dl,byte ptr ds: ; 0换3
004C2662 |. 8850 03 mov byte ptr ds:,dl
004C2665 |. 8D45 F4 lea eax,
004C2668 |. E8 B726F4FF call 潍坊长远.00404D24
004C266D |. 8B55 F8 mov edx,
004C2670 |. 8A5203 mov dl,byte ptrds: ; 3换4
004C2673 |. 8850 04 mov byte ptr ds:,dl
004C2676 |. 8D45 F4 lea eax,
004C2679 |. E8 A626F4FF call 潍坊长远.00404D24
004C267E |. 8B55 F8 mov edx,
004C2681 |. 8A5206 mov dl,byte ptrds: ; 6换5
004C2684 |. 8850 05 mov byte ptr ds:,dl
004C2687 |. 8D45 F4 lea eax,
004C268A |. E8 9526F4FF call 潍坊长远.00404D24
004C268F |. 8B55 F8 mov edx,
004C2692 |. 8A5201 mov dl,byte ptrds: ; 1换6
004C2695 |. 8850 06 mov byte ptr ds:,dl
004C2698 |. 8D45 F4 lea eax,
004C269B |. E8 8426F4FF call 潍坊长远.00404D24
004C26A0 |. 8B55 F8 mov edx,
004C26A3 |. 8A5205 mov dl,byte ptrds: ; 5换7.
004C26A6 |. 8850 07 mov byte ptr ds:,dl
004C26A9 |. BE 01000000 mov esi,0x1 ; 上面的注册码进行了进一步调整
004C26AE |> 8B45 F4 /mov eax,
004C26B1 |. 807C30FF 4F |cmp byte ptr ds:,0x4F
004C26B6 |. 75 0D |jnz X潍坊长远.004C26C5
004C26B8 |. 8D45 F4 |lea eax,这里也是最后一次处理了。
004C26BB |. E8 6426F4FF |call 潍坊长远.00404D24 ; 这里的大概意思是说,处理之后看看是否有字母O
004C26C0 |. C64430 FF 30 |mov byte ptr ds:,0x30 ;如果有则换成数字0
004C26C5 |> 46 |inc esi
004C26C6 |. 83FE 09 |cmp esi,0x9
004C26C9 |.^ 75 E3 \jnz X潍坊长远.004C26AE
004C26CB |. 8D55 F0 lea edx,
004C26CE |. 8B45 F4 mov eax, ;将变量3中字母转成大写
004C26D1 |. E8 C265F4FF call 潍坊长远.00408C98 ;UpperCase(AnsiString)
004C26D6 |. 8B55 F0 mov edx,
004C26D9 |. 8D45 F4 lea eax,
004C26DC |. E8 C321F4FF call 潍坊长远.004048A4 ; System.@LStrLAsg
004C26E1 |. 8BC7 mov eax,edi
004C26E3 |. 8B55 F4 mov edx,
004C26E6 |. E8 7521F4FF call 潍坊长远.00404860 ; System.@LStrAsg
004C26EB |. 33C0 xor eax,eax
004C26ED |. 5A pop edx
004C26EE |. 59 pop ecx
004C26EF |. 59 pop ecx
004C26F0 |. 64:8910 mov dword ptr fs:,edx
004C26F3 |. 68 0D274C00 push 潍坊长远.004C270D
004C26F8 |> 8D45 F0 lea eax,
004C26FB |. BA 04000000 mov edx,0x4
004C2700 |. E8 2B21F4FF call 潍坊长远.00404830 ; System.@LStrArrayClr好了。我们解读下算法。
通过上面的分析,整个注册都在“注册”按钮事件里面处理完成,我们大致总结一下算法(我们试注册的码称假码)。
假码处理:注册码必须是8位字符,不包括两端的空格键,不能有英文字母O,如果有则用数字0替换掉了,但对我们没有影响,它会自动替换掉。
注册码:先取1-4位处理,5-8位处理,最后就是打乱它们的位置
我们开始编写注册机。我用的编辑器是VS 2013 C#写的
namespace csharp_reg
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
//首先我们要有一个字符串来存机器码
private void Btn_Reg_Click(object sender, EventArgs e)
{
if (TB_REGCODE.Text.ToString().Length != 8)
return;
char[] MCODE=new char;
char[] KEYWORD=new char;
int i = 0;
MCODE = TB_REGCODE.Text.ToString().ToCharArray();
//一、对机器码的前4位的处理
for(;i<4;i++)
{
char k;
//如果是数字
if (Char.IsNumber(MCODE))
{
k = MCODE;
k +=Convert.ToChar( (i+1)*2 +17);
MCODE = k;
}
//其它的我们在这里处理
else
{
k = MCODE;
if (k <= ('Z' - (i+1)))
{
MCODE = Convert.ToChar(k + i + 1);
}
else
{
if (k < ('Z'+1 - (i + 1)))
{
MCODE = k;
}
else
{
if (k > 'Z')
{
MCODE = k;
}
else
{
k = Convert.ToChar((Convert.ToInt16(k)-26 + i+1));
MCODE = k;
}
}
}
}
}
//二是、对机器码的后4位的处理
/*
30下 直接存起来。
30-37 +2 结束
38-39 -8 存起来
40 直接存
41 -41 转ASCII+30存
41-5A 里面值 -41
小于存, 如果大于10 -10 还大于10就再减10*/
for (; i < 8; i++)
{
if( (MCODE < '0')||(MCODE=='@'))
{
Console.WriteLine(MCODE);
}
else
{
if (MCODE < '8')
{
MCODE = Convert.ToChar((MCODE + 2));
continue;
}
if (MCODE < 'A')
{
MCODE =Convert.ToChar((MCODE + 8));
continue;
}
if (MCODE >= 'A')
{
int K = MCODE - 'A';
if (K < 10)
{
MCODE = Convert.ToChar(K + 48);
}
else
{
if (K < 10)
{
MCODE = Convert.ToChar(K + 48);
}
else
{
K -= 10;
MCODE = Convert.ToChar(K + 48);
}
}
}
}
}
//三是、换位,成型!
KEYWORD = MCODE;
KEYWORD = MCODE;
KEYWORD = MCODE;
KEYWORD = MCODE;
KEYWORD = MCODE;
KEYWORD = MCODE;
KEYWORD = MCODE;
KEYWORD = MCODE;
string msg=null;
for (i = 0; i < 8; i++)
{
msg += KEYWORD.ToString();
}
this.textBox_reg.Text = msg;
}
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
System.Diagnostics.Process.Start("iexplore.exe", <A >www.xuepojie.com</A>);
}
}
}
注册机源码下载:
{:5_116:}抢到沙发拿到奖励谢谢楼主的分享哦!
膜拜玩算法的大牛
同上,膜拜会算法的大牛。
这个不错啊,正是需要
一看就很流弊
新人求解,局部变量4 是什么意思
首先感谢大神的原创教程,让我又学到新的技能!
给力啊不服不行!!!!!!!!!!!!我喜欢我考100分
感谢,新技能get!