• 标 题:OllyDbg破解CoolTabs快速攻略
  • 作 者:windcbf
  • 时 间:2003/05/26 11:29am
  • 链 接:http://bbs.pediy.com

《OllyDbg破解CoolTabs快速攻略》
偶是OllyDbg的忠实支持者,OllyDbg不用安装,静态分析、动态调试、
修改程序、编写注释.....用过的人都说好,哈哈

好了,做了一段OllyDbg的广告后(就算是对作者的支持了),开始切入我们的正题:
破解CoolTabs软件——

(1)反反跟踪
该软件用了反跟踪代码,这种反跟踪原理和“亿虎Email邮差”如出一辙:
通过判断两次时间差,如发现有两次时间差超过N秒,则报错,程序退出。
(弹出消息框"The Application security is compromised. Quiting now")

搜索程序中调用GetTickCount的地方:

参考位于CoolTabs:.text 到 KERNEL32.GetTickCount
Address    Disassembly                                        Comment
00419E91   CALL DWORD PTR DS:[<&KERNEL32.GetTickCount>]       KERNEL32.GetTickCount
00419E9C   CALL DWORD PTR DS:[<&KERNEL32.GetTickCount>]       KERNEL32.GetTickCount
0045079A   MOV EBX,DWORD PTR DS:[<&KERNEL32.GetTickCount>]    KERNEL32.GetTickCount
00450C73   CALL DWORD PTR DS:[<&KERNEL32.GetTickCount>]       KERNEL32.GetTickCount
00452671   MOV EBX,DWORD PTR DS:[<&KERNEL32.GetTickCount>]    KERNEL32.GetTickCount
004529E5   CALL DWORD PTR DS:[<&KERNEL32.GetTickCount>]       KERNEL32.GetTickCount
0047861C   JMP DWORD PTR DS:[<&KERNEL32.GetTickCount>]        KERNEL32.GetTickCount
004B7637   MOV ESI,DWORD PTR DS:[<&KERNEL32.GetTickCount>]    KERNEL32.GetTickCount
004C2957   CALL DWORD PTR DS:[<&KERNEL32.GetTickCount>]       KERNEL32.GetTickCount
004C2FD8   MOV EBP,DWORD PTR DS:[<&KERNEL32.GetTickCount>]    KERNEL32.GetTickCount

