• 标 题:Universe 1.63注册码生成分析及注册机原码(上) (2千字)
  • 作 者:Maomao[CCG]
  • 时 间:2001-11-12 18:34:15
  • 链 接:http://bbs.pediy.com

Universe 1.63注册码生成分析及注册机原码(上)

作者:Maomao[CCG][BCG][CNCG]

下载:
  http://www.diardsoftware.com/ (最新版本1.63)

说明: 本程序是一个专门用于制作美丽星空图的软件,可生成各种各样的星云、星空、行星、星系等,可自由调节,效果非常棒,而且没有加壳。


    用TRW载入后下getwindowtexta,运行并注册,输入用户名Maomao[CCG]与注册码87654321后OK,被中断,按F5,又被中断(第一次取用户名,第二次取注册码),下BD *, pmodule后,来到这里:
0177:00462D65  CALL    `USER32!GetWindowTextA`
0177:00462D6B  MOV      ECX,[EBP+10]  <=====光标在这里
0177:00462D6E  PUSH    BYTE -01
0177:00462D70  CALL    00456056
0177:00462D75  JMP      SHORT 00462D82

按住F10,一直来到这里:
0177:0040AC87  MOV      EDX,[EBP-0C]
0177:0040AC8A  ADD      EDX,9C
0177:0040AC90  PUSH    EDX
0177:0040AC91  MOV      ECX,00497950
0177:0040AC96  CALL    00416D8E    <=====可疑的call
0177:0040AC9B  MOV      [EBP-04],EAX
0177:0040AC9E  CMP      DWORD [EBP-04],BYTE +00
0177:0040ACA2  JZ      0040ACDC    <=====跳走就Over了
0177:0040ACA4  MOV      EAX,[EBP-0C]

在0177:0040AC96行上设断,重新注册跟进去,这个call里有这样一段程序:
0177:00416D8E  PUSH    EBP
0177:00416D8F  MOV      EBP,ESP
0177:00416D91  SUB      ESP,BYTE +08
0177:00416D94  MOV      [EBP-04],ECX
0177:00416D97  CMP      DWORD [EBP+0C],BYTE +00
0177:00416D9B  JNG      00416DA5
0177:00416D9D  MOV      EAX,[EBP+0C]
0177:00416DA0  MOV      [EBP-08],EAX
0177:00416DA3  JMP      SHORT 00416DAE
0177:00416DA5  MOV      ECX,[EBP-04]
0177:00416DA8  MOV      EDX,[ECX+10]
0177:00416DAB  MOV      [EBP-08],EDX
0177:00416DAE  MOV      EAX,[EBP+08]
0177:00416DB1  PUSH    EAX
0177:00416DB2  CALL    00416844      <=====算注册码的call
0177:00416DB7  ADD      ESP,BYTE +04
0177:00416DBA  XOR      ECX,ECX
0177:00416DBC  CMP      [EBP-08],EAX  <=====这里?EAX可以看到真正注册码"603700860"
                                      ? EBP-8是输入的注册码"87654321"
0177:00416DBF  SETZ    CL            <=====设置标志
0177:00416DC2  MOV      EAX,ECX
0177:00416DC4  MOV      ESP,EBP
0177:00416DC6  POP      EBP
0177:00416DC7  RET      08
    程序运行时,时刻检测所输注册码,直接暴破是没有用的。修改标志为1可以使用程序不弹出错误框,但无法完成注册。现在我们得到一个正确的注册码:User Name:Maomao[CCG] User Key:603700860
    如果仅满足于在0177:00416DBC处找出一个注册码,对破解水平的提高没有任何帮助。我们还是要追进算码的那个call。

(上篇完~~~)

  • 标 题:Universe 1.63注册码生成分析及注册机原码(中) (7千字)
  • 作 者:Maomao[CCG]
  • 时 间:2001-11-12 20:22:32

Universe 1.63注册码生成分析及注册机原码(中)
作者:Maomao[CCG]

