ufony破解记录
kongfoo/2004.6.6
由于要将2首WMA转成MP3,找到了这个软件。不注册只能转换60秒的音乐,
哪有这样做限制的?气愤中。。。
PEiD查壳tElock 0.98b1,这个壳不错啊。想一下搞音频转换算法是少不了
的,这个软件好像不易对付呢。。。
目的在于搞掂限制,尽快脱壳。
直接查OEP:4135e4。LordPE dump full,ImpREC有一堆函数无效,用tElock 98
/tElock插件都不行。trace level2找到了几个。trace level3又找到几个。最后
剩6个,OD attach上去分析一下。
第1个3e0011:
代码:
003E0011 B8 8DC44300 MOV EAX,43C48D 003E0016 90 NOP 003E0017 FF30 PUSH DWORD PTR DS:[EAX] 003E0019 C3 RETN
43c48d处是0,哪么这个项可以cut掉了。跟着的3个和3e0011的代码一样,都
cut掉。剩下2个指向程序本身空间,不管。fix dump。脱出来可以运行。
OD载入脱壳后的程序,倒,程序自带的DLL都上了壳。。。
注册窗口点确定后什么反应都没有,果然没有估计错误。由于DLL的壳(都是
tElock)没脱去,直接在OD运行很烦,所以用attach的办法。下断GetWindowTextA。
没断到,一狠心,把hlclass的函数全断了。光下断就用了近10分钟:(
这一招可谓必杀:)点确定后断下:
代码:
0040BE31 FF15 BCE24300 CALL DWORD PTR DS:[<&hlclass.??0CRegistr>; hlclass.??0CRegistry@@QAE@XZ ==这里断下 0040BE37 8D4C24 44 LEA ECX,DWORD PTR SS:[ESP+44] 0040BE3B C64424 64 02 MOV BYTE PTR SS:[ESP+64],2 0040BE40 FF15 2CE14300 CALL DWORD PTR DS:[<&hlclass.??0CString@>; hlclass.??0CString@@QAE@XZ 0040BE46 8D4C24 4C LEA ECX,DWORD PTR SS:[ESP+4C] 0040BE4A C64424 64 03 MOV BYTE PTR SS:[ESP+64],3 0040BE4F FF15 B8E24300 CALL DWORD PTR DS:[<&hlclass.??0CMenu@@Q>; hlclass.??0CMenu@@QAE@XZ 0040BE55 8B3D F0E04300 MOV EDI,DWORD PTR DS:[<&hlclass.?IsEmpty>; hlclass.?IsEmpty@CString@@QAEHXZ 0040BE5B 8D4C24 20 LEA ECX,DWORD PTR SS:[ESP+20] 0040BE5F C64424 64 04 MOV BYTE PTR SS:[ESP+64],4 0040BE64 FFD7 CALL EDI 0040BE66 85C0 TEST EAX,EAX 0040BE68 0F85 9F000000 JNZ dumped_.0040BF0D 0040BE6E 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+18] 0040BE72 FFD7 CALL EDI 0040BE74 85C0 TEST EAX,EAX 0040BE76 0F85 91000000 JNZ dumped_.0040BF0D 0040BE7C 8B3D C4E04300 MOV EDI,DWORD PTR DS:[<&hlclass.??0CStri>; hlclass.??0CString@@QAE@PAD@Z 0040BE82 83EC 08 SUB ESP,8 0040BE85 8BCC MOV ECX,ESP 0040BE87 896424 18 MOV DWORD PTR SS:[ESP+18],ESP 0040BE8B 68 34EB4100 PUSH dumped_.0041EB34 ; ASCII "Software\Ufony\Registration" 0040BE90 FFD7 CALL EDI 0040BE92 68 01000080 PUSH 80000001 0040BE97 8D4C24 34 LEA ECX,DWORD PTR SS:[ESP+34] 0040BE9B FF15 4CE44300 CALL DWORD PTR DS:[<&hlclass.?CreateKey@>; hlclass.?CreateKey@CRegistry@@QAEJPAUHKEY__@@VCString@@@Z 0040BEA1 8B2D B8E34300 MOV EBP,DWORD PTR DS:[<&hlclass.??0CStri>; hlclass.??0CString@@QAE@AAV0@@Z 0040BEA7 83EC 08 SUB ESP,8 0040BEAA 8D5424 28 LEA EDX,DWORD PTR SS:[ESP+28] 0040BEAE 8BCC MOV ECX,ESP 0040BEB0 896424 18 MOV DWORD PTR SS:[ESP+18],ESP 0040BEB4 52 PUSH EDX 0040BEB5 FFD5 CALL EBP 0040BEB7 83EC 08 SUB ESP,8 0040BEBA 8BCC MOV ECX,ESP 0040BEBC 896424 24 MOV DWORD PTR SS:[ESP+24],ESP 0040BEC0 68 28EB4100 PUSH dumped_.0041EB28 ; ASCII "UserName" 0040BEC5 C64424 78 05 MOV BYTE PTR SS:[ESP+78],5 0040BECA FFD7 CALL EDI 0040BECC 8B1D 48E44300 MOV EBX,DWORD PTR DS:[<&hlclass.?SetValu>; hlclass.?SetValue@CRegistry@@QAEJVCString@@0@Z 0040BED2 8D4C24 38 LEA ECX,DWORD PTR SS:[ESP+38] 0040BED6 C64424 74 04 MOV BYTE PTR SS:[ESP+74],4 0040BEDB FFD3 CALL EBX 0040BEDD 83EC 08 SUB ESP,8 0040BEE0 8D4424 20 LEA EAX,DWORD PTR SS:[ESP+20] 0040BEE4 8BCC MOV ECX,ESP 0040BEE6 896424 1C MOV DWORD PTR SS:[ESP+1C],ESP 0040BEEA 50 PUSH EAX 0040BEEB FFD5 CALL EBP 0040BEED 83EC 08 SUB ESP,8 0040BEF0 8BCC MOV ECX,ESP 0040BEF2 896424 20 MOV DWORD PTR SS:[ESP+20],ESP 0040BEF6 68 20EB4100 PUSH dumped_.0041EB20 ; ASCII "RegCode" 0040BEFB C64424 78 06 MOV BYTE PTR SS:[ESP+78],6 0040BF00 FFD7 CALL EDI 0040BF02 8D4C24 38 LEA ECX,DWORD PTR SS:[ESP+38] 0040BF06 C64424 74 04 MOV BYTE PTR SS:[ESP+74],4 0040BF0B FFD3 CALL EBX 0040BF0D 8B4C24 70 MOV ECX,DWORD PTR SS:[ESP+70] 0040BF11 8B5424 6C MOV EDX,DWORD PTR SS:[ESP+6C] 0040BF15 51 PUSH ECX 0040BF16 52 PUSH EDX 0040BF17 8BCE MOV ECX,ESI 0040BF19 FF15 20E44300 CALL DWORD PTR DS:[<&hlclass.?OnCancelCl>; hlclass.?OnOKClick@CDialog@@QAEJIJ@Z 0040BF1F 8D4C24 4C LEA ECX,DWORD PTR SS:[ESP+4C] 0040BF23 C64424 64 08 MOV BYTE PTR SS:[ESP+64],8 0040BF28 FF15 98E24300 CALL DWORD PTR DS:[<&hlclass.??1CMenu@@U>; hlclass.??1CMenu@@UAE@XZ 0040BF2E 8B35 9CE04300 MOV ESI,DWORD PTR DS:[<&hlclass.??1CStri>; hlclass.??1CString@@QAE@XZ 0040BF34 8D4C24 44 LEA ECX,DWORD PTR SS:[ESP+44] 0040BF38 C64424 64 07 MOV BYTE PTR SS:[ESP+64],7 0040BF3D FFD6 CALL ESI 0040BF3F 8D4C24 28 LEA ECX,DWORD PTR SS:[ESP+28] 0040BF43 C64424 64 01 MOV BYTE PTR SS:[ESP+64],1 0040BF48 FF15 94E24300 CALL DWORD PTR DS:[<&hlclass.??1CRegistr>; hlclass.??1CRegistry@@QAE@XZ 0040BF4E 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+18] 0040BF52 C64424 64 00 MOV BYTE PTR SS:[ESP+64],0 0040BF57 FFD6 CALL ESI 0040BF59 8D4C24 20 LEA ECX,DWORD PTR SS:[ESP+20] 0040BF5D C74424 64 FFFFF>MOV DWORD PTR SS:[ESP+64],-1 0040BF65 FFD6 CALL ESI 0040BF67 8B4C24 5C MOV ECX,DWORD PTR SS:[ESP+5C] 0040BF6B 5F POP EDI 0040BF6C 5E POP ESI 0040BF6D 5D POP EBP 0040BF6E 33C0 XOR EAX,EAX 0040BF70 64:890D 0000000>MOV DWORD PTR FS:[0],ECX 0040BF77 5B POP EBX 0040BF78 83C4 58 ADD ESP,58 0040BF7B C2 0800 RETN 8
只是将用户名和sn直接放到注册表。。。在调用转换窗口时会弹出限制信息窗口,
应该会判断是否注册,下断hlclass所有注册表操作函数。断下:
代码:
0040A612 FF15 BCE24300 CALL DWORD PTR DS:[<&hlclass.??0CRegistr>; hlclass.??0CRegistry@@QAE@XZ 0040A64E E8 CD660000 CALL dumped_.00410D20 0040A653 85C0 TEST EAX,EAX 0040A655 /74 41 JZ SHORT dumped_.0040A698 ==令这个跳不跳就可以跳过限制信息窗口,但只能转换1分钟的限制还在。
很明显410d20就是判断是否注册的函数了。
代码:
00410E26 8B4C24 18 MOV ECX,DWORD PTR SS:[ESP+18] 00410E2A 6A 01 PUSH 1 00410E2C 51 PUSH ECX ==sn 00410E2D 8D5424 18 LEA EDX,DWORD PTR SS:[ESP+18] 00410E31 52 PUSH EDX 00410E32 8BCF MOV ECX,EDI 00410E34 E8 77F5FFFF CALL dumped_.004103B0 ==通过sn计算出key 00410420 8B8424 90000000 MOV EAX,DWORD PTR SS:[ESP+90] ==sn 00410427 50 PUSH EAX 00410428 8D4C24 38 LEA ECX,DWORD PTR SS:[ESP+38] 0041042C C68424 88000000>MOV BYTE PTR SS:[ESP+88],5 00410434 FF15 C4E04300 CALL DWORD PTR DS:[<&hlclass.??0CString@>; hlclass.??0CString@@QAE@PAD@Z ==搬字串 0041043A 8D4C24 34 LEA ECX,DWORD PTR SS:[ESP+34] ==sn 0041043E C68424 84000000>MOV BYTE PTR SS:[ESP+84],6 00410446 FF15 50E44300 CALL DWORD PTR DS:[<&hlclass.?Trim@CStri>; hlclass.?Trim@CString@@QAEXXZ ==返回了第1个字母的ASCII码 0041044C 8D4C24 34 LEA ECX,DWORD PTR SS:[ESP+34] ==sn 00410450 895C24 30 MOV DWORD PTR SS:[ESP+30],EBX 00410454 895C24 28 MOV DWORD PTR SS:[ESP+28],EBX 00410458 895C24 48 MOV DWORD PTR SS:[ESP+48],EBX 0041045C 895C24 38 MOV DWORD PTR SS:[ESP+38],EBX 00410460 FF15 F0E04300 CALL DWORD PTR DS:[<&hlclass.?IsEmpty@CS>; hlclass.?IsEmpty@CString@@QAEHXZ ==看字面是判断字串是否空 00410466 85C0 TEST EAX,EAX 00410468 74 1A JE SHORT dumped_.00410484 =空字串返回0 ecx是长度 0041049F 8B3D 5CE14300 MOV EDI,DWORD PTR DS:[<&hlclass.?GetLeng>; hlclass.?GetLength@CString@@QAEHXZ 004104A5 FFD7 CALL EDI 004104A7 83F8 10 CMP EAX,10 ==sn长度要16位以上 004104AA 7D 33 JGE SHORT dumped_.004104DF 00410E8F 8B4C24 20 MOV ECX,DWORD PTR SS:[ESP+20] 00410E93 6A 00 PUSH 0 ==可见4103b0的参数里面第3个是1的话计算sn的key,是0的话计算name的key 00410E95 51 PUSH ECX 00410E96 8D5424 40 LEA EDX,DWORD PTR SS:[ESP+40] 00410E9A B3 05 MOV BL,5 00410E9C 52 PUSH EDX 00410E9D 8BCF MOV ECX,EDI 00410E9F 885C24 54 MOV BYTE PTR SS:[ESP+54],BL 00410EA3 C74424 38 01000>MOV DWORD PTR SS:[ESP+38],1 00410EAB E8 00F5FFFF CALL dumped_.004103B0
程序通过判断2个字串是否相等来判断是否注册,在找不到爆破点的情况下可以
直接打补丁破解。
我们在410eb0(计算出2个key之后)插入代码,让2个字串相等。
410eb0:jmp 416b00
416b00:
代码:
00416B00 60 PUSHAD 00416B01 8D7424 58 LEA ESI,DWORD PTR SS:[ESP+58] 00416B05 8D7C24 38 LEA EDI,DWORD PTR SS:[ESP+38] 00416B09 8B36 MOV ESI,DWORD PTR DS:[ESI] 00416B0B 8B3F MOV EDI,DWORD PTR DS:[EDI] 00416B0D B9 20000000 MOV ECX,20 00416B12 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[> 00416B14 61 POPAD 00416B15 50 PUSH EAX 00416B16 8D4424 34 LEA EAX,DWORD PTR SS:[ESP+34] 00416B1A ^ E9 96A3FFFF JMP dumped_.00410EB5
60 8D 74 24 58 8D 7C 24 38 8B 36 8B 3F B9 20 00 00 00 F3 A4 61 50 8D 44 24 34 E9 96 A3 FF FF
程序在转换时会一直调用410d20判断是否注册,所以这样打补丁比较安全:)
(程序也因为这样慢一些,这样设计程序&$%$#@%^@#)
用户名:任意
序列号:16位任意数字