破解实战-第五战
本帖最后由 我是用户 于 2013-6-23 13:49 编辑【软件名称】: 文件夹加密精灵V5.3
【作者邮箱】: 2714608453@qq.com
【下载地址】: http://www.skycn.com/soft/30468.html
【加壳方式】: Microsoft Visual C++ 6.0
【使用工具】: OD
【操作平台】: XP SP2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
前言:
写文章不容易啊,如果对你有帮助的话,就请加下分,给点鼓励哈,小菜还会一直更新下去的!
1.查壳
用PEID查壳,显示Microsoft Visual C++ 6.0。
如图1:
2.爆破:
无壳就直接脱入OD里,运行。未注册版本只能注册20天,把系统时间改掉(只要超过20天就好),弹出试用对话框.
如图2:
因为我是在虚拟机里,所以很容易看出来机器码是硬盘序列号。
输入注册码1234567890,然后点击提交注册码。弹出提示。
如图3:
很明显这是一个重启验证的程序,我们现在来找找注册码保存在哪,右键字符串搜索"请重新运行程序,以验证注册码!"
如图4:
向上找到函数开头,下好CC断点,重新输入注册码,程序断下。
00414620 .6A FF push -0x1
00414622 .68 686D4500 push FolderPr.00456D68 ;SE 处理程序安装
00414627 .64:A1 0000000>mov eax,dword ptr fs:
0041462D .50 push eax
...省略无关代码
00414681 >55 push ebp
00414682 .8BCE mov ecx,esi
00414684 .E8 17020000 call FolderPr.004148A0 ;进入(保存注册码)
00414689 .68 14644600 push FolderPr.00466414 ;\\
0041468E .68 18644600 push FolderPr.00466418 ;\
00414693 .B9 F4A34600 mov ecx,FolderPr.0046A3F4
00414698 .E8 21110000 call <jmp.&MFC42.#?Replace@CString@@QAEHPBD0@Z_6877>
0041469D .8B86 B8000000 mov eax,dword ptr ds:
004146A3 .85C0 test eax,eax
004146A5 .0F85 98000000 jnz FolderPr.00414743
004146AB .8B15 F4A34600 mov edx,dword ptr ds:
004146B1 .68 98744600 push FolderPr.00467498 ; /w
...省略无关代码
0041473A .52 push edx ;ntdll.KiFastSystemCallRet
0041473B .50 push eax
0041473C .8BCE mov ecx,esi
0041473E .E8 2D070000 call FolderPr.00414E70
00414743 >6A 00 push 0x0
00414745 .6A 00 push 0x0
00414747 .68 60744600 push FolderPr.00467460 ;请重新运行程序,以验证注册码!
0041474C .8BCE mov ecx,esi
0041474E .E8 05100000 call <jmp.&MFC42.#?MessageBoxA@CWnd@@QAEHPBD0I@Z_4224>
进入004148A0中
004148A0/$83EC 08 sub esp,0x8
004148A3|.8D4424 04 lea eax,dword ptr ss:
004148A7|.8D4C24 00 lea ecx,dword ptr ss:
004148AB|.50 push eax ; /pDisposition = NULL
004148AC|.51 push ecx ; |pHandle = 0012FFB0
004148AD|.6A 00 push 0x0 ; |pSecurity = NULL
004148AF|.68 3F000F00 push 0xF003F ; |Access = KEY_ALL_ACCESS
004148B4|.6A 00 push 0x0 ; |Options = REG_OPTION_NON_VOLATILE
004148B6|.6A 00 push 0x0 ; |Class = NULL
004148B8|.6A 00 push 0x0 ; |Reserved = 0x0
004148BA|.68 20684600 push FolderPr.00466820 ; |SOFTWARE\Microsoft\FolderPro
004148BF|.68 02000080 push 0x80000002 ; |hKey = HKEY_LOCAL_MACHINE
004148C4|.FF15 0C904500 call dword ptr ds:[<&ADVAPI32.RegCreateKeyExA>] ; \RegCreateKeyExA
004148CA|.85C0 test eax,eax
004148CC|.74 08 je short FolderPr.004148D6
004148CE|.33C0 xor eax,eax
004148D0|.83C4 08 add esp,0x8
004148D3|.C2 0400 retn 0x4
004148D6|>8B5424 0C mov edx,dword ptr ss:
004148DA|.8B4424 00 mov eax,dword ptr ss: ;kernel32.7C817077
004148DE|.6A 14 push 0x14 ; /BufSize = 14 (20.)
004148E0|.52 push edx ; |Buffer = ntdll.KiFastSystemCallRet
004148E1|.6A 01 push 0x1 ; |ValueType = REG_SZ
004148E3|.6A 00 push 0x0 ; |Reserved = 0x0
004148E5|.68 84684600 push FolderPr.00466884 ; |RegSerial
004148EA|.50 push eax ; |hKey = 0x0
004148EB|.FF15 14904500 call dword ptr ds:[<&ADVAPI32.RegSetValueExA>] ; \RegSetValueExA
004148F1|.85C0 test eax,eax
004148F3|.74 08 je short FolderPr.004148FD
004148F5|.33C0 xor eax,eax
004148F7|.83C4 08 add esp,0x8
004148FA|.C2 0400 retn 0x4
004148FD|>8B4C24 00 mov ecx,dword ptr ss: ;kernel32.7C817077
00414901|.51 push ecx ; /hKey = 0012FFB0
00414902|.FF15 10904500 call dword ptr ds:[<&ADVAPI32.RegCloseKey>] ; \RegCloseKey
00414908|.B8 01000000 mov eax,0x1
0041490D|.83C4 08 add esp,0x8
00414910\.C2 0400 retn 0x4
可见注册码保存在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\FolderPro\RegSerial中。
如图5:
知道注册码的保存位置,我们下断RegQueryValueExA。然后Ctrl+F2,程序断下。
如图6:
此时堆栈回溯
如图7:
返回处的代码如下:
00406171 .894C24 34 mov dword ptr ss:,ecx
00406175 .8BCE mov ecx,esi ;FolderPr.0046A2A0
00406177 .E8 A4190000 call FolderPr.00407B20
0040617C .85C0 test eax,eax ;返回到这
0040617E .0F84 C4010000 je FolderPr.00406348 ;nop掉
00406184 .C705 F0664600>mov dword ptr ds:,0x0 ;注册标志位
0040618E .E9 0A040000 jmp FolderPr.0040659D
00406193 >BF 9C674600 mov edi,FolderPr.0046679C ;uninstall
00406198 .8BC2 mov eax,edx
把0040617E处nop掉,F9运行,即可实现注册。
如图8:
3.算法分析:
现在我们追下注册码,用PEID的KANAL插件扫描。
如图9:
有MD5算法,具体分析代码如下:
00408370/$64:A1 0000000>mov eax,dword ptr fs:
00408376|.6A FF push -0x1
00408378|.68 D8564500 push FolderPr.004556D8
0040837D|.50 push eax
0040837E|.64:8925 00000>mov dword ptr fs:,esp
00408385|.83EC 70 sub esp,0x70
00408388|.53 push ebx
00408389|.55 push ebp
0040838A|.56 push esi ;FolderPr.0046A2A0
0040838B|.8BB1 2C010000 mov esi,dword ptr ds:
00408391|.57 push edi ;FolderPr.0046A364
00408392|.8B4E F8 mov ecx,dword ptr ds:
00408395|.83F9 14 cmp ecx,0x14 ;判断机器码是否为0x14位
00408398|.7E 05 jle short FolderPr.0040839F
0040839A|.B9 14000000 mov ecx,0x14
0040839F|>33C0 xor eax,eax
004083A1|.85C9 test ecx,ecx ;FolderPr.0046A2A0
004083A3|.7E 11 jle short FolderPr.004083B6
004083A5|>8A1406 /mov dl,byte ptr ds:
004083A8|.885404 14 |mov byte ptr ss:,dl ;将机器码保存在临时变量里
004083AC|.40 |inc eax
004083AD|.3BC1 |cmp eax,ecx ;FolderPr.0046A2A0
004083AF|.^ 7C F4 \jl short FolderPr.004083A5
004083B1|.83F8 14 cmp eax,0x14
004083B4|.7D 0F jge short FolderPr.004083C5
004083B6|>8AC8 /mov cl,al
004083B8|.80C1 41 |add cl,0x41
004083BB|.884C04 14 |mov byte ptr ss:,cl
004083BF|.40 |inc eax
004083C0|.83F8 14 |cmp eax,0x14
004083C3|.^ 7C F1 \jl short FolderPr.004083B6
004083C5|>8D5424 28 lea edx,dword ptr ss:
004083C9|.52 push edx
004083CA|.E8 716F0000 call FolderPr.0040F340 ;初始化MD5
============================================================================================
0040F340处代码如下:
0040F340/$8B4424 04 mov eax,dword ptr ss: ;FolderPr.0046A3D8
0040F344|.33C9 xor ecx,ecx ;FolderPr.0046A2A0
0040F346|.8948 14 mov dword ptr ds:,ecx ;FolderPr.0046A2A0
0040F349|.8948 10 mov dword ptr ds:,ecx ;FolderPr.0046A2A0
0040F34C|.C700 01234567 mov dword ptr ds:,0x67452301
0040F352|.C740 04 89ABC>mov dword ptr ds:,0xEFCDAB89
0040F359|.C740 08 FEDCB>mov dword ptr ds:,0x98BADCFE
0040F360|.C740 0C 76543>mov dword ptr ds:,0x10325476
0040F367\.C3 retn
//Initialize variables:
var int h0 := 0x67452301
var int h1 := 0xEFCDAB89
var int h2 := 0x98BADCFE
var int h3 := 0x10325476
============================================================================================
004083CF|.8D4424 18 lea eax,dword ptr ss:
004083D3|.6A 14 push 0x14
004083D5|.8D4C24 30 lea ecx,dword ptr ss:
004083D9|.50 push eax
004083DA|.51 push ecx ;FolderPr.0046A2A0
004083DB|.E8 906F0000 call FolderPr.0040F370
004083E0|.8D5424 38 lea edx,dword ptr ss:
004083E4|.8D4424 20 lea eax,dword ptr ss:
004083E8|.52 push edx
004083E9|.50 push eax
004083EA|.E8 F17E0000 call FolderPr.004102E0 ;将机器码进行MD5加密
004083EF|.83C4 18 add esp,0x18
004083F2|.8B4C24 10 mov ecx,dword ptr ss: ;ecx=经MD5加密过的密码
004083F6|.33F6 xor esi,esi ;FolderPr.0046A2A0
004083F8|.8A01 mov al,byte ptr ds: ;MD5加密后的密码第一位给机器码的第一位
004083FA|.884424 14 mov byte ptr ss:,al
004083FE|.8A41 04 mov al,byte ptr ds: ;MD5加密后的密码第五位给机器码的第五位
00408401|.884424 18 mov byte ptr ss:,al
00408405|.8A41 06 mov al,byte ptr ds: ;MD5加密后的密码第七位给机器码的第七位
00408408|.884424 1A mov byte ptr ss:,al
0040840C|.8A51 0C mov dl,byte ptr ds: ;MD5加密后的密码第十三位给机器码的第十三位
0040840F|.885424 20 mov byte ptr ss:,dl
00408413|>8A4434 14 /mov al,byte ptr ss: ;依次取经过处理后的机器码给al
00408417|.3C 30 |cmp al,0x30
00408419|.7C 0C |jl short FolderPr.00408427
0040841B|.3C 39 |cmp al,0x39
0040841D|.7F 08 |jg short FolderPr.00408427
0040841F|.B2 69 |mov dl,0x69 ;当al在0x30和0x39之间时,0x69-al
00408421|.2AD0 |sub dl,al
00408423|.885434 14 |mov byte ptr ss:,dl ;保存dl
00408427|>3C 41 |cmp al,0x41
00408429|.7C 0C |jl short FolderPr.00408437
0040842B|.3C 5A |cmp al,0x5A
0040842D|.7F 08 |jg short FolderPr.00408437
0040842F|.B2 9B |mov dl,0x9B ;当al在0x41和0x5A之时间,0x9B-al
00408431|.2AD0 |sub dl,al
00408433|.885434 14 |mov byte ptr ss:,dl ;保存dl
00408437|>3C 61 |cmp al,0x61
00408439|.7C 0C |jl short FolderPr.00408447
0040843B|.3C 7A |cmp al,0x7A
0040843D|.7F 08 |jg short FolderPr.00408447
0040843F|.B2 DB |mov dl,0xDB ;当al在0x61和0x7A之时间,0xDB-al
00408441|.2AD0 |sub dl,al
00408443|.885434 14 |mov byte ptr ss:,dl ;保存dl
00408447|>46 |inc esi ;FolderPr.0046A2A0
00408448|.83FE 14 |cmp esi,0x14
0040844B|.^ 7C C6 \jl short FolderPr.00408413
0040844D|.8A5424 21 mov dl,byte ptr ss: ;相互换位
00408451|.8A4424 15 mov al,byte ptr ss:
00408455|.885424 15 mov byte ptr ss:,dl
00408459|.8A5424 1E mov dl,byte ptr ss:
0040845D|.884424 21 mov byte ptr ss:,al
00408461|.8A4424 17 mov al,byte ptr ss:
00408465|.885424 17 mov byte ptr ss:,dl
00408469|.8A5424 20 mov dl,byte ptr ss:
0040846D|.8BAC24 900000>mov ebp,dword ptr ss:
00408474|.884424 1E mov byte ptr ss:,al
00408478|.8A4424 19 mov al,byte ptr ss:
0040847C|.885424 19 mov byte ptr ss:,dl
00408480|.8A5424 22 mov dl,byte ptr ss:
00408484|.884424 20 mov byte ptr ss:,al
00408488|.8A4424 1B mov al,byte ptr ss:
0040848C|.885424 1B mov byte ptr ss:,dl
00408490|.8A5424 1C mov dl,byte ptr ss:
00408494|.884424 1C mov byte ptr ss:,al
00408498|.885424 22 mov byte ptr ss:,dl
0040849C|.8BC5 mov eax,ebp
0040849E|.8D5424 14 lea edx,dword ptr ss: ;edx=经过换位后的密码
004084A2|.33F6 xor esi,esi ;FolderPr.0046A2A0
004084A4|.2BC2 sub eax,edx
004084A6|>8D7C34 14 /lea edi,dword ptr ss:
004084AA|.33DB |xor ebx,ebx
004084AC|.0FBE1438 |movsx edx,byte ptr ds:
004084B0|.8A1F |mov bl,byte ptr ds:
004084B2|.3BD3 |cmp edx,ebx
004084B4 0F85 B8000000 |jnz FolderPr.00408572 ;输入的注册码和密码比较,不等就跳
004084BA|.46 |inc esi ;FolderPr.0046A2A0
004084BB|.83FE 10 |cmp esi,0x10 ;这里只比较0x10位
004084BE|.^ 7C E6 \jl short FolderPr.004084A6
004084C0|.8A41 1F mov al,byte ptr ds: ;MD5码的第0x1F位
004084C3|.A2 F4664600 mov byte ptr ds:,al ;为真码的第0x11位
004084C8|.8A51 0F mov dl,byte ptr ds: ;MD5码的第0xF位
004084CB|.8815 F5664600 mov byte ptr ds:,dl ;为真码的第0x12位
004084D1|.8A59 07 mov bl,byte ptr ds: ;MD5码的第0x7位
004084D4|.881D 5C694600 mov byte ptr ds:,bl ;为真码的第0x13位
004084DA|.8A49 03 mov cl,byte ptr ds: ;MD5码的第0x3位
004084DD|.3C 61 cmp al,0x61
004084DF|.880D 5D694600 mov byte ptr ds:,cl ;为真码的第0x14位
004084E5|.72 0B jb short FolderPr.004084F2
004084E7|.3C 7A cmp al,0x7A
004084E9|.77 07 ja short FolderPr.004084F2
004084EB|.2C 20 sub al,0x20 ;如果真码的第0x11位们于0x61和0x7A之间,刚减去0x20,然后再保存
004084ED|.A2 F4664600 mov byte ptr ds:,al ;%&
004084F2|>80FA 61 cmp dl,0x61
004084F5|.72 0E jb short FolderPr.00408505
004084F7|.80FA 7A cmp dl,0x7A
004084FA|.77 09 ja short FolderPr.00408505
004084FC|.80EA 20 sub dl,0x20 ;如果真码的第0x12位们于0x61和0x7A之间,刚减去0x20,然后再保存
004084FF|.8815 F5664600 mov byte ptr ds:,dl ;&
00408505|>80FB 61 cmp bl,0x61
00408508|.72 0E jb short FolderPr.00408518
0040850A|.80FB 7A cmp bl,0x7A
0040850D|.77 09 ja short FolderPr.00408518
0040850F|.80EB 20 sub bl,0x20 ;如果真码的第0x13位们于0x61和0x7A之间,刚减去0x20,然后再保存
00408512|.881D 5C694600 mov byte ptr ds:,bl ;'(
00408518|>80F9 61 cmp cl,0x61
0040851B|.72 0E jb short FolderPr.0040852B
0040851D|.80F9 7A cmp cl,0x7A
00408520|.77 09 ja short FolderPr.0040852B
00408522|.80E9 20 sub cl,0x20 ;如果真码的第0x14位们于0x61和0x7A之间,刚减去0x20,然后再保存
00408525|.880D 5D694600 mov byte ptr ds:,cl ;(
0040852B|>0FBE45 10 movsx eax,byte ptr ss:
0040852F|.8B15 F4664600 mov edx,dword ptr ds: ;%&
00408535|.81E2 FF000000 and edx,0xFF
0040853B|.3BD0 cmp edx,eax ;比较第0x11位
0040853D|.75 4B jnz short FolderPr.0040858A
0040853F|.0FBE45 11 movsx eax,byte ptr ss:
00408543|.33D2 xor edx,edx
00408545|.8A15 F5664600 mov dl,byte ptr ds: ;&
0040854B|.3BD0 cmp edx,eax ;比较第0x12位
0040854D|.75 3B jnz short FolderPr.0040858A
0040854F|.0FBE45 12 movsx eax,byte ptr ss:
00408553|.33D2 xor edx,edx
00408555|.8A15 5C694600 mov dl,byte ptr ds: ;'(
0040855B|.3BD0 cmp edx,eax ;比较第0x13位
0040855D|.75 2B jnz short FolderPr.0040858A
0040855F|.0FBE45 13 movsx eax,byte ptr ss:
00408563|.33D2 xor edx,edx
00408565|.8AD1 mov dl,cl
00408567|.3BD0 cmp edx,eax ;比较第0x14位
00408569|.75 1F jnz short FolderPr.0040858A
0040856B|.BE 01000000 mov esi,0x1 ;验证通过,esi=1
00408570|.EB 1A jmp short FolderPr.0040858C
00408572|>8D4C24 10 lea ecx,dword ptr ss:
00408576|.C78424 880000>mov dword ptr ss:,-0x1
00408581|.E8 A8D10000 call <jmp.&MFC42.#??1CString@@QAE@XZ_800>
00408586|.33C0 xor eax,eax
00408588|.EB 18 jmp short FolderPr.004085A2
0040858A|>33F6 xor esi,esi ;FolderPr.0046A2A0
0040858C|>8D4C24 10 lea ecx,dword ptr ss:
00408590|.C78424 880000>mov dword ptr ss:,-0x1
0040859B|.E8 8ED10000 call <jmp.&MFC42.#??1CString@@QAE@XZ_800>
004085A0|.8BC6 mov eax,esi ;FolderPr.0046A2A0
004085A2|>8B8C24 800000>mov ecx,dword ptr ss:
004085A9|.5F pop edi ;FolderPr.00407BAC
004085AA|.5E pop esi ;FolderPr.00407BAC
004085AB|.5D pop ebp ;FolderPr.00407BAC
004085AC|.5B pop ebx ;FolderPr.00407BAC
004085AD|.64:890D 00000>mov dword ptr fs:,ecx ;FolderPr.0046A2A0
004085B4|.83C4 7C add esp,0x7C
004085B7\.C2 0400 retn 0x4
程序算法如下:
第一步:
程序先将机器码(000000000000001)进行MD5加密,得到密码1(a47014b09dec2c3c6fccf840b5a89840)
第二步:
取密码1的第一位给机器码的第一位
取密码1的第五位给机器码的第五位
取密码1的第七位给机器码的第七位
取密码1的第十三位给机器码的第十三位
得到密码2(z99989y9999979999998)
第三步:
依次取密码2的的每一位(al)如下判断:
al在0x30和0x39之间时,0x69-al
al在0x41和0x5A之时间,0x9B-al
al在0x61和0x7A之时间,0xDB-al
得到密码3(z99989y9999979999998)
第四步:
密码2中部分进行相互换位,得到密码4(z99987y9999999999998)
到了这第四步,密码的0x10位是正常的,0x11到0x14位请看第五步.
第五步:
MD5码的第0x1F位为真码的第0x11位(如果位于0x61和0x7A之间,则减去0x20)
MD5码的第0xF位为真码的第0x12位(如果位于0x61和0x7A之间,则减去0x20)
MD5码的第0x7位为真码的第0x13位(如果位于0x61和0x7A之间,则减去0x20)
MD5码的第0x3位为真码的第0x14位(如果位于0x61和0x7A之间,则减去0x20)
得到真码5(z99987y9999999990C00)
输入真码,注册成功,试用框窗口消失,
如图10:
=================================================================
传送门:
破解实战-第一战:http://www.52pojie.cn/thread-197281-1-1.html
破解实战-第二战:http://www.52pojie.cn/thread-197598-1-1.html
破解实战-第三站:http://www.52pojie.cn/thread-197957-1-1.html
破解实战-第四站:http://www.52pojie.cn/thread-198203-1-1.html
破解实战-第五战:http://www.52pojie.cn/thread-198365-1-1.html
破解实战-第六战:http://www.52pojie.cn/thread-198930-1-1.html
破解实战-第七战:http://www.52pojie.cn/thread-199459-1-1.html
破解实战-第八战:http://www.52pojie.cn/thread-199834-1-1.html
破解实战-第九战:http://www.52pojie.cn/thread-200655-1-1.html
破解实战-第十战:http://www.52pojie.cn/thread-200798-1-1.html
{:301_993:}非常感谢楼主 这么好的教程小菜菜研究了 下发现!
mov eax, dword ptr 这个地址是全局注册的标志!
这个地址的值是1为未注册0就是注册了!
{:17_1068:}希望得到大大更多的指教 就是关于堆栈回溯的 详细过程!{:17_1069:}
前辈,有个问题请教下:我下bp RegQueryValueExA,为啥下在了77DA7ABB这么个地址上?这个是不是DLL的地址还是什么函数的地址是吗?altF9也返回不到你下断的那个地址,请指教下。
----------------------------------------
地址=77DA7ABB advapi32.RegQueryValueExA
模块=advapi32
激活=始终
反汇编=mov edi,edi
------------------------------------------
好厉害啊 算法都知道了 很详细啊,哪位大神把算法源码写出来就好了。。 好东西,不过我一般都只喜欢爆的。。。。 不错 支持 期待下期教程{:301_999:} 顶楼主 大神牛牛,很详细! 偶很想好好学习爆破,算法分析很难懂,,爆破很多地方也不是很懂 虽然没看懂 但是~~~~~~ 看看学习了, 不错,,先学习了啊啊 啊啊