易木马 发表于 2015-1-31 22:23

某某驾校驾驶员理论模拟考试系统4.2算法分析及注册机编写

软件名称:潍坊长远驾校驾驶员理论模拟考试系统4.2(收费版)加壳方式:无运行平台:windows delphi作者:DevilMayCry(易木马)工具:OD 、DeDe v3.50.04内容提示:1、简介            2、运行            3、载入DeDe             4、OD分析            5、算法解读            6、注册机编写一、简介    潍坊长远驾校驾驶员理论模拟考试系统是一套用于驾驶证理论考试训练的专用软件,先以科学的循序渐近的方法进行各类别的训练,最后以一种仿真考试的形式进行水平测试。该软件的主要特点是能够为您提供真实的考试环境,其电脑小键盘布局与真实考试键盘完全对应,使您平时就能在考试环境中练习,因而能够轻松进入考试状态,在最短的时间内获得最佳的成绩。二、试运行下载下来之后是一个安装包,安装之后运行,看看有没有什么能够帮助到我们的。好了,有用的大概也就这么多吧。 三、载入DeDe    从上面的情况来看,有独立的注册窗体,我们用dede来找到“注册”按键事件。直接原程序拖进Dede.找到注册的按钮事件入口:004C2128 >/.55            push ebp                              ;注册按钮
004C2129|.8BEC         mov ebp,esp
004C212B|.33C9          xor ecx,ecx
四、OD 分析    在OD里转到004C2128位置,下断进行分析,就不截图了:004C2138|.68 2E224C00   push 潍坊长远.004C222E
004C213D|.64:FF30      push dword ptr fs:
004C2140|.64:8920      mov dword ptr fs:,esp
004C2143|.8D55 F0       lea edx,                ;局部变量4,放假码的
004C2146|.8B86 14030000 mov eax,dword ptrds:   ;EAX放的是Edit_zcm : TEdit
004C214C|.E89B74F8FF   call 潍坊长远.004495EC   ;GetText(TControl):TCaption;
004C2151|.8B45 F0       mov eax,
004C2154|.8D55 F8       lea edx,            ;变量2是4 去前后空格的值
004C2157|.E8 8C6DF4FF   call 潍坊长远.00408EE8   ; SysUtils.Trim(AnsiString)
004C215C|.8B45 F8      mov eax,
004C215F|.E8 6829F4FFcall 潍坊长远.00404ACC      ;大概是取字符长度
004C2164|.83F808       cmp eax,0x8
004C2167|.7D 0F         jge X潍坊长远.004C2178   ;小于时出错
004C2169|.B8 44224C00   moveax,潍坊长远.004C2244;ASCII "注册码格式错误!\r\r请输入8位注册码错误。"
004C216E|.E8 4D0EF7FFcall 潍坊长远.00432FC0
004C2173|.E9 93000000jmp 潍坊长远.004C220B         ; 4C220B是结束位置
004C2178|>BB 01000000mov ebx,0x1
004C217D|>8B45 F8       /mov eax,
004C2180|.807C18FF 4F|cmp byte ptr ds:,0x4F;在注册码里面查找注册码,英文字母“o“
004C2185|.75 0D      |jnz X潍坊长远.004C2194         ;没有就进行下一次循环
004C2187|.8D45 F8       |lea eax,
004C218A|.E8952BF4FF   |call 潍坊长远.00404D24
004C218F|. C64418 FF 30|mov byte ptrds:,0x30; 有就在这里用数字“0”不替换掉
004C2194|>43         |inc ebx
004C2195|.83FB 09      |cmp ebx,0x9
004C2198|.^ 75 E3         \jnz X潍坊长远.004C217D
004C219A|. 8D55 FC       lea edx,                  ;变量1
004C219D|.8BC6         mov eax,esi      ;这里ESI中放的是控件机器码框的ID号
004C219F|.E800070000   call 潍坊长远.004C28A4         ; 取出机器码放在变量1里面
004C21A4|. 8D4D F4       leaecx,               ;变量3的地址
004C21A7|.8B55FC       mov edx,                ;变量1,机器码
004C21AA|.8BC6         mov eax,esi
004C21AC|.E8 6F030000call 潍坊长远.004C2520 ;真注册码计算CALL我们要进去
004C21B1|.8B45 F8       mov eax,                  ;替换后的假码
004C21B4|.8B55 F4       mov edx,               ;计算后的真假
004C21B7|.E8 5C2AF4FF   call 潍坊长远.00404C18          ;System.@LStrCmp;
004C21BC|.75 43      jnz X潍坊长远.004C2201          ; 关键跳转
我们到注册码计算的位置去看看,去分析一下,看看算法:004C2520/$55         push ebp   入口
004C2536|.E8 8127F4FF   call 潍坊长远.00404CBC                      ;System.@LStrAddRef(void;void):Pointer;
004C253B|.33C0          xor eax,eax                        ;机器码
004C253D|.55         push ebp
004C253E|.68 06274C00   push 潍坊长远.004C2706
004C2543|.64:FF30      push dword ptr fs:
004C2546|.64:8920      mov dword ptr fs:,esp
004C2549|.8D45 F8       lea eax,                     ;变量2
004C254C|. 8B55 FC       mov edx,
004C254F|.E8 5023F4FFcall潍坊长远.004048A4            ;System.@LStrLAsg
004C2554|.BE 01000000mov esi,0x1          ;下面可以看见是对机器进行计算
004C2559|>8B45 FC      /mov eax,
004C255C|. 33DB          |xor ebx,ebx
004C255E|.8A5C30 FF    |mov bl,byte ptr ds:;依次取出每一位的ASCII值
004C2562|.83FB 30      |cmp ebx,0x30
004C2565|.7C0B         |jl X潍坊长远.004C2572
004C2567|.83FB 39      |cmp ebx,0x39
004C256A|.7F 06      |jg X潍坊长远.004C2572   ;如果是0-9,ASCII+位数+0x11
004C256C|. 8D441E 11   |lea eax,dword ptrds:
004C2570|.8BD8         |mov ebx,eax
004C2572|>83FB 41      |cmp ebx,0x41
004C2575|.7C0F         |jl X潍坊长远.004C2586
004C2577|.B8 5A000000   |mov eax,0x5A                           ;"Z'
004C257C|. 2BC6          |sub eax,esi       ;"z"-位数与位数上的数的ASCII码比较
004C257E|.3BD8         |cmp ebx,eax
004C2580|.7F04         |jg X潍坊长远.004C2586
004C2582|.03DE         |add ebx,esi                        ;就再加一次位数
004C2584|.EB 16      |jmp X潍坊长远.004C259C
004C2586|>B8 5A000000   |mov eax,0x5A
004C258B|.2BC6         |sub eax,esi
004C258D|.40         |inc eax
004C258E|.3BD8         |cmp ebx,eax
004C2590|.7C0A         |jl X潍坊长远.004C259C
004C2592|.83FB 5A       |cmp ebx,0x5A
004C2595|.7F05         |jg X潍坊长远.004C259C
004C2597|.83EB 1A       |subebx,0x1A
004C259A|. 03DE          |add ebx,esi
004C259C|> 8D45 F8       |lea eax,
004C259F|.E8 8027F4FF|call 潍坊长远.00404D24
004C25A4|.885C30 FF    |mov byte ptr ds:,bl;把计算的每一位都放回去
004C25A8|. 46            |inc esi
004C25A9|. 83FE 05       |cmp esi,0x5          ; ESI每次增长一
004C25AC|.^ 75 AB         \jnz X潍坊长远.004C2559   ;前4位就这样计算结束了
004C25AE|.BE 05000000mov esi,0x5         
    到此前四位结束了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|.7F 05      |jg X潍坊长远.004C25CB                      ;>8
