程序的地址是:http://www.jcrystal.com/
程序没有加壳,用PEid查显示为:Microsoft Visual Basic 5.0 / 6.0
由于是来分析算法,所以我还用PEid的插件来分析了一下程序所用的算法是:
代码:
CRC32 [poly] :: 0013D96F :: 0053D96F The reference is above.
代码:
73502096 MSVBVM> 55 push ebp 73502097 8BEC mov ebp,esp 73502099 83EC 4C sub esp,4C 7350209C 8B4D 14 mov ecx,dword ptr ss:[ebp+14]
代码:
004B8DBD . /0F84 BD000000 je wincnt.004B8E80 004B8DC3 . |8B45 08 mov eax,dword ptr ss:[ebp+8] 004B8DC6 . |8D95 FCFEFFFF lea edx,dword ptr ss:[ebp-104] 004B8DCC . |52 push edx 004B8DCD . |8B55 E8 mov edx,dword ptr ss:[ebp-18] 004B8DD0 . |8B08 mov ecx,dword ptr ds:[eax] 004B8DD2 . |52 push edx 004B8DD3 . |50 push eax 004B8DD4 . |FF91 38090000 call dword ptr ds:[ecx+938] ; 这里就是第一个关键CALL了,F7跟进 004B8DDA . |8B45 E8 mov eax,dword ptr ss:[ebp-18] 004B8DDD . |50 push eax 004B8DDE . |FFD6 call esi ; <&MSVBVM60.__vbaLenBstr> 004B8DE0 . |33C9 xor ecx,ecx 004B8DE2 . |83F8 0D cmp eax,0D 004B8DE5 . |0F9DC1 setge cl 004B8DE8 . |33D2 xor edx,edx 004B8DEA . |66:3995 FCFEFFFF cmp word ptr ss:[ebp-104],dx 004B8DF1 . |0F95C2 setne dl 004B8DF4 . |85CA test edx,ecx 004B8DF6 . |0F85 3D010000 jnz wincnt.004B8F39 004B8DFC . |BE 04000280 mov esi,80020004 004B8E01 . |8D95 50FFFFFF lea edx,dword ptr ss:[ebp-B0] 004B8E07 . |8D4D B0 lea ecx,dword ptr ss:[ebp-50] 004B8E0A . |8975 98 mov dword ptr ss:[ebp-68],esi 004B8E0D . |895D 90 mov dword ptr ss:[ebp-70],ebx 004B8E10 . |8975 A8 mov dword ptr ss:[ebp-58],esi 004B8E13 . |895D A0 mov dword ptr ss:[ebp-60],ebx 004B8E16 . |C785 58FFFFFF 4050>mov dword ptr ss:[ebp-A8],wincnt.00415040 ; UNICODE "Registration failed!" 004B8E20 . |C785 50FFFFFF 0800>mov dword ptr ss:[ebp-B0],8 004B8E2A . |FFD7 call edi ; <&MSVBVM60.__vbaVarDup> 004B8E2C . |8D95 60FFFFFF lea edx,dword ptr ss:[ebp-A0] 004B8E32 . |8D4D C0 lea ecx,dword ptr ss:[ebp-40] 004B8E35 . |C785 68FFFFFF 2450>mov dword ptr ss:[ebp-98],wincnt.00415024 ; UNICODE "Invalid Key" 004B8E3F . |C785 60FFFFFF 0800>mov dword ptr ss:[ebp-A0],8 004B8E49 . |FFD7 call edi ; <&MSVBVM60.__vbaVarDup> 004B8E4B . |8D45 90 lea eax,dword ptr ss:[ebp-70] 004B8E4E . |8D4D A0 lea ecx,dword ptr ss:[ebp-60] 004B8E51 . |50 push eax 004B8E52 . |8D55 B0 lea edx,dword ptr ss:[ebp-50] 004B8E55 . |51 push ecx 004B8E56 . |52 push edx 004B8E57 . |8D45 C0 lea eax,dword ptr ss:[ebp-40] 004B8E5A . |6A 30 push 30 004B8E5C . |50 push eax 004B8E5D . |FF15 B8114000 call dword ptr ds:[<&MSVBVM60.#595>] ; MSVBVM60.rtcMsgBox 004B8E63 . |8D4D 90 lea ecx,dword ptr ss:[ebp-70]
代码:
004CBEC9 . 52 push edx 004CBECA . 894D C4 mov dword ptr ss:[ebp-3C],ecx 004CBECD . C745 BC 08400000 mov dword ptr ss:[ebp-44],4008 004CBED4 . FFD7 call edi ; <&MSVBVM60.__vbaLenBstr> 004CBED6 . 83E8 09 sub eax,9 ; 取用户输入的注册长度,与9比较 004CBED9 . 8D4D CC lea ecx,dword ptr ss:[ebp-34] 004CBEDC . 0F80 C5000000 jo wincnt.004CBFA7 ; 小于9则出错返回 //0012F7F8 001DAA84 UNICODE "AAA-_12345678"
代码:
004CBEE6 . 50 push eax 004CBEE7 . 51 push ecx 004CBEE8 . FF15 F8134000 call dword ptr ds:[<&MSVBVM60.#617>] ; MSVBVM60.rtcLeftCharVar 004CBEEE . 8D55 CC lea edx,dword ptr ss:[ebp-34] ; 取出左边4个字符 //0012F7E8 0021B104 UNICODE "AAA-"
代码:
004CBF14 . 52 push edx 004CBF15 . 8D55 EC lea edx,dword ptr ss:[ebp-14] 004CBF18 . 8B08 mov ecx,dword ptr ds:[eax] 004CBF1A . 52 push edx 004CBF1B . 50 push eax 004CBF1C . FF91 34090000 call dword ptr ds:[ecx+934] ; 关键CALL,F7跟进
代码:
//========================================================= 004CBBED . 52 push edx ; /Arg2 004CBBEE . 50 push eax ; |Arg1 004CBBEF . C785 5CFFFFFF A74D>mov dword ptr ss:[ebp-A4],4DA7 ; | 004CBBF9 . C785 54FFFFFF 0200>mov dword ptr ss:[ebp-AC],2 ; | 004CBC03 . FF15 E0114000 call dword ptr ds:[<&MSVBVM60.#520>] ; \将4DA7转换为10格式字符串,即:19879
代码:
004CBC3A . 8D95 44FFFFFF lea edx,dword ptr ss:[ebp-BC] 004CBC40 . 8D85 34FFFFFF lea eax,dword ptr ss:[ebp-CC] 004CBC46 . 52 push edx 004CBC47 . 50 push eax 004CBC48 . FFD7 call edi ; 将^LTB与上面得到字符串连接; <&MSVBVM60.__vbaVarCat> 004CBC4A . 50 push eax ; /得到:UNICODE "^LTB19879"
代码:
004CBD23 . 52 push edx 004CBD24 . 50 push eax 004CBD25 . 8975 E0 mov dword ptr ss:[ebp-20],esi 004CBD28 . C745 C4 08000000 mov dword ptr ss:[ebp-3C],8 ; 将主程序名转成小写 004CBD2F . FF15 44114000 call dword ptr ds:[<&MSVBVM60.#518>] ; MSVBVM60.rtcLowerCaseVar 004CBD35 . 8B4D E4 mov ecx,dword ptr ss:[ebp-1C] ; //UNICODE "wincnt" …………………… 004CBD4B . 50 push eax 004CBD4C . 51 push ecx 004CBD4D . C785 24FFFFFF 0800>mov dword ptr ss:[ebp-DC],8 004CBD57 . FFD7 call edi ; 接上上面的字符串得:"wincnt^LTB19879" 004CBD59 . 50 push eax ; /Arg1 = 0012F74C …………………… 004CBD6D . 51 push ecx 004CBD6E . 8D4D DC lea ecx,dword ptr ss:[ebp-24] 004CBD71 . 8B10 mov edx,dword ptr ds:[eax] 004CBD73 . 51 push ecx 004CBD74 . 8B4D 0C mov ecx,dword ptr ss:[ebp+C] 004CBD77 . 51 push ecx 004CBD78 . 50 push eax 004CBD79 . FF92 44090000 call dword ptr ds:[edx+944] ; 关键CALL,继续F7跟进
代码:
//======================================= 004CC8D5 . C745 C0 65F95900 mov dword ptr ss:[ebp-40],59F965 ; | 004CC8DC . C745 B8 03000000 mov dword ptr ss:[ebp-48],3 ; | 004CC8E3 . FF15 E0114000 call dword ptr ds:[<&MSVBVM60.#520>] ; \rtcTrimVar 004CC8E9 . 8B5D 0C mov ebx,dword ptr ss:[ebp+C] ; 又得一字符串:5896549 …………………… 004CC923 . 51 push ecx 004CC924 . 52 push edx 004CC925 . FFD7 call edi ; 继续连接字符串; <&MSVBVM60.__vbaVarCat> 004CC927 . 50 push eax ; 得:"5896549AAA-" 004CC928 . 8D85 54FFFFFF lea eax,dword ptr ss:[ebp-AC] 004CC92E . 8D4D 88 lea ecx,dword ptr ss:[ebp-78] 004CC931 . 50 push eax 004CC932 . 51 push ecx 004CC933 . FFD7 call edi ; <&MSVBVM60.__vbaVarCat> 004CC935 . 8BD0 mov edx,eax ; 得:"5896549AAA-wincnt^LTB19879" …………………… 004CC995 . 52 push edx 004CC996 . 50 push eax 004CC997 . 8BF8 mov edi,eax 004CC999 . FF51 28 call dword ptr ds:[ecx+28] ; 关键CALL,继续F7跟进
代码:
//=============================================================== 0053DCB1 > /8B4D E8 mov ecx,dword ptr ss:[ebp-18] 0053DCB4 . |8B45 A4 mov eax,dword ptr ss:[ebp-5C] 0053DCB7 . |3BC8 cmp ecx,eax 0053DCB9 . |0F8F B1000000 jg wincnt.0053DD70 0053DCBF . |8B55 0C mov edx,dword ptr ss:[ebp+C] 0053DCC2 . |8B02 mov eax,dword ptr ds:[edx] 0053DCC4 . |3BC7 cmp eax,edi 0053DCC6 . |74 20 je short wincnt.0053DCE8 0053DCC8 . |66:8338 01 cmp word ptr ds:[eax],1 0053DCCC . |75 1A jnz short wincnt.0053DCE8 0053DCCE . |8B50 14 mov edx,dword ptr ds:[eax+14] 0053DCD1 . |8BF9 mov edi,ecx 0053DCD3 . |8B48 10 mov ecx,dword ptr ds:[eax+10] 0053DCD6 . |2BFA sub edi,edx 0053DCD8 . |3BF9 cmp edi,ecx 0053DCDA . |72 06 jb short wincnt.0053DCE2 0053DCDC . |FF15 38124000 call dword ptr ds:[<&MSVBVM60.__vbaGenerateBou>; MSVBVM60.__vbaGenerateBoundsError 0053DCE2 > |8BC7 mov eax,edi 0053DCE4 . |33FF xor edi,edi 0053DCE6 . |EB 06 jmp short wincnt.0053DCEE 0053DCE8 > |FF15 38124000 call dword ptr ds:[<&MSVBVM60.__vbaGenerateBou>; MSVBVM60.__vbaGenerateBoundsError 0053DCEE > |8B4D 0C mov ecx,dword ptr ss:[ebp+C] 0053DCF1 . |8B11 mov edx,dword ptr ds:[ecx] 0053DCF3 . |8B4A 0C mov ecx,dword ptr ds:[edx+C] 0053DCF6 . |33D2 xor edx,edx 0053DCF8 . |8A1401 mov dl,byte ptr ds:[ecx+eax] 0053DCFB . |8BC6 mov eax,esi 0053DCFD . |8BCA mov ecx,edx 0053DCFF . |25 FF000000 and eax,0FF 0053DD04 . |33C8 xor ecx,eax 0053DD06 . |8BC6 mov eax,esi 0053DD08 . |24 00 and al,0 0053DD0A . |99 cdq 0053DD0B . |81E2 FF000000 and edx,0FF 0053DD11 . |03C2 add eax,edx 0053DD13 . |C1F8 08 sar eax,8 0053DD16 . |25 FFFFFF00 and eax,0FFFFFF 0053DD1B . |8BF0 mov esi,eax 0053DD1D . |8B43 34 mov eax,dword ptr ds:[ebx+34] 0053DD20 . |3BC7 cmp eax,edi 0053DD22 . |74 23 je short wincnt.0053DD47 0053DD24 . |66:8338 01 cmp word ptr ds:[eax],1 0053DD28 . |75 1D jnz short wincnt.0053DD47 0053DD2A . |2B48 14 sub ecx,dword ptr ds:[eax+14] 0053DD2D . |8BF9 mov edi,ecx 0053DD2F . |8B48 10 mov ecx,dword ptr ds:[eax+10] 0053DD32 . |3BF9 cmp edi,ecx 0053DD34 . |72 06 jb short wincnt.0053DD3C 0053DD36 . |FF15 38124000 call dword ptr ds:[<&MSVBVM60.__vbaGenerateBou>; MSVBVM60.__vbaGenerateBoundsError 0053DD3C > |8D04BD 00000000 lea eax,dword ptr ds:[edi*4] 0053DD43 . |33FF xor edi,edi 0053DD45 . |EB 06 jmp short wincnt.0053DD4D 0053DD47 > |FF15 38124000 call dword ptr ds:[<&MSVBVM60.__vbaGenerateBou>; MSVBVM60.__vbaGenerateBoundsError 0053DD4D > |8B4B 34 mov ecx,dword ptr ds:[ebx+34] 0053DD50 . |8B51 0C mov edx,dword ptr ds:[ecx+C] 0053DD53 . |8B0C02 mov ecx,dword ptr ds:[edx+eax] 0053DD56 . |B8 01000000 mov eax,1 0053DD5B . |33F1 xor esi,ecx 0053DD5D . |8B4D E8 mov ecx,dword ptr ss:[ebp-18] 0053DD60 . |03C1 add eax,ecx 0053DD62 . |0F80 CC000000 jo wincnt.0053DE34 0053DD68 . |8945 E8 mov dword ptr ss:[ebp-18],eax 0053DD6B .^\E9 41FFFFFF jmp wincnt.0053DCB1
对UNICODE格式的字符串"5896549AAA-wincnt^LTB19879"进行CRC32计算:
代码:
0053DD70 > \F7D6 not esi ; 对取得CRC32值取反得10进制数:"795102726" 0053DD72 . 68 B4434200 push wincnt.004243B4 ; UNICODE "00000000" 0053DD77 . 56 push esi 0053DD78 . FF15 EC104000 call dword ptr ds:[<&MSVBVM60.__vbaStrI4>] ; MSVBVM60.__vbaStrI4 0053DD7E . 8B35 08144000 mov esi,dword ptr ds:[<&MSVBVM60.__vbaStrMove>>; MSVBVM60.__vbaStrMove 0053DD84 . 8BD0 mov edx,eax 0053DD86 . 8D4D D0 lea ecx,dword ptr ss:[ebp-30] 0053DD89 . FFD6 call esi ; <&MSVBVM60.__vbaStrMove> 0053DD8B . 50 push eax 0053DD8C . FF15 58114000 call dword ptr ds:[<&MSVBVM60.__vbaStrCat>] ; 将结果与00000000相连 0053DD92 . 8945 C8 mov dword ptr ss:[ebp-38],eax ; 得:"00000000795102726" 0053DD95 . 8D45 C0 lea eax,dword ptr ss:[ebp-40] 0053DD98 . 6A 08 push 8 0053DD9A . 8D4D B0 lea ecx,dword ptr ss:[ebp-50] 0053DD9D . 50 push eax 0053DD9E . 51 push ecx 0053DD9F . C745 C0 08000000 mov dword ptr ss:[ebp-40],8 0053DDA6 . FF15 18144000 call dword ptr ds:[<&MSVBVM60.#619>] ; 取得到的字符串右8位:"95102726"
这里的结果是“AAA-_95102726”
下面是我用C++写的KeyGen:
代码:
#include<iostream> using namespace std; unsigned long Crc32Table[256]; void GetCRC32Table(){ int i,j; unsigned long Crc; for (i = 0; i < 256; i++){ Crc = i; for (j = 0; j < 8; j++){ if (Crc & 1) Crc = (Crc >> 1) ^ 0xEDB88320; else Crc >>= 1; } Crc32Table[i] = Crc; } } //获取字符串CRC32校验值 unsigned int GetCrc32(char* InStr,int len){ GetCRC32Table(); unsigned int crc=0xffffffff; for(int i=0; i<len; i++){ unsigned int tmp=InStr[i]; crc = (crc >> 8) ^ Crc32Table[(crc & 0xFF) ^ tmp]; } return crc; } int main(){ cout<<"请输入你的用户名(4位长字符):\t"; char name[5]; cin>>name; char str[64]={0}; sprintf(str,"5896549%swincnt^LTB19879",name); //下面是手工将ASCII转成UNICODE的,呵呵 char ch[128]={0}; int len=strlen(str); int j=0; for(int i=0;i<len;i++){ ch[j]=str[i]; j++; ch[j]=0; j++; } unsigned int crc32=GetCrc32(ch,j);//得到上面字符串的CRC32值 crc32 = crc32 ^ 0xFFFFFFFF; //对取得的CRC32值取反 char tmp[10]={0}; sprintf(tmp,"%d",crc32);//格式化成字符串 char regCode[32]={0}; sprintf(regCode,"%s_%s",name,&tmp[1]); //生成并打印出来 cout<<"Your RegCode Is: "<<regCode<<endl; return 0; }