我们追进算注册码的CALL,看到下面的程序段:
0177:00416844  PUSH    EBP
0177:00416845  MOV      EBP,ESP
0177:00416847  PUSH    BYTE -01
0177:00416849  PUSH    DWORD 004754B9
0177:0041684E  MOV      EAX,`DOSMGR_BackFill_Allowed`
0177:00416854  PUSH    EAX
0177:00416855  MOV      `DOSMGR_BackFill_Allowed`,ESP
0177:0041685C  SUB      ESP,BYTE +2C
0177:0041685F  PUSH    DWORD 0048DCCC
0177:00416864  LEA      EAX,[EBP-30]
0177:00416867  PUSH    EAX
0177:00416868  CALL    00416CC2
0177:0041686D  ADD      ESP,BYTE +08
0177:00416870  MOV      [EBP-34],EAX
0177:00416873  MOV      ECX,[EBP-34]
0177:00416876  MOV      [EBP-38],ECX
0177:00416879  MOV      DWORD [EBP-04],00
0177:00416880  MOV      EDX,[EBP-38]
0177:00416883  PUSH    EDX
0177:00416884  MOV      EAX,[EBP+08]
0177:00416887  PUSH    EAX
0177:00416888  CALL    00417020
0177:0041688D  MOV      [EBP-2C],AL
0177:00416890  MOV      DWORD [EBP-04],FFFFFFFF
0177:00416897  LEA      ECX,[EBP-30]
0177:0041689A  CALL    00455C64
0177:0041689F  MOV      ECX,[EBP-2C]
0177:004168A2  AND      ECX,FF
0177:004168A8  TEST    ECX,ECX
0177:004168AA  JZ      004168B3
0177:004168AC  XOR      EAX,EAX
0177:004168AE  JMP      00416997
0177:004168B3  CALL    0042A6D0
0177:004168B8  MOV      [EBP-24],EAX
0177:004168BB  MOV      DWORD [EBP-10],00
0177:004168C2  MOV      DWORD [EBP-20],01
0177:004168C9  MOV      DWORD [EBP-1C],00
0177:004168D0  JMP      SHORT 004168DB
以上是一些无太多关系的操作,主要是姓名和注册码的存取和转换,下面来到重点了:

0177:004168D2  MOV      EDX,[EBP-1C]
0177:004168D5  ADD      EDX,BYTE +01
0177:004168D8  MOV      [EBP-1C],EDX
0177:004168DB  MOV      ECX,[EBP+08]
0177:004168DE  CALL    00403460      <=====计算姓名的位数
0177:004168E3  CMP      [EBP-1C],EAX  <=====EBP-1C是指针,用于取字符
0177:004168E6  JNL      00416937
0177:004168E8  MOV      EAX,[EBP-1C]  <=====指针送入EAX
0177:004168EB  PUSH    EAX
0177:004168EC  MOV      ECX,[EBP+08]  <=====这里D *ECX 可以看到用户名"Maomao[CCG]"
0177:004168EF  CALL    00417000      <=====取指针所指字符到AL
0177:004168F4  MOVSX    ECX,AL        <=====送入ECX
0177:004168F7  MOV      [EBP-28],ECX  <=====临时寄存这个字符(下面还要用到)
0177:004168FA  MOV      EDX,[EBP-10]  <=====取累加器中的数据(EBP-10为累加器)
0177:004168FD  ADD      EDX,[EBP-28]  <=====相加
0177:00416900  MOV      [EBP-10],EDX  <=====结果送入累加器,下一次再使用
0177:00416903  MOV      EAX,[EBP-1C]  <=====取指针到EAX
0177:00416906  AND      EAX,80000001  <=====与0x80000001 AND
                                        (当指针为奇数时结果为0,偶数数结果为1)
0177:0041690B  JNS      00416912
0177:0041690D  DEC      EAX
0177:0041690E  OR      EAX,BYTE -02
0177:00416911  INC      EAX
0177:00416912  TEST    EAX,EAX        <=====判断奇偶
0177:00416914  JZ      0041691F
0177:00416916  MOV      DWORD [EBP-20],FFFFFFFF <=====偶位时送符号位-1
0177:0041691D  JMP      SHORT 00416926
0177:0041691F  MOV      DWORD [EBP-20],01      <=====奇位时送符号位1
0177:00416926  MOV      ECX,[EBP-20]            <=====取符号位
0177:00416929  IMUL    ECX,[EBP-28]            <=====取临时寄存的字符与符号相乘(偶数位结果为负)
0177:0041692D  MOV      EDX,[EBP-10]            <=====取累加器中的值
0177:00416930  ADD      EDX,ECX                <=====再相加(如果是偶数位就是相减了)
0177:00416932  MOV      [EBP-10],EDX            <=====送入累加器
0177:00416935  JMP      SHORT 004168D2          <=====取下一字符
    上面这段程序完成奇位字符相加两次,偶位字符一加一减(等于不运算)。结果为所有奇位字符和的二倍。
