• 标 题:Actual checker v1.0 之完全pj
  • 作 者:三脚猫  
  • 时 间:2002/02/16
  • 链 接:http://bbs.pediy.com

Actual checker v1.0 之完全pj

软件简介:这是一个俄国棋类游戏,由atlant software公司出品。
工具:w32dasm ,trw2000,
:pj人:三脚猫(trilegcat)
一:用wdasm查找,发现敏感字串,“register.key”。双击找到以下代码。
0047D3F9 40                      inc eax
:0047D3FA 83F81E                  cmp eax, 0000001E                    *****
:0047D3FD 7CB4                    jl 0047D3B3

* Possible StringData Ref from Code Obj ->"Register.key"
                                 |
:0047D3FF BA84D54700              mov edx, 0047D584
:0047D404 B83CE44900              mov eax, 0049E43C

* Possible StringData Ref from Code Obj ->"Name "
                                 |
:0047D42A 689CD54700              push 0047D59C
:0047D42F 8D55E4                  lea edx, dword ptr [ebp-1C]
:0047D444 68ACD54700              push 0047D5AC
:

* Possible StringData Ref from Code Obj ->"cod "
                                 |
:0047D463 68C4D54700              push 0047D5C4
:0047D468 8D55E0                  lea edx, dword ptr [ebp-20]
: * Possible StringData Ref from Code Obj ->"Please restart program"
                                 |
:0047D4B3 B8D4D54700              mov eax, 0047D5D4
:0047D4B8 E81F27FEFF              call 0045FBDC
:0047D4BD 8BC6                    mov eax, esi
:0047D4BF E8B4D2FCFF              call 0044A778
                        标记的地方是关键比较,原来只要输入的注册码不小于30(1eh)位,就会将注册名与注册码写入一个文件名为register.key  的keyfile中,并提示重新启动程序以验证注册码。

二:再用wdasm查找字串:register.key,找到另一处,这里一定是程序启动时读取的代码。


* Referenced by a CALL at Addresses:
|:0047CDEA   , :0047CE0B   , :0047CE2C   , :0047CE4B   , :0047CE65  
|
:0047CCBC 55                      push ebp

:0047CCDE E8BD6EF8FF              call 00403BA0

* Possible StringData Ref from Code Obj ->"Register.key"
                                 |
:0047CCE3 BA4CCD4700              mov edx, 0047CD4C
:0047CCE8 B83CE44900              mov eax, 0049E43C
:0047CCED E8AC8CF8FF              call 0040599E
哇,共有五处地址呼叫它,一看原来都在0047D245 的 call 0047CD5C里面。进入原来是读keyfile里的name,num,cod,addr,size,这五项的值。

三:输入 name:trilegcat    fn:67895432678954326789543267895432.自动生成keyfile,按提示重启程序。用trw下bpx 0047d245,中断后用f8进入call。
* Possible StringData Ref from Code Obj ->"cod "
                                 |
:0047CE27 B8E0D04700              mov eax, 0047D0E0
:0047CE2C E88BFEFFFF              call 0047CCBC
:0047CE31 8B55EC                  mov edx, dword ptr [ebp-14]
   此处下d edx 可见到fn。下bpmw edx  r 跟踪对fn的读取。中断后可跟踪到下面。  

0047D142 A1F8E34900              mov eax, dword ptr [0049E3F8]
:0047D147 8A4418FF                 mov al, byte ptr [eax+ebx-01]
:0047D14B 3C30                        cmp al, 30                                                 | fn 的各个值必须在              
:0047D14D 0F82A9000000            jb 0047D1FC                                        |      30--------46之间
:0047D153 8B15F8E34900             mov edx, dword ptr [0049E3F8]          |    ascii字符不就是
:0047D159 3C46                           cmp al, 46                                                |  0—f之间吗?有意思
:0047D15B 0F879B000000            ja 0047D1FC
:0047D161 43                      inc ebx
:0047D162 83FB1E                  cmp ebx, 0000001E
:0047D165 7CDB                    jl 0047D142
:0047D167 BB01000000              mov ebx, 00000001

