• 标 题:解了,如下 (4千字)
  • 作 者:guest
  • 时 间:2000-6-2 15:17:50
  • 链 接:http://bbs.pediy.com

1、这个东西似乎用Aspack压缩的,脱壳很容易。咱不讨论这个。
2、它用MeltICE的方法来检测SoftICE,即
      CreateFileA("\\\\.\\SICE", ...)
      CreateFileA("\\\\.\\NTICE", ...)
  所以只要用bpx CreateFileA do "d *(esp+4)"设断点,等看见它欲打开SoftICE的driver时,把上面的文件名改掉糊弄它即可。用FrogsICE欺骗也行。
3、输入注册码之后它并不立即判断,而是用WritePrivateProfileStringA( )写入c:\windows\update.ini中,下次启动的时候再判断。
4、用bpx GetPrivateProfileStringA do "d *(esp+8)"设断点,然后再启动它,等看见它读NAME和SERIAL时,让它读出来,然后用BPR监视读出来的NAME和SERIAL,就会看见判断注册码的整个过程。
  它先计算NAME的累加和,然后每次用wsprintfA( )生成注册码中的两个字符,总共有12字符。

0167:0042EBD6  MOV      BL,[EAX+ESP+1C]
0167:0042EBDA  ADD      DL,BL          //求累加和
0167:0042EBDC  INC      EAX
0167:0042EBDD  CMP      EAX,ECX
0167:0042EBDF  JL        0042EBD6
0167:0042EBE1  MOV      [ESP+10],DL
......
0167:0042EC2B  MOV      ESI,[ESP+10]
0167:0042EC2F  MOV      EDI,[ESP+18]
0167:0042EC33  MOV      ECX,[ESP+14]
0167:0042EC37  LEA      EAX,[EBX+ESP+1C]
0167:0042EC3B  XOR      EDX,EDX
0167:0042EC3D  MOV      DL,[EAX+ECX]
0167:0042EC40  XOR      ECX,ECX
0167:0042EC42  MOV      CL,[EAX]
0167:0042EC44  XOR      EDX,ECX
0167:0042EC46  XOR      EDX,EDI
0167:0042EC48  XOR      EDX,ESI
0167:0042EC4A  PUSH      EDX
0167:0042EC4B  LEA      EDX,[ESP+00000120]
0167:0042EC52  PUSH      0047E198          //格式字符串 "%02x"
0167:0042EC57  PUSH      EDX
0167:0042EC58  CALL      [USER32!wsprintfA]
0167:0042EC5E  LEA      EDI,[ESP+00000128]
0167:0042EC65  OR        ECX,-01
0167:0042EC68  XOR      EAX,EAX
0167:0042EC6A  ADD      ESP,0C
0167:0042EC6D  REPNZ SCASB
0167:0042EC6F  NOT      ECX
0167:0042EC71  SUB      EDI,ECX
0167:0042EC73  MOV      ESI,EDI
0167:0042EC75  MOV      EDI,[ESP+00000224]
0167:0042EC7C  MOV      EDX,ECX
0167:0042EC7E  OR        ECX,-01
0167:0042EC81  REPNZ SCASB
0167:0042EC83  MOV      ECX,EDX
0167:0042EC85  DEC      EDI
0167:0042EC86  SHR      ECX,02
0167:0042EC89  REPZ MOVSD
0167:0042EC8B  MOV      ECX,EDX
0167:0042EC8D  AND      ECX,03
0167:0042EC90  INC      EBX
0167:0042EC91  CMP      EBX,EBP
0167:0042EC93  REPZ MOVSB
0167:0042EC95  JL        0042EC2B    //循环
   
  它还要将这12个字符中的首字符用相邻两字符交换位置的方法放到第8个字符的位置上。并将这12个字符中的前7个字符都与0x67相或。
