作 者: zyr零零发
时 间: 2010-02-27
【破文标题】Editplus v3.12(bilud 531)最新版算法分析并注册
【破文作者】zyr零零发
【破解工具】OD
【破解平台】Win7(xpxp3亦可)
【程序下载】http://search.newhua.com/search_list.php?searchname=editplus&search=1&button=+%E6%8F%90+%E4%BA%A4+ 最新版。
【保护方式】用户名 注册码
【软件简介】一套功能强大,可取代记事本的文字编辑器,拥有无限制的 Undo/Redo、英文拼字检查、自动换行、列数标记、搜寻取代、同时编辑多文件。。。。。
【破解声明】我以前一直用它,我觉得还不错的。本论坛有一篇以前版本分析算法的文章,现在是最新版的,
算法验证不同了,感兴趣请自行搜索。破解完后,虽然注册了,也避开了重启验证,但是重启验证的代码没找
到,有感兴趣的可以找找看,然后告诉我,不胜感激啊。。。注册脱离OD不行。纯粹是
学习讨论,没别的目的。第一次发破文,失误之处请多指教。此文版权所有,转载需注明作者!
【破解内容】
首先用OD打开程序,F9运行,输入用户名(zyr零零发)和假码(34567890),假码要求八位以上吧,我用8位假码,没仔细研
究。BPX GetWindowTextW(此程序用到的API大部分是UNIONCODE)下断点,按Register按钮,在此处断下:
004DED15 |. FF15 A0B55000 call dword ptr [<&USER32.GetWindowTex>; \GetWindowTextW
接下来是验证用户名和假码中有违规字符,看下面代码(也可略过不看):
00495DAF |. E8 4F8F0400 call 004DED03
00495DB4 |> 66:8B06 /mov ax, word ptr [esi]
00495DB7 |. 66:3D 2000 |cmp ax, 20 ; 第一个字符是否空格
00495DBB |. 74 06 |je short 00495DC3
00495DBD |. 66:3D 0900 |cmp ax, 9 ; 第一个字符是否句号
00495DC1 |. 75 05 |jnz short 00495DC8
00495DC3 |> 83C6 02 |add esi, 2
00495DC6 |.^ EB EC \jmp short 00495DB4
00495DC8 |> 56 push esi
00495DC9 |. E8 23550300 call 004CB2F1 ; 验证用户名中有否0
00495DCE >|. 8B4C24 18 mov ecx, dword ptr [esp+18]
00495DD2 |. 83C4 04 add esp, 4
00495DD5 |. 85C0 test eax, eax ; 验证用户名长度是否为0
00495DD7 |. 8901 mov dword ptr [ecx], eax
00495DD9 |. 7E 1A jle short 00495DF5
00495DDB |> 8B01 /mov eax, dword ptr [ecx]
00495DDD |. 66:8B5446 FE |mov dx, word ptr [esi+eax*2-2]
一路F8到了关键点(从这里必看):
00495ED7 . E8 84000000 call 00495F60 ; 依次验证假码第三,四位,一位,二位,真确的话
EAX返回1
要F7跟进去:
00495F60 /$ 81EC 34020000 sub esp, 234
00495F66 |. 53 push ebx
00495F67 |. 8B9C24 3C0200>mov ebx, dword ptr [esp+23C] ; 取用户名到EDX
00495F6E |. 56 push esi
00495F6F |. 57 push edi
00495F70 |. 53 push ebx
00495F71 >|. E8 7B530300 call 004CB2F1 ; 验证用户名字符中是否有
0,EAX返回用户名长度
00495F76 |. 8BF0 mov esi, eax
00495F78 |. 83C4 04 add esp, 4
00495F7B |. 85F6 test esi, esi ; 又一次验证用户名是否输
入为空
00495F7D |. 75 0A jnz short 00495F89
00495F7F |. 5F pop edi
00495F80 |. 5E pop esi
00495F81 |. 5B pop ebx
00495F82 |. 81C4 34020000 add esp, 234
00495F88 |. C3 retn
00495F89 |> 8BBC24 480200>mov edi, dword ptr [esp+248] ; 取假码到EDI
00495F90 |. 55 push ebp
00495F91 |. 57 push edi
00495F92 |. E8 5A530300 call 004CB2F1 ; 验证假码字符中是否有空
格,EAX返回假码长度
00495F97 |. 83C4 04 add esp, 4
00495F9A |. 8BE8 mov ebp, eax
00495F9C |. 8D4424 50 lea eax, dword ptr [esp+50]
00495FA0 |. 6A 00 push 0 ; /pDefaultCharUsed =
NULL
00495FA2 |. 6A 00 push 0 ; |pDefaultChar = NULL
00495FA4 |. 68 F3010000 push 1F3 ; |MultiByteCount = 1F3
(499.)
00495FA9 |. 50 push eax ; |MultiByteStr
00495FAA |. 56 push esi ; |WideCharCount
00495FAB |. 53 push ebx ; |WideCharStr
00495FAC |. 8B1D 60B45000 mov ebx, dword ptr [<&KERNEL32.WideC>; |
kernel32.WideCharToMultiByte
00495FB2 |. 6A 00 push 0 ; |Options = 0
00495FB4 |. 6A 00 push 0 ; |CodePage = CP_ACP
00495FB6 |. FFD3 call ebx ; \WideCharToMultiByte
00495FB8 |. 6A 00 push 0 ; /pDefaultCharUsed =
NULL
00495FBA |. 6A 00 push 0 ; |pDefaultChar = NULL
00495FBC |. 8D4C24 24 lea ecx, dword ptr [esp+24] ; |
00495FC0 |. 6A 31 push 31 ; |MultiByteCount = 31
(49.)
00495FC2 |. 51 push ecx ; |MultiByteStr
00495FC3 |. 55 push ebp ; |WideCharCount
00495FC4 |. 8BF0 mov esi, eax ; |
00495FC6 |. 57 push edi ; |WideCharStr
00495FC7 |. 6A 00 push 0 ; |Options = 0
00495FC9 |. 6A 00 push 0 ; |CodePage = CP_ACP
00495FCB |. C64434 70 00 mov byte ptr [esp+esi+70], 0 ; |
00495FD0 |. FFD3 call ebx ; \WideCharToMultiByte
00495FD2 |. 8BF8 mov edi, eax ; 假码长度送EDI
00495FD4 |. C6443C 1C 00 mov byte ptr [esp+edi+1C], 0 ; 将0送12ED9C指向的一个
字节
00495FD9 |. E8 92F6FFFF call 00495670 ; 动态生成以数据表,大小
128B,和用户名假码无关。
00495FDE |. 8D5424 50 lea edx, dword ptr [esp+50] ; 取用户名到EDX
00495FE2 |. 56 push esi ; 用户名长度入栈
00495FE3 |. 52 push edx ; 用户名入栈
00495FE4 |. 6A 00 push 0 ;
00495FE6 |. E8 D5F6FFFF call 004956C0 ; 把用户名每位字母和上表
运算得出数据6F61
00495FEB |. 83C4 0C add esp, 0C
00495FEE |. 25 FFFF0000 and eax, 0FFFF
00495FF3 |. 50 push eax ; 把运算的数据入栈保存
00495FF4 |. 8D4424 14 lea eax, dword ptr [esp+14]
00495FF8 |. 68 80D45300 push 0053D480 ; ASCII "%02X"
00495FFD |. 50 push eax ; EAX是个空白指针12ED88
内容是0000000D
00495FFE |. E8 91640300 call <wsprintf> ; 就是wsprintf函数,把
6F61转换为字符
00496003 |. 8A4C24 2A mov cl, byte ptr [esp+2A] ; 取假码第三位
00496007 |. 8A4424 1C mov al, byte ptr [esp+1C] ; 取真码6F61的第一位
0049600B |. 83C4 0C add esp, 0C
0049600E |. 3AC8 cmp cl, al
00496010 |. 5D pop ebp
00496011 |. 74 0C je short 0049601F
00496013 |. 5F pop edi
00496014 |. 5E pop esi
00496015 |. 33C0 xor eax, eax
00496017 |. 5B pop ebx
00496018 |. 81C4 34020000 add esp, 234
0049601E |. C3 retn
0049601F |> 8A5424 1B mov dl, byte ptr [esp+1B] ; 取假码的第四字符,那么
假码改为346F7890
00496023 |. 8A4424 0D mov al, byte ptr [esp+D] ; 取6F61第二个字符F
00496027 |. 3AD0 cmp dl, al
00496029 |. 74 0C je short 00496037
0049602B |. 5F pop edi
0049602C |. 5E pop esi
0049602D |. 33C0 xor eax, eax
0049602F |. 5B pop ebx
00496030 |. 81C4 34020000 add esp, 234
00496036 |. C3 retn
00496037 |> 83C7 FE add edi, -2
0049603A |. 8D4424 1A lea eax, dword ptr [esp+1A]
0049603E |. 57 push edi
0049603F |. 50 push eax
00496040 |. 6A 00 push 0
00496042 |. E8 79F6FFFF call 004956C0 ; 取假码后六位计算第二组
真码返回EAX值5AC0
00496047 |. 83C4 0C add esp, 0C
0049604A |. 25 FFFF0000 and eax, 0FFFF
0049604F |. 8D4C24 0C lea ecx, dword ptr [esp+C]
00496053 |. 50 push eax
00496054 |. 68 80D45300 push 0053D480 ; ASCII "%02X"
00496059 |. 51 push ecx
0049605A |. E8 35640300 call <wsprintf>
0049605F |. 8A5424 24 mov dl, byte ptr [esp+24] ; 取假码第一位
00496063 |. 8A4424 18 mov al, byte ptr [esp+18] ; 取真码第一位
00496067 |. 83C4 0C add esp, 0C
0049606A |. 3AD0 cmp dl, al
0049606C |. 74 0C je short 0049607A
0049606E |. 5F pop edi
0049606F |. 5E pop esi
00496070 |. 33C0 xor eax, eax
00496072 |. 5B pop ebx
00496073 |. 81C4 34020000 add esp, 234
00496079 |. C3 retn
0049607A |> 8A4C24 19 mov cl, byte ptr [esp+19]
0049607E |. 8A5424 0D mov dl, byte ptr [esp+D]
00496082 |. 33C0 xor eax, eax
00496084 |. 3ACA cmp cl, dl
00496086 |. 5F pop edi
00496087 |. 5E pop esi
00496088 0F94C0 sete al
0049608B |. 5B pop ebx
0049608C |. 81C4 34020000 add esp, 234
00496092 \. C3 retn
以上这段代码看起来比较乱,大致的思路是这样的:
从这儿说起吧,00495FD9 |. E8 92F6FFFF call 00495670(上面的代码看注释就不写了)。
这个CALL生成一个128b大小的数据块,就叫他是一张表吧,下面的算法要用到其中的数据。在这就不贴这张表的代码了
。
往下到这儿:
00495FE6 |. E8 D5F6FFFF call 004956C0
这个CALL就是计算真码的,第一次调用(调用了三次)是根据用户名和上面的表生成一组真码,我这里是‘6F61’,返回在AX
中。
接下来到这里:
0049605A |. E8 35640300 call <wsprintf>
我这里看到的是<wsprintf>,在你的OD里可能是地址004CC494,我把它加了标签了。功能是把‘6F61’转化为
字符。
紧接着就是第一次验证:
00496003 |. 8A4C24 2A mov cl, byte ptr [esp+2A] ; 取假码第三位
00496007 |. 8A4424 1C mov al, byte ptr [esp+1C] ; 取真码6F61的第一位
0049600B |. 83C4 0C add esp, 0C
0049600E |. 3AC8 cmp cl, al
00496010 |. 5D pop ebp
00496011 |. 74 0C je short 0049601F
就是假码第三个字符5和6比较,6从哪里来?6从上面6F61的第一个字符来的。若相同往下跳,继续第二次验证
,到这里:
0049601F |> \8A5424 1B mov dl, byte ptr [esp+1B] ; 取假码的第四字符,那么假
码改为346F7890
00496023 |. 8A4424 0D mov al, byte ptr [esp+D] ; 取6F61第二个字符F
00496027 |. 3AD0 cmp dl, al
00496029 |. 74 0C je short 00496037
假码第四个字符6和F比较,F从从上面6F61的第二个字符来的。
根据以上程序验证,我把我的假码34567890改为346F6190,注意是把假码替换了四位,把78也换了。让以上验
证成功。
若相同往下跳,到这里:
00496037 |> \83C7 FE add edi, -2
0049603A |. 8D4424 1A lea eax, dword ptr [esp+1A]
0049603E |. 57 push edi
0049603F |. 50 push eax
00496040 |. 6A 00 push 0
00496042 |. E8 79F6FFFF call 004956C0 ; 取假码后六位计算第二组真
码返回AX值5AC0
第二次 call 004956C0,(第一次在那里?还有第三次调用,是根据机器硬盘序列号和生成的表生成第三
组真码,不过在这里用不上,感兴趣请自行分析),取假码346F6190中的后6位6F6190,和上面生成的表计算出
第二组真码,同样返回在AX中,我这里是5AC0。接下来还是用0049605A |. E8 35640300 call
<wsprintf>把5AC0转化为字符。接下来当然是验证了:
0049605F |. 8A5424 24 mov dl, byte ptr [esp+24] ; 取假码第一位
00496063 |. 8A4424 18 mov al, byte ptr [esp+18] ; 取真码5AC0第一位
00496067 |. 83C4 0C add esp, 0C
0049606A |. 3AD0 cmp dl, al
0049606C |. 74 0C je short 0049607A
0049606E |. 5F pop edi
0049606F |. 5E pop esi
00496070 |. 33C0 xor eax, eax
00496072 |. 5B pop ebx
00496073 |. 81C4 34020000 add esp, 234
00496079 |. C3 retn
0049607A |> 8A4C24 19 mov cl, byte ptr [esp+19];取假码第二位
0049607E |. 8A5424 0D mov dl, byte ptr [esp+D];取真码5AC0第二位
00496082 |. 33C0 xor eax, eax
00496084 |. 3ACA cmp cl, dl
为了验证成功,把假码改为5A6F6190,接下来就简单了,一路F8,直到程序出现重启验证的对话框,这时关闭
OD,重启程序,在菜单help里看一下:
注册成功!
总结:一,这是侥幸注册成功,用户名和注册码只是用了本文提到的,别的没试过。
二,这是程序验证漏洞?
三,本人水平有限,本文分析的很粗浅,在此抛砖引玉,希望有更好的分析文章出现。
四,希望大家拿它练练手,哈,感觉还是蛮难的。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课