004C25C6|.83C3 02      |add ebx,0x2            ;如果是0-7之间的数字,则加2
004C25C9|.EB0D         |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       |cmpebx,0x5A
004C25E0|.7F24         |jg X潍坊长远.004C2606                ;“z”
004C25E2|.83EB 41      |sub ebx,0x41
004C25E5|.83FB 0A       |cmpebx,0xA
004C25E8|.7C03         |jl X潍坊长远.004C25ED      ;下面两个字符串也说明了,如果是A-J,则减41,B-Z,则减4B
004C25EA|.83EB 0A       |subebx,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       |cmpebx,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|.7C 03      |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
到此后4位结束了。004C2618|.8D45 F4       lea eax,
004C261B|.8B55 F8       mov edx,
004C261E|.E8 8122F4FF   call 潍坊长远.004048A4      ;大概是拷贝了一份放在变量3里面了吧
004C2623|.8D45 F4       lea eax,
004C2626|.E8 F926F4FFcall 潍坊长远.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|.8A52 07      mov dl,byte ptr ds:         ;7
004C2652|.8850 02      mov byte ptr ds:,dl         ;2
004C2655|.8D45 F4       lea eax,
004C2658|.E8 C726F4FFcall 潍坊长远.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 A626F4FFcall 潍坊长远.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 9526F4FFcall 潍坊长远.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|.8A52 05      mov dl,byte ptr ds:         ;5换7.
004C26A6|. 8850 07       mov byte ptrds:,dl
004C26A9|.BE01000000   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 ptrds:,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 C265F4FFcall 潍坊长远.00408C98       ;UpperCase(AnsiString)
004C26D6|.8B55 F0       mov edx,
004C26D9|.8D45 F4       lea eax,
004C26DC|.E8 C321F4FFcall 潍坊长远.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 ptrfs:,edx
004C26F3|.680D274C00   push 潍坊长远.004C270D
004C26F8|> 8D45 F0       lea eax,
004C26FB|.BA 04000000mov edx,0x4
004C2700|.E8 2B21F4FF   call 潍坊长远.00404830         ; System.@LStrArrayClr
五、算法解读    通过上面的分析,整个注册都在“注册”按钮事件里面处理完成,我们大致总结一下算法(我们试注册的码称假码)。    1、假码处理:注册码必须是8位字符,不包括两端的空格键,不能有英文字母O,如果有则用数字0替换掉了,但对我们没有影响,它会自动替换掉。    2、注册码:先取1-4位处理,5-8位处理,最后就是打乱它们的位置,字符替换。
六、注册机编写    C#注册机原始代码见://一、对机器码的前位的处理
            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;
                            } }}}}
