- UID
- 35582
注册时间2007-8-28
阅读权限20
最后登录1970-1-1
以武会友
该用户从未签到
|
目标软件:OJOsoft系列
语言:VC
工具:OD
软件是VC写的,用PEID显示为:Microsoft Visual C++ 7.0 Method2 [调试]
二话不说,直接到OD载入,然后输入假的激活码,很快就能找到关键点:
- 00401D6D . C74424 1C 00000>mov dword ptr ss:[esp+1C],0
- 00401D75 . E8 96E80100 call <jmp.&MFC71.#3761>
- 00401D7A . 51 push ecx
- 00401D7B . 8D5424 08 lea edx,dword ptr ss:[esp+8]
- 00401D7F . 8BCC mov ecx,esp
- 00401D81 . 896424 10 mov dword ptr ss:[esp+10],esp
- 00401D85 . 52 push edx
- 00401D86 . FF15 E4514200 call dword ptr ds:[<&MFC71.#297>] ; MFC71.7C14E575
- 00401D8C . 8B8E C8000000 mov ecx,dword ptr ds:[esi+C8]
- 00401D92 . FF15 30504200 call dword ptr ds:[<&Control.AVProxy::Reg>; Control.AVProxy::RegisteProduct
复制代码 [separator]
显然是通过专用的DLL来验证注册的。
跟进后,来到这里:
- 003A6C49 C64424 4C 01 mov byte ptr ss:[esp+4C],1
- 003A6C4E FF15 94803B00 call dword ptr ds:[<&MFC71.#297>] ; MFC71.7C14E575
- 003A6C54 8D4C24 0C lea ecx,dword ptr ss:[esp+C]
- 003A6C58 E8 03DB0000 call Control.003B4760 //这里同样为关键CALL,跟进继续分析
- 003A6C5D 8BF0 mov esi,eax
- 003A6C5F 85F6 test esi,esi
- 003A6C61 75 76 jnz short Control.003A6CD9
- 003A6C63 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
复制代码 继续跟进
- 003B485D 8BCE mov ecx,esi
- 003B485F 885C24 3C mov byte ptr ss:[esp+3C],bl
- 003B4863 E8 38F5FFFF call Control.003B3DA0
- 003B4868 0FB6C0 movzx eax,al
- 003B486B 85C0 test eax,eax
- 003B486D 74 69 je short Control.003B48D8
复制代码 继续跟进
- 003B3DE7 8BCE mov ecx,esi
- 003B3DE9 E8 12FAFFFF call Control.003B3800
- 003B3DEE 84C0 test al,al
- 003B3DF0 0F84 49010000 je Control.003B3F3F
复制代码 跟进CALL后,发现这里是对激活码的格式的一段验证:
- 003B3837 2BC2 sub eax,edx
- 003B3839 83F8 18 cmp eax,18 //比较激活码的长度是否为0x18,不是则失败
- …………………………
- 003B3850 > 56 push esi
- 003B3851 . |8D4C24 20 lea ecx,dword ptr ss:[esp+20]
- 003B3855 . |FF15 20813B00 call dword ptr ds:[<&MFC71.#865>] ; MFC71.7C1894E7
- 003B385B . |0FBEC0 movsx eax,al
- 003B385E . |50 push eax
- 003B385F . |FFD3 call ebx
- 003B3861 . |83C4 04 add esp,4
- 003B3864 . |83FF 04 cmp edi,4
- 003B3867 . |75 08 jnz short Control.003B3871
- 003B3869 . |3C 2D cmp al,2D
- 003B386B . |75 33 jnz short Control.003B38A0
- 003B386D . |33FF xor edi,edi
- 003B386F . |EB 09 jmp short Control.003B387A
- 003B3871 > |3C 41 cmp al,41
- 003B3873 . |7C 2B jl short Control.003B38A0
- 003B3875 . |3C 5A cmp al,5A
- 003B3877 . |7F 27 jg short Control.003B38A0
- 003B3879 . |47 inc edi
- 003B387A > |46 inc esi
- 003B387B . |83FE 18 cmp esi,18
- 003B387E .^\7C D0 jl short Control.003B3850
复制代码 难过上面一段,我们知道了激活的格式应该为:XXXX-XXXX-XXXX-XXXX-XXXX
而且应该是全为字母,不能为数字!
好了,我们重新输入来过,路跳过上面的分析,来到:
- 003B3960 |> /8D4424 14 /lea eax,dword ptr ss:[esp+14]
- 003B3964 |. |33ED |xor ebp,ebp
- 003B3966 |. |8D50 01 |lea edx,dword ptr ds:[eax+1]
- 003B3969 |. |8DA424 00000000 |lea esp,dword ptr ss:[esp]
- 003B3970 |> |8A08 |/mov cl,byte ptr ds:[eax]
- 003B3972 |. |40 ||inc eax
- 003B3973 |. |84C9 ||test cl,cl
- 003B3975 |.^|75 F9 |\jnz short Control.003B3970
- 003B3977 |. |2BC2 |sub eax,edx ; 取软件名长度-EBX
- 003B3979 |. |8BF8 |mov edi,eax
- 003B397B |. |33C9 |xor ecx,ecx
- 003B397D |. |85FF |test edi,edi
- 003B397F |. |7E 18 |jle short Control.003B3999
- 003B3981 |> |0FBE740C 14 |/movsx esi,byte ptr ss:[esp+ecx+1>
- 003B3986 |. |8BC3 ||mov eax,ebx
- 003B3988 |. |0FAFC6 ||imul eax,esi
- 003B398B |. |99 ||cdq
- 003B398C |. |2BC2 ||sub eax,edx
- 003B398E |. |D1F8 ||sar eax,1
- 003B3990 |. |03C6 ||add eax,esi
- 003B3992 |. |03E8 ||add ebp,eax
- 003B3994 |. |41 ||inc ecx
- 003B3995 |. |3BCF ||cmp ecx,edi
- 003B3997 |.^|7C E8 |\jl short Control.003B3981
- 003B3999 |> |8BC5 |mov eax,ebp
- 003B399B |. |99 |cdq
- 003B399C |. |B9 1A000000 |mov ecx,1A
- 003B39A1 |. |F7F9 |idiv ecx
- 003B39A3 |. |8B4424 10 |mov eax,dword ptr ss:[esp+10] ; 除以常量0x1A
- 003B39A7 |. |83C3 06 |add ebx,6 ; EB+=6
- 003B39AA |. |83C0 04 |add eax,4
- 003B39AD |. |83FB 19 |cmp ebx,19 ; 与0x19比较,大于则结束循环
- 003B39B0 |. |894424 10 |mov dword ptr ss:[esp+10],eax
- 003B39B4 |. |8950 FC |mov dword ptr ds:[eax-4],edx ; 将上面的相除所得余数保存到下来
- 003B39B7 |.^\7C A7 \jl short Control.003B3960
复制代码 这段代码很重要,主要是针对程序名进行处理,得到4个整数,保存下来后,将参与注册验证!
这里将之记为modNum[4],代码的流程用C++转述如下(注:name记为软件名):
- int modNum[4]={0};
- int k=0;
- for(int i=1;i<0x19;i+=6){
- int len=strlen(name);
- int sum=0;
- for(int j=0;j<len;j++){
- int tmpSum=name[j]*i;
- tmpSum=(tmpSum>>1);
- sum=sum+tmpSum+name[j];
- }
- modNum[k]=sum % 0x1A;
- k++;
- }
复制代码 好了,我们继续单步,来到这里:
- 003B3E02 |> /83FF 04 /cmp edi,4
- 003B3E05 |. |75 04 |jnz short Control.003B3E0B
- 003B3E07 |. |33FF |xor edi,edi
- 003B3E09 |. |EB 23 |jmp short Control.003B3E2E
- 003B3E0B |> |53 |push ebx
- 003B3E0C |. |8D8C24 E0000000 |lea ecx,dword ptr ss:[esp+E0]
- 003B3E13 |. |FF15 20813B00 |call dword ptr ds:[<&MFC71.#865>] ; MFC71.7C1894E7
- 003B3E19 |. |0FBEC8 |movsx ecx,al
- 003B3E1C |. |51 |push ecx
- 003B3E1D |. |FFD5 |call ebp
- 003B3E1F |. |0FBED0 |movsx edx,al
- 003B3E22 |. |83EA 41 |sub edx,41
- 003B3E25 |. |83C4 04 |add esp,4
- 003B3E28 |. |8916 |mov dword ptr ds:[esi],edx
- 003B3E2A |. |47 |inc edi
- 003B3E2B |. |83C6 04 |add esi,4
- 003B3E2E |> |43 |inc ebx
- 003B3E2F |. |83FB 18 |cmp ebx,18
- 003B3E32 |.^\7C CE \jl short Control.003B3E02
复制代码 上面是对用户输入的假码进行处理,处理的方式是对激活码按位送去0x41(跳过"-")!
然后我们就来到了关键的比较点了:
- 003B3F01 |> /8B6C0C 18 /mov ebp,dword ptr ss:[esp+ecx+18] ; 按位取第1组
- 003B3F05 |. |8B840C B8000000 |mov eax,dword ptr ss:[esp+ecx+B8] ; 按位取上面所得余数
- 003B3F0C |. |8B7C0C 28 |mov edi,dword ptr ss:[esp+ecx+28] ; 按位取第2组
- 003B3F10 |. |8B740C 48 |mov esi,dword ptr ss:[esp+ecx+48] ; 按位取第4组
- 003B3F14 |. |8B540C 38 |mov edx,dword ptr ss:[esp+ecx+38] ; 按位取第3组
- 003B3F18 |. |03C5 |add eax,ebp
- 003B3F1A |. |03C7 |add eax,edi
- 003B3F1C |. |03C6 |add eax,esi
- 003B3F1E |. |03C2 |add eax,edx
- 003B3F20 |. |99 |cdq
- 003B3F21 |. |BE 1A000000 |mov esi,1A
- 003B3F26 |. |F7FE |idiv esi
- 003B3F28 |. |3B940C A8000000 |cmp edx,dword ptr ss:[esp+ecx+A8] ; 按位与第5组相比
- 003B3F2F |. |89540C 58 |mov dword ptr ss:[esp+ecx+58],edx
- 003B3F33 |. |75 0A |jnz short Control.003B3F3F
- 003B3F35 |. |83C1 04 |add ecx,4
- 003B3F38 |. |83F9 10 |cmp ecx,10
- 003B3F3B |.^\7C C4 \jl short Control.003B3F01
- 003B3F3D |. EB 02 jmp short Control.003B3F41
- 003B3F3F |> 32DB xor bl,bl
- 003B3F41 |> 8D8C24 D8000000 lea ecx,dword ptr ss:[esp+D8]
复制代码 分析好了,我们开始写KeyGen了,完整的代码如下:
- #include<stdio.h>
- #include<time.h>
- #include<iOStream>
- using namespace std;
- int main()
- {
- char name[32]={0};
- cout<<"Please Enter SoftName:()\n";
- cin.getline(name,31);
- //cout<<name<<endl;
-
- int modNum[4]={0};
- int k=0;
- for(int i=1;i<0x19;i+=6){
- int len=strlen(name);
- int sum=0;
- for(int j=0;j<len;j++){
- int tmpSum=name[j]*i;
- tmpSum=(tmpSum>>1);
- sum=sum+tmpSum+name[j];
- }
- modNum[k]=sum % 0x1A;
- k++;
- }
-
- srand(time(NULL));
- char code[32]={0};
- for(int i=0;i<4;i++){
- int n1,n2,n3,n4,n5;
- while(1){
- n1=((double)rand()/(double)RAND_MAX)*0x19+0;
- n2=((double)rand()/(double)RAND_MAX)*0x19+0;
- n3=((double)rand()/(double)RAND_MAX)*0x19+0;
- n4=((double)rand()/(double)RAND_MAX)*0x19+0;
- n5=((double)rand()/(double)RAND_MAX)*0x19+0;
- int tmp=n1+n2+n3+n4+modNum[i];
- if((tmp %0x1A)==n5)
- break;
- }
-
- code[i]=0x41+n1;
- code[i+5]=0x41+n2;
- code[i+5*2]=0x41+n3;
- code[i+5*3]=0x41+n4;
- code[i+5*4]=0x41+n5;
- }
- code[4]='-';
- code[9]='-';
- code[14]='-';
- code[19]='-';
- cout<<"Your RegCode is: ";
- cout<<code<<endl;;
-
- cout<<"Please Enter a Key to Exit…………\n";
- getchar();
- getchar();
-
- return 0;
- }
复制代码
[ 本帖最后由 iawen 于 2009-1-20 23:44 编辑 ] |
|