到相应的代码段去看,根据上下文可以看出004B7637处的代码就是用来Anti-Debug的:
004B7637   .  8B35 10485200 MOV ESI,DWORD PTR DS:[<&KERNEL32.GetTick>;  KERNEL32.GetTickCount
004B763D   .  75 0D         JNZ SHORT CoolTabs.004B764C
004B763F   .  FFD6          CALL ESI                                 ; [GetTickCount
004B7641   .  FF05 40DB5100 INC DWORD PTR DS:[51DB40]
004B7647   .  A3 A46F5100   MOV DWORD PTR DS:[516FA4],EAX
004B764C   >  FFD6          CALL ESI
004B764E   .  2B05 A46F5100 SUB EAX,DWORD PTR DS:[516FA4]
004B7654   .  3D 60EA0000   CMP EAX,0EA60                    ;比较时间差
004B7659   .  76 0D         JBE SHORT CoolTabs.004B7668      ;JBE 改成JMP就搞定了
注:不能直接修改exe,程序带自校验的,只需要修改OllyDbg调试窗口里面的代码就可以了,
OllyDbg真好用:)

(2)跟踪——读取注册信息
对GetDlgItemText和GetWindowText设断,输入注册信息:WinHack, 4545454545454,确定。
程序在此处停下:
004A5FAE  |.  FF15 484E5200 CALL DWORD PTR DS:[<&USER32.GetWindowTex>; \GetWindowTextW
004A5FB4  |.  8B4D 10       MOV ECX,DWORD PTR SS:[EBP+10]  
察看寄存器窗口可以看到:
ECX 01438C80 UNICODE "4545454545454"

察看01438C80内存地址:
01438C80  34 00 35 00 34 00 35 00  4.5.4.5.
01438C88  34 00 35 00 34 00 35 00  4.5.4.5.
01438C90  34 00 35 00 34 00 35 00  4.5.4.5.
01438C98  34 00 35 00 34 00        4.5.4.

*注意,这个相当有用哦,通过OllyDbg的“内存设断点”功能,我们可以迅速定位到
处理判断注册信息的关键代码(步骤:选中这段内存,右键-〉断点-〉内存访问)

(3)跟踪——处理注册信息
内存设断以后,F9运行,程序在00486D7E停下来
00486D7E  |>  66:8B07       /MOV AX,WORD PTR DS:[EDI]
00486D81  |.  50            |PUSH EAX
00486D82  |.  E8 D4EDFDFF   |CALL CoolTabs.00465B5B
00486D87  |.  85C0          |TEST EAX,EAX
00486D89  |.  59            |POP ECX
00486D8A  |.  74 04         |JE SHORT CoolTabs.00486D90
00486D8C  |.  47            |INC EDI
00486D8D  |.  47            |INC EDI
00486D8E  |.^ EB EE         \JMP SHORT CoolTabs.00486D7E
根据上下文,看起来这里并不是关键点,所以再次F9运行。

程序第二次停下来,在00463577处:
00463577  |.  66:8B0E       MOV CX,WORD PTR DS:[ESI]
0046357A  |>  0FB702        /MOVZX EAX,WORD PTR DS:[EDX]
0046357D  |.  0FB7F9        |MOVZX EDI,CX
00463580  |.  2BC7          |SUB EAX,EDI
00463582  |.  75 0E         |JNZ SHORT CoolTabs.00463592
00463584  |.  66:85C9       |TEST CX,CX
00463587  |.  74 09         |JE SHORT CoolTabs.00463592
00463589  |.  42            |INC EDX
0046358A  |.  42            |INC EDX
0046358B  |.  46            |INC ESI
0046358C  |.  46            |INC ESI
0046358D  |.  66:8B0E       |MOV CX,WORD PTR DS:[ESI]
00463590  |.^ EB E8         \JMP SHORT CoolTabs.0046357A
这时候,发现新大陆了!! 在右边的寄存器窗口我们可以看到:
EAX 0012F0EC
ECX 01438650 UNICODE "06FE525C69890F5777F5CF4DB2A918C0"
EDX 01438650 UNICODE "06FE525C69890F5777F5CF4DB2A918C0"
EBX 00000000
ESP 0012EF9C
EBP 0012F0FC
ESI 01438C80  UNICODE "4545454545454"
EDI 0012EFB0  ASCII "WinHack145BB31D6838F26251945BB9010134C2"

显然,上面那段代码是strcmp(ESI,EDX) ,大家一定猜到
"06FE525C69890F5777F5CF4DB2A918C0"就是我们想要的注册码了,而且
还可以大致猜到"WinHack145BB31D6838F26251945BB9010134C2"是计算注
册码的参数 :)
WinHack是用户名,"145BB31D6838F26251945BB9010134C2"是注册对话框上
的Authencation码。

跟踪代码很快遇到Return ,跳回到主控代码:
0044D583   .  E8 E55F0100   CALL CoolTabs.0046356D ; 比较真假注册码

(4)跟踪——注册码算法分析

注意0044D583上方的CALL代码,便可分析出
0044D4F6   .  50            PUSH EAX                        ; "WinHack145BB31D6838F26251945BB9010134C2"
0044D4F7   .  8D45 CC       LEA EAX,DWORD PTR SS:[EBP-34]
0044D4FA   .  53            PUSH EBX
0044D4FB   .  50            PUSH EAX
0044D4FC   .  E8 775EFBFF   CALL CoolTabs.00403378          ;  计算注册码,EAX->注册码的十六进制码
0044D501   .  8D45 DC       LEA EAX,DWORD PTR SS:[EBP-24]
0044D504   .  C645 FC 03    MOV BYTE PTR SS:[EBP-4],3
0044D508   .  50            PUSH EAX
0044D509   .  8D85 10FFFFFF LEA EAX,DWORD PTR SS:[EBP-F0]   ;  
0044D50F   .  50            PUSH EAX
0044D510   .  C745 DC 40000>MOV DWORD PTR SS:[EBP-24],40
0044D517   .  FF75 D0       PUSH DWORD PTR SS:[EBP-30]
0044D51A   .  FF75 CC       PUSH DWORD PTR SS:[EBP-34]      ;  
0044D51D   .  E8 235FFBFF   CALL CoolTabs.00403445          ;  十六进制转化为字符串(注册码)

跟进 0044D4FC   .  E8 775EFBFF   CALL CoolTabs.00403378 , 看到:
00455F63   >  B8 671F4D00   MOV EAX,CoolTabs.004D1F67
00455F68   .  E8 47D00000   CALL CoolTabs.00462FB4
00455F6D   .  83EC 14       SUB ESP,14
00455F70   .  53            PUSH EBX
00455F71   .  56            PUSH ESI
00455F72   .  33DB          XOR EBX,EBX
00455F74   .  57            PUSH EDI
00455F75   .  8D4D E0       LEA ECX,DWORD PTR SS:[EBP-20]
00455F78   .  895D E8       MOV DWORD PTR SS:[EBP-18],EBX
00455F7B   .  E8 D0C4FAFF   CALL CoolTabs.00402450
00455F80   .  8B75 0C       MOV ESI,DWORD PTR SS:[EBP+C]
00455F83   .  6A 01         PUSH 1
00455F85   .  8B3D B0425200 MOV EDI,DWORD PTR DS:[<&ADVAPI3>;  ADVAPI32.CryptAcquireContextA
00455F8B   .  58            POP EAX
00455F8C   .  4E            DEC ESI
00455F8D   .  53            PUSH EBX                        ;  dwFlags = 0;
00455F8E   .  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX    ;  [EBP-4] =1
00455F91   .  50            PUSH EAX                        ;  dwProvType=1
00455F92   .  F7DE          NEG ESI
00455F94   .  68 A0665000   PUSH CoolTabs.005066A0          ;  ASCII "Microsoft Base Cryptographic Provider v1.0"
00455F99   .  8D45 EC       LEA EAX,DWORD PTR SS:[EBP-14]
00455F9C   .  1BF6          SBB ESI,ESI
00455F9E   .  53            PUSH EBX                        ;  szContainer
00455F9F   .  50            PUSH EAX                        ;  hProv
00455FA0   .  895D EC       MOV DWORD PTR SS:[EBP-14],EBX
00455FA3   .  895D F0       MOV DWORD PTR SS:[EBP-10],EBX
00455FA6   .  81C6 04800000 ADD ESI,8004
00455FAC   .  FFD7          CALL EDI                        ;  <&ADVAPI32.CryptAcquireContextA>
00455FAE   .  85C0          TEST EAX,EAX
00455FB0   .  75 10         JNZ SHORT CoolTabs.00455FC2
00455FB2   .  6A 08         PUSH 8
00455FB4   .  6A 01         PUSH 1
00455FB6   .  68 A0665000   PUSH CoolTabs.005066A0          ;  ASCII "Microsoft Base Cryptographic Provider v1.0"
00455FBB   .  8D45 EC       LEA EAX,DWORD PTR SS:[EBP-14]
00455FBE   .  53            PUSH EBX
00455FBF   .  50            PUSH EAX
00455FC0   .  FFD7          CALL EDI
00455FC2   >  395D EC       CMP DWORD PTR SS:[EBP-14],EBX
00455FC5   .  0F84 90000000 JE CoolTabs.0045605B
00455FCB   .  8D45 F0       LEA EAX,DWORD PTR SS:[EBP-10]
00455FCE   .  50            PUSH EAX                        ;  &hHash
00455FCF   .  53            PUSH EBX                        ;  0
00455FD0   .  53            PUSH EBX                        ;  0
00455FD1   .  56            PUSH ESI                        ;  0x00008003
00455FD2   .  FF75 EC       PUSH DWORD PTR SS:[EBP-14]
00455FD5   .  FF15 A8425200 CALL DWORD PTR DS:[<&ADVAPI32.C>;  ADVAPI32.CryptCreateHash
00455FDB   .  85C0          TEST EAX,EAX
00455FDD   .  74 72         JE SHORT CoolTabs.00456051
00455FDF   .  8B45 10       MOV EAX,DWORD PTR SS:[EBP+10]
00455FE2   .  53            PUSH EBX                        ;  dwFlags=0
00455FE3   .  8B48 04       MOV ECX,DWORD PTR DS:[EAX+4]
00455FE6   .  8B00          MOV EAX,DWORD PTR DS:[EAX]
00455FE8   .  51            PUSH ECX                        ;  Length
00455FE9   .  50            PUSH EAX                        ;  User+Auth
00455FEA   .  FF75 F0       PUSH DWORD PTR SS:[EBP-10]
00455FED   .  FF15 98425200 CALL DWORD PTR DS:[<&ADVAPI32.C>;  ADVAPI32.CryptHashData
00455FF3   .  85C0          TEST EAX,EAX
00455FF5   .  74 51         JE SHORT CoolTabs.00456048
00455FF7   .  8B35 DC425200 MOV ESI,DWORD PTR DS:[<&ADVAPI3>;  ADVAPI32.CryptGetHashParam
00455FFD   .  8D45 0C       LEA EAX,DWORD PTR SS:[EBP+C]
00456000   .  53            PUSH EBX                        ;  0
00456001   .  50            PUSH EAX                        ;  4
00456002   .  53            PUSH EBX                        ;  0
00456003   .  6A 02         PUSH 2
00456005   .  FF75 F0       PUSH DWORD PTR SS:[EBP-10]
00456008   .  C745 0C 04000>MOV DWORD PTR SS:[EBP+C],4
0045600F   .  FFD6          CALL ESI                        ;  <&ADVAPI32.CryptGetHashParam>
00456011   .  85C0          TEST EAX,EAX
00456013   .  74 33         JE SHORT CoolTabs.00456048
00456015   .  FF75 0C       PUSH DWORD PTR SS:[EBP+C]
00456018   .  E8 C6D50300   CALL CoolTabs.004935E3
0045601D   .  8BF8          MOV EDI,EAX
0045601F   .  59            POP ECX
00456020   .  3BFB          CMP EDI,EBX
00456022   .  74 24         JE SHORT CoolTabs.00456048      ;  EDI!=0
00456024   .  8D45 0C       LEA EAX,DWORD PTR SS:[EBP+C]
00456027   .  53            PUSH EBX                        ;  dwFlag= 0
00456028   .  50            PUSH EAX                        ;  &dwDataLen
00456029   .  57            PUSH EDI                        ;  pbData
0045602A   .  6A 02         PUSH 2                          ;  dwParam =2
0045602C   .  FF75 F0       PUSH DWORD PTR SS:[EBP-10]      ;  hHash
0045602F   .  FFD6          CALL ESI                        ;  CryptGetHashParam
00456031   .  85C0          TEST EAX,EAX
00456033   .  74 0C         JE SHORT CoolTabs.00456041
00456035   .  FF75 0C       PUSH DWORD PTR SS:[EBP+C]
00456038   .  8D4D E0       LEA ECX,DWORD PTR SS:[EBP-20]
0045603B   .  57            PUSH EDI
0045603C   .  E8 CCD4FAFF   CALL CoolTabs.0040350D          ;  EAX 指向注册码abs.0
00456041   >  57            PUSH EDI
00456042   .  E8 C5D50300   CALL CoolTabs.0049360C

上面的代码是一段很典型的API点用 PUSH ,CALL ,PUSH ,CALL ,翻译成C代码为:
DWORD dwProvType = PROV_RSA_FULL;
DWORD dwFlags = 0;
HCRYPTPROV hProv=NULL; //[EBP-14]
HCRYPTHASH hHash=NULL; //[EBP-10]
char* szContainer = NULL;
char* szProvider = "Microsoft Base Cryptographic Provider v1.0";
if(!CryptAcquireContextA(&hProv,NULL,szProvider,dwProvType,dwFlags))
{
ASSERT(0);
}
ASSERT(hProv);
ALG_ID Algid = CALG_MD5;//0x8003;
if(!CryptCreateHash(hProv,Algid,0,0,&hHash))
{
ASSERT(0);
}
if(!CryptHashData(hHash,szInpuString,nLen,0))
{
ASSERT(0);
}
DWORD dwDataLen = 0x00000004;
BYTE *bData;
CryptGetHashParam(hHash,2,NULL,&dwDataLen,0);
bData = new BYTE[dwDataLen];
CryptGetHashParam(hHash,2,bData,&dwDataLen,0);

//bData里面就是注册码的十六进制数,对每个BYTE进行字符转换就变成我们
需要的注册码了;
char szText[4];
g_szSn[0] = '\0';
for(int i=0;i< (int)dwDataLen;i++)
{
sprintf(szText,"%2X",bData[i]);
szText[0] = (szText[0]==' ')?'0':szText[0];
szText[1] = (szText[0]==' ')?'0':szText[1];
strcat(g_szSn,szText);
}
printf("注册码为:%s\n",g_szSn);


(5)总结
昨晚抢了一时间空写的,时间仓促,加上本人水平比较菜,写得有点乱,希望大家能看懂。
最后还想说一句,OllyDbg真的很好用,偶最推崇它,有兴趣者欢迎交流,QQ: 85436

                                                     WinHack[CCG][OCN]
                                                     2003-5-26凌晨