0167:0042ECA2  OR        ESI,-01
0167:0042ECA5  LEA      EAX,[ECX+01]
0167:0042ECA8  SUB      ESI,ECX
0167:0042ECAA  MOV      DL,[EAX]
0167:0042ECAC  MOV      CL,[EAX-01]
0167:0042ECAF  OR        DL,67
0167:0042ECB2  OR        CL,67
0167:0042ECB5  MOV      [EAX-01],DL    //交换位置
0167:0042ECB8  MOV      [EAX],CL        //交换位置
0167:0042ECBA  INC      EAX
0167:0042ECBB  LEA      ECX,[EAX+ESI]
0167:0042ECBE  CMP      ECX,EBP
0167:0042ECC0  JL        0042ECAA

  再把你输入的假注册码的前7个字符也与0x67相或,然后就比较。
0167:00428862  REPNZ SCASB
0167:00428864  NOT      ECX
0167:00428866  DEC      ECX
0167:00428867  LEA      EDI,[ESP+00000164]
0167:0042886E  MOV      EDX,ECX
0167:00428870  OR        ECX,-01
0167:00428873  REPNZ SCASB
0167:00428875  NOT      ECX
0167:00428877  DEC      ECX
0167:00428878  CMP      ECX,EDX  //比较真假注册码的长度,为12
0167:0042887A  JZ        004288A6
0167:0042887C  PUSH      6C
0167:0042887E  CALL      004531B7
..............
0167:004288BA  MOV      AL,[ECX+ESP+000000E4]
0167:004288C1  MOV      DL,[ECX+ESP+00000164]
0167:004288C8  CMP      AL,DL          //比较
0167:004288CA  JNZ      004288CF
0167:004288CC  DEC      ECX
0167:004288CD  JNS      004288BA
0167:004288CF  LEA      EDI,[ESP+000000E4]
0167:004288D6  OR        ECX,-01
0167:004288D9  XOR      EAX,EAX
0167:004288DB  XOR      EDX,EDX
0167:004288DD  REPNZ SCASB
0167:004288DF  NOT      ECX
0167:004288E1  DEC      ECX
0167:004288E2  JZ        00428977
0167:004288E8  MOV      CL,[EDX+ESP+00000164]
0167:004288EF  MOV      AL,[EDX+ESP+000000E4]
0167:004288F6  CMP      CL,AL          //比较
0167:004288F8  JNZ      00428912

  也就是说,它不是直接比较注册码,而是把真假注册码都与0x67相或之后再进行比较。

Name:  Netguy/CrackingForFun
Code:  3c8d99e3dfc0

  • 标 题:key generator (1千字)
  • 作 者:guest
  • 时 间:2000-6-2 16:44:12

#include <stdio.h>
#include <string.h>

void main(void)
{
    char Buf[128];
    char Name[128];
    char Serial[13];
    int  k, len;
    char sum, repeat;
    const char home[]="www.pcchina.net";

    printf("KeyGen for Update NOW! 2.0.\n");
    printf("coded by Netguy.\n");

    printf("Input your name: ");
    gets(Name);

    strcpy(Buf, Name);

    len = strlen(Name);
    for(k = 0; k < 6; k++)
    {
        Name[k] &= 0x7F;
    }

    repeat = 6 / len;
    for (k = 0; k < repeat; k++)
    {
        strcat(Name, Buf);
    }
   
    len = strlen(Name);
    sum = 0;
    for(k = 0; k < len; k++)
    {
        sum += Name[k];
    }

    Serial[0] = '\0';
    for(k = 0; k < 6; k++)
    {
        Name[k] ^= sum;
        Name[k] ^= 0xC7;
        Name[k] ^= home[k];
        sprintf(Buf, "%02x", Name[k] & 0xFF);
        strcat(Serial, Buf);
    }

    printf("Your registration code is: ");
    for (k = 1; k <= 6; k++) putchar(Serial[k]);
    putchar(Serial[0]);
    puts(&Serial[7]);
}