:0047D16C 8D45F8                  lea eax, dword ptr [ebp-08]
:0047D16F 8B15F8E34900            mov edx, dword ptr [0049E3F8]
:0047D175 8A541AFF                mov dl, byte ptr [edx+ebx-01]
:0047D179 885001                  mov byte ptr [eax+01], dl
:0047D17C C60001                  mov byte ptr [eax], 01
:0047D17F 8D55F8                  lea edx, dword ptr [ebp-08]
:0047D182 8D45F4                  lea eax, dword ptr [ebp-0C]
:0047D185 E87258F8FF              call 004029FC
:0047D18A 8D45F0                  lea eax, dword ptr [ebp-10]
:0047D18D 8B15F8E34900            mov edx, dword ptr [0049E3F8]
:0047D193 8A141A                  mov dl, byte ptr [edx+ebx]
:0047D196 885001                  mov byte ptr [eax+01], dl
:0047D199 C60001                  mov byte ptr [eax], 01
:0047D19C 8D55F0                  lea edx, dword ptr [ebp-10]
:0047D19F 8D45F4                  lea eax, dword ptr [ebp-0C]
:0047D1A2 B102                    mov cl, 02
:0047D1A4 E82358F8FF              call 004029CC
:0047D1A9 8D55F4                  lea edx, dword ptr [ebp-0C]
:0047D1AC 8D45FC                  lea eax, dword ptr [ebp-04]
:0047D1AF E8106CF8FF              call 00403DC4
:0047D1B4 A1ECE34900              mov eax, dword ptr [0049E3EC]
:0047D1B9 0FB64438FF              movzx eax, byte ptr [eax+edi-01]
:0047D1BE 8904B5FCE34900          mov dword ptr [4*esi+0049E3FC], eax——>循环取name,的前五位,(此处即triletriletrilet)设为Ai
:0047D1C5 8D45EC                  lea eax, dword ptr [ebp-14]
:0047D1C8 8B4DFC                  mov ecx, dword ptr [ebp-04]
:0047D1CB BA30D24700              mov edx, 0047D230
:0047D1D0 E8976CF8FF              call 00403E6C
:0047D1D5 8B45EC                  mov eax, dword ptr [ebp-14]-----两位一组取注册码字符(如:67 89  54  32  67 89 …..)设为Bi
:0047D1D8 E8ABB6F8FF              call 00408888
:0047D1DD 2904B5FCE34900          sub dword ptr [4*esi+0049E3FC], eax--将Ai-Bi所得结果设为Ci
:0047D1E4 46                              inc esi
:0047D1E5 47                                inc edi
:0047D1E6 83C302                  add ebx, 00000002
:0047D1E9 83FF05                  cmp edi, 00000005
:0047D1EC 7E05                    jle 0047D1F3
:0047D1EE BF01000000              mov edi, 00000001

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0047D1EC(C)
|
:0047D1F3 83FE10                  cmp esi, 00000010-------共循环16次。
:0047D1F6 0F8C70FFFFFF            jl 0047D16C
         同样用bpm设断来追踪对Ci的读取,将来到这里:
004998EE 8B03                    mov eax, dword ptr [ebx]---->取C1
:004998F0 03431C                  add eax, dword ptr [ebx+1C]-将C1+C8(1C/4+1=8)
:004998F3 034310                  add eax, dword ptr [ebx+10]--将C1+C8+C5(10/4+1=5)
:004998F6 83F80F                  cmp eax, 0000000F--和必须为F。
:004998F9 750F                    jne 0049990A
:004998FB B201                    mov dl, 01
:004998FD 8B86DC020000            mov eax, dword ptr [esi+000002DC]
:00499903 E8B064FAFF              call 0043FDB8
:00499908 EB0D                    jmp 00499917

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004998F9(C)
|
:0049990A 33D2                    xor edx, edx
:0049990C 8B86DC020000            mov eax, dword ptr [esi+000002DC]
:00499912 E8A164FAFF              call 0043FDB8
       以下是一个长长的相似的代码段,直到这里:
