004027A0 SUB ESP,0C 004027A3 PUSH ESI 004027A4 PUSH 0C 004027A6 CALL superdic.004319E7 004027AB PUSH 0A 004027AD MOV ESI,EAX 004027AF CALL superdic.004319E7 004027B4 ADD ESP,8 004027B7 LEA ECX,DWORD PTR SS:[ESP+C] 004027BB LEA EDX,DWORD PTR SS:[ESP+4] 004027BF PUSH 0A ; /pFileSystemNameSize = 0000000A 004027C1 PUSH EAX ; |pFileSystemNameBuffer 004027C2 LEA EAX,DWORD PTR SS:[ESP+10] ; | 004027C6 PUSH EAX ; |pFileSystemFlags 004027C7 PUSH ECX ; |pMaxFilenameLength 004027C8 PUSH EDX ; |pVolumeSerialNumber 004027C9 PUSH 0C ; |MaxVolumeNameSize = C (12.) 004027CB PUSH ESI ; |VolumeNameBuffer 004027CC PUSH superdic.00446148 ; |RootPathName = "c:\" 004027D1 CALL DWORD PTR DS:[<&KERNEL32.GetVolumeI>; \GetVolumeInformationA 004027D7 MOV EAX,DWORD PTR SS:[ESP+4] 004027DB MOV ESI,DWORD PTR SS:[ESP+14] 004027DF PUSH EAX 004027E0 PUSH superdic.00446144 ; ASCII "%x" 004027E5 PUSH ESI 004027E6 CALL <superdic._sprintf> 这段代码大概是使用 GetVolumeInformationA 函数再加上其他一系列操作生成申请号 的过程,因为是逆注册算法,这一块我们不关心,可以直接 f8 过去看结果即可,而事实上 也确实生成一个子串是 24578843,与图 19 中的申请号相一致。 我接着往下走,前面不关键的地方就不跟了,一直走到这里: /*403D48*/ LEA EAX,DWORD PTR DS:[EBX+6FC] /*403D4E*/ PUSH ECX /*403D4F*/ PUSH EAX /*403D50*/ CALL superdic.004034E0 可以看到把申请号压入了堆栈,而函数 CALL superdic.004034E0 经判断是对申请号做了一 次加密过程。从堆栈处看到加密后密文是: 0012EF6C 0012EFA0 ASCII "BqwITTcm8kG5lcEk" 接着再 f8 配合 f7 来慢慢走。 /*403D5B*/ PUSH ESI /*403D5C*/ CALL superdic.00403630 403d5b 的位置是把注册码压入堆栈,随即利用 CALL superdic.00403630 做了一次加密过程。 过了这个 call 后把我预设的 123456789 加密成了 l6345q789.看下面堆栈数据。 0012EF64 0012FCA0 ASCII "l6345q789" 随后又经过一些对算法无用的代码后来到这里: /*403EBD*/ MOV DL,BYTE PTR DS:[ESI] /*403EBF*/ MOV CL,BYTE PTR DS:[EDI] /*403EC1*/ MOV AL,DL /*403EC3*/ CMP DL,CL /*403EC5*/ JNZ SHORT superdic.00403EE5 /*403EC7*/ TEST AL,AL /*403EC9*/ JE SHORT superdic.00403EE1 /*403ECB*/ MOV CL,BYTE PTR DS:[ESI+1] /*403ECE*/ MOV DL,BYTE PTR DS:[EDI+1] /*403ED1*/ MOV AL,CL |