紧接着:
0177:00416937  MOV      EAX,[EBP-10]      <=====取累加器中的值
0177:0041693A  MOV      [EBP-18],EAX      <=====送入[EBP-18]
0177:0041693D  MOV      ECX,[EBP-10]      <=====取累加器中的值到ECX
0177:00416940  IMUL    ECX,[EBP-10]      <=====相乘(相当于求平方)
0177:00416944  MOV      [EBP-10],ECX      <=====结果送入累加器
0177:00416947  MOV      EDX,[EBP-10]      <=====取累加器中的值
0177:0041694A  ADD      EDX,[EBP-18]      <=====与刚才保存的[EBP-18]相加
0177:0041694D  MOV      [EBP-10],EDX      <=====结果送入累加器
0177:00416950  MOV      EAX,[EBP-10]      <=====累加器送入EAX
0177:00416953  PUSH    EAX
0177:00416954  CALL    0042A6C0          <=====保存中间值到[0048E7E8],此call略
0177:00416959  ADD      ESP,BYTE +04     

  以上程序完成求形如(X*X+X)的结果,其中X为第一段累加运算的结果。接下来:

0177:0041695C  MOV      DWORD [EBP-1C],00 <=====指针清0
0177:00416963  JMP      SHORT 0041696E
0177:00416965  MOV      ECX,[EBP-1C]
0177:00416968  ADD      ECX,BYTE +01      <=====指针加1
0177:0041696B  MOV      [EBP-1C],ECX
0177:0041696E  MOV      EDX,[EBP-1C]     
0177:00416971  CMP      EDX,[00497808]  <=====[00497808]为循环计数器,值为3
0177:00416977  JNL      00416980     <=====大于或等于时结束运算 
0177:00416979  CALL    0042A6E0     <=====运算的call 
0177:0041697E  JMP      SHORT 00416965
0177:00416980  CALL    0042A6E0     <=====再运算一次 
0177:00416985  MOV      [EBP-14],EAX      <=====保存结果
0177:00416988  MOV      EAX,[EBP-24]
0177:0041698B  PUSH    EAX
0177:0041698C  CALL    0042A6C0
0177:00416991  ADD      ESP,BYTE +04
0177:00416994  MOV      EAX,[EBP-14]   <=====取回结果
0177:00416997  MOV      ECX,[EBP-0C]
0177:0041699A  MOV      `DOSMGR_BackFill_Allowed`,ECX
0177:004169A1  MOV      ESP,EBP
0177:004169A3  POP      EBP
0177:004169A4  RET   
  以上这段完成四次循环运算,结果保存在EAX中。看来还要跟进0177:00416980的CALL 0042A6E0。
跟进后,是这样的程序段:
0177:0042A6E0  MOV      EAX,[0048E7E8]  <=====取加保存的中间结果
0177:0042A6E5  PUSH    DWORD 78B30C40  <=====放一个辅助运算数0x78B30C40
0177:0042A6EA  CDQ   
0177:0042A6EB  PUSH    BYTE +00
0177:0042A6ED  PUSH    DWORD 25A2A40D  <=====放另一个辅助运算数0x25A2A40D
0177:0042A6F2  PUSH    EDX       
0177:0042A6F3  PUSH    EAX
0177:0042A6F4  CALL    00441870     <=====第一次运算  
0177:0042A6F9  ADD      EAX,BYTE +01   <=====运算结果加1
0177:0042A6FC  ADC      EDX,BYTE +00
0177:0042A6FF  PUSH    EDX
0177:0042A700  PUSH    EAX
0177:0042A701  CALL    0042A760        <=====第二次运算
0177:0042A706  ADD      ESP,BYTE +0C
0177:0042A709  MOV      [0048E7E8],EAX  <=====保存中间结果,下次使用
0177:0042A70E  RET   

第一次运算的call:
0177:00441870  MOV      EAX,[ESP+08]
0177:00441874  MOV      ECX,[ESP+10]
0177:00441878  OR      ECX,EAX
0177:0044187A  MOV      ECX,[ESP+0C]  <=====取辅助运算数0x25A2A40D
0177:0044187E  JNZ      00441889
0177:00441880  MOV      EAX,[ESP+04]  <=====取累算的结果
0177:00441884  MUL      ECX       <=====两数相乘送入ECX
0177:00441886  RET      10