00499DF3 8B4304                  mov eax, dword ptr [ebx+04]
:00499DF6 034318                  add eax, dword ptr [ebx+18]
:00499DF9 0303                    add eax, dword ptr [ebx]
:00499DFB 83F814                  cmp eax, 00000014
:00499DFE 753E                    jne 00499E3E
:00499E00 8B0D3CCD4900            mov ecx, dword ptr [0049CD3C]
:00499E06 8B09                    mov ecx, dword ptr [ecx]
:00499E08 8D45FC                  lea eax, dword ptr [ebp-04]

* Possible StringData Ref from Code Obj ->"Registered by: "
                                 |
:00499E0B BA7C9E4900              mov edx, 00499E7C
:00499E10 E857A0F6FF              call 00403E6C
:00499E15 8B55FC                  mov edx, dword ptr [ebp-04]
:00499E18 A16CCB4900              mov eax, dword ptr [0049CB6C]
:00499E1D 8B00                    mov eax, dword ptr [eax]
:00499E1F 8B8000030000            mov eax, dword ptr [eax+00000300]
:00499E25 E86E56F9FF              call 0042F498
:00499E2A A16CCB4900              mov eax, dword ptr [0049CB6C]
:00499E2F 8B00                    mov eax, dword ptr [eax]
:00499E31 8B8000030000            mov eax, dword ptr [eax+00000300]
:00499E37 B201                    mov dl, 01
:00499E39 E84255F9FF              call 0042F380

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00499DFE(C)
|
:00499E3E 33C0                    xor eax, eax
:00499E40 5A                      pop edx

整理得必须满足以下式子:
 C1+C8+C5=F    C3+C14+C10+C11=9        C5+C13=9             C2+C7+C9=14             C4+C+C14=D C2+C7+C8=18     C9+C11=4                         C2+C9+C10=11    C2+C1+C13=F             C1+C2=B        C6+C9+C11=5     C2+C12=8                         C4+C6=3               C3+C14+C10+C11=9  C5+C6=6  C2+C5+C7=16     C4+C5+C8=E                    C12+C13=4           C1+C2+C6=C              C7+C8=10 C5+C13=9             C5+C7=17                         C1+C7+C10=12    C2+C7+C8=18             C4+C8+C6=A   C5+C6=6               C5+C13=9                         C5+C2=D              C2+C1+C7=14
     计算得:
         C1 .C2 C3 C4   C5   C6  C7  C8  C9  C10  C11  C12   C13    C14
         3      8    0   2      5      1     9     7     3      6    1       0        4          2
整理可得注册码:
                    name:     trilegcat
                     code:     716A696A60736962695F7372656A5858


四:可写key如下:(c++编译)
include <iostream.h>
void main()
{
cout<<"please input your name:\n";
char name[16];
cin>>name;
int acsname[16],i;
for(i=0;i<16;i++)
{ acsname[i]=name[i];    //取名字的ascii码
}

int code[16];
code[0]=acsname[0]-3;
code[1]=acsname[1]-8;
code[2]=acsname[2];
code[3]=acsname[3]-2;
code[4]=acsname[4]-5;
code[5]=acsname[0]-1;
code[6]=acsname[1]-9;
code[7]=acsname[2]-7;
code[8]=acsname[3]-3;
code[9]=acsname[4]-6;
code[10]=acsname[0]-1;
code[11]=acsname[1];
code[12]=acsname[2]-4;
code[13]=acsname[3]-2;
code[14]=88;
code[15]=88;              //减去Ci
int divide[16],mode[16];
for(i=0;i<16;i++)
{divide[i]=code[i]/16;
mode[i]=code[i]%16;
}
cout<<"the regcode is:";
for(i=0;i<16;i++)
{switch(mode[i])
{case(10):
cout<<divide[i]<<"A";
break;
case(11):
cout<<divide[i]<<"B";
break;
case(12):
cout<<divide[i]<<"C";
break;
case(13):
cout<<divide[i]<<"D";
break;
case(14):
cout<<divide[i]<<"E";
break;
case(15):
cout<<divide[i]<<"F";
break;
default:
cout<<divide[i]<<mode[i];
}
}                  //转化成十六进制输出
cout<<"\n";
}

              菜鸟菜文 ,   请诸位大侠多多指教,感激不 尽.。