//二是、对机器码的后位的处理
            /*
            30下直接存起来。
            30-37+2 结束
            38-39-8   存起来
            40   直接存
            41-41 转ASCII+30存
            41-5A 里面值-41
            小于存, 如果大于-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;
            stringmsg=null;
            for(i = 0; i < 8; i++)
            {
                msg +=KEYWORD.ToString();
            }
            this.textBox_reg.Text= msg;
         }原代码见附件:如有什么不对,希望大家指正,后面跟贴子

shantnyou 发表于 2015-4-27 21:56

豆芽~ 发表于 2015-2-23 15:47
楼主的注册机 在我的系统注册失败了,于是尝试了下 制作了一个内存补丁
然后··附上 过程:http://user.q ...

谢谢 你给我 这套 比较 好用 我郁闷的是 我要的是 科目四 来的 是 科目1

豆芽~ 发表于 2015-2-23 15:47

楼主的注册机 在我的系统注册失败了,于是尝试了下 制作了一个内存补丁
然后··附上 过程:http://user.qzone.qq.com/1608600868/2

我是小白,并无冒犯的意思,请多多关照

yutao531315 发表于 2015-1-31 22:28

前排镇楼.............支持楼主

快乐的2B 发表于 2015-1-31 22:28

有什么用啊?

lpxx 发表于 2015-1-31 22:34

科目二考过了,我是来看你的算法的。

Chinawlcc 发表于 2015-1-31 22:39

支持原创,楼主辛苦了。

双菜鱼 发表于 2015-1-31 22:42

膜拜楼主大大,学习了,明天才有分可以给你加了,很详细的教程{:1_931:}

丶毛毛 发表于 2015-1-31 22:44

表弟要考,楼主发个现成的   

tony8888 发表于 2015-1-31 22:53

很详细, 支持

帅斌 发表于 2015-1-31 22:59

楼主给个现成的   准备报考了。提前学习也好

Ascian 发表于 2015-1-31 23:24

支持楼主    算法都会分析
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 某某驾校驾驶员理论模拟考试系统4.2算法分析及注册机编写