第二次运算的call:
0177:0042A760  PUSH    EBP
0177:0042A761  MOV      EBP,ESP
0177:0042A763  PUSH    EBX
0177:0042A764  MOV      EAX,[EBP+08] <=====取累算的结果
0177:0042A767  MOV      EDX,[EBP+0C]
0177:0042A76A  MOV      EBX,[EBP+10] <=====取辅助运算数0x78B30C40
0177:0042A76D  DIV      EBX      <=====相除(商到EAX,余数到EDX)
0177:0042A76F  MOV      EAX,EDX    <=====只取余数
0177:0042A771  POP      EBX
0177:0042A772  POP      EBP
0177:0042A773  RET   
  这段程序主要完成形如 [(X*0x25A2A40D)+1]  mod  0x78B30C40 的功能,并且要重复运算4次!
OK,可以整理一下了:
    注册算码程序首先取用户名的奇位字符的2倍累加,对结果再进行形如(X*X+X)的运算,然后循环四次,循环中进行形如 [(X*0x25A2A40D)+1]  mod  0x78B30C40 的运算,结果为正确的注册码。
  到这里就结束了吗?没有,还有注册机的制作,请看下篇:C++Builder的注册机原码
(中篇完~~~)

  • 标 题:Universe 1.63注册码生成分析及注册机原码(下) (3千字)
  • 作 者:Maomao[CCG]
  • 时 间:2001-11-12 20:52:58

Universe 1.63注册码生成分析及注册机原码(下)
作者:Maomao[CCG]

下面是我用C++Builder5制作的源程序代码:

#include <vcl.h>
#pragma hdrstop
#include <math.h>

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
Close();
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)
{
unsigned __int64 Total=0;

Edit2->Text="";
if(Edit1->Text.IsEmpty())
{
ShowMessage("请输入姓名!");
Edit1->SetFocus();
}
  else
  {
  char* cp = new char[Edit1->Text.Length() + 1];
  strcpy( cp, Edit1->Text.c_str());
  for(int i=0;i<Edit1->Text.Length();i+=2)  //取奇字符求和
      Total+=cp[i];
  Total*=2;                                //乘以2
  Total=Total*Total+Total;                  //求(x*x)+x
  for(int i=0;i<4;i++)                      //循环四次
    {
    Total=Total*0X25A2A40D+1;           //[(X*0x25A2A40D)+1] mod 0x78B30C40
    Total=Total%0X78B30C40;
    }
  Edit2->Text=AnsiString(Total);
}
}



下面是窗体代码,可以不看:)

object Form1: TForm1
  Left = 218
  Top = 146
  BorderIcons = [biSystemMenu, biMinimize]
  BorderStyle = bsSingle
  Caption = 'Universe1.63 KeyGen By Maomao[CCG]'
  ClientHeight = 256
  ClientWidth = 348
  Color = clBtnFace
  Font.Charset = GB2312_CHARSET
  Font.Color = clWindowText
  Font.Height = -13
  Font.Name = '宋体'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object Image1: TImage
    Left = 0
    Top = 0
    Width = 348
    Height = 130
    Align = alTop
    AutoSize = True
    Center = True
  object Panel1: TPanel
    Left = 0
    Top = 130
    Width = 348
    Height = 63
    Align = alTop
    BevelInner = bvLowered
    BevelOuter = bvSpace
    Color = clScrollBar
    TabOrder = 0
    object Label1: TLabel
      Left = 3
      Top = 11
      Width = 59
      Height = 13
      Caption = '输入姓名:'
    end
    object Label2: TLabel
      Left = 16
      Top = 40
      Width = 46
      Height = 13
      Caption = '注册码:'
    end
    object Edit1: TEdit
      Left = 72
      Top = 5
      Width = 265
      Height = 21
      TabOrder = 0
    end
    object Edit2: TEdit
      Left = 72
      Top = 36
      Width = 265
      Height = 21
      ReadOnly = True
      TabOrder = 1
    end
  end
  object Button1: TButton
    Left = 59
    Top = 204
    Width = 75
    Height = 25
    Caption = '生成注册码'
    Default = True
    TabOrder = 1
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 203
    Top = 204
    Width = 75
    Height = 25
    Caption = '退出'
    TabOrder = 2
    OnClick = Button2Click
  end
  object StatusBar1: TStatusBar
    Left = 0
    Top = 237
    Width = 348
    Height = 19
    Panels = <
      item
        Text = 'KenGen By Maomao[CCG]'
        Width = 200
      end
      item
        Alignment = taRightJustify
        Text = '2001.11.11'
        Width = 50
      end>
    SimplePanel = False
  end
end
(全文完)
怎么样,看累了吧,休息一会儿~~~~~~