• 标 题:XXX报表数据管理系统(行业软件)
  • 作 者: isfun
  • 时 间:2003/03/20 01:03am
  • 链 接:http://bbs.pediy.com

这个程序是XXX报表数据管理系统(行业软件),程序是Delphi编的,没加壳。OK,用DEDE反编译,找到SoftRegister.pas的文件(这是个注册窗体文件),找到
* Possible String Reference to: '祝贺'
|
0065210B   B924246500             mov     ecx, $00652424

* Possible String Reference to: '您已经完成了XX报表的注册,您可以....(不写了)
00652110   BA2C246500             mov     edx, $0065242C

* Reference to TApplication instance
|
00652115   A1B8896D00             mov     eax, dword ptr [$006D89B8]
0065211A   8B00                   mov     eax, [eax]

* Reference to : TApplication._PROC_00457374()
|
0065211C   E85352E0FF             call    00457374
00652121   8B45FC                 mov     eax, [ebp-$04]

* Reference to field TSoftRegisterform.OFFS_0234
|
00652124   C7803402000001000000   mov     dword ptr [eax+$0234], $00000001
0065212E   EB29                   jmp     00652159
00652130   6A30                   push    $30  (查找这一句是从哪里跳来的,害我这么苦)

* Possible String Reference to: '警告'
|
00652132   B9CC216500             mov     ecx, $006521CC

* Possible String Reference to: '软件注册码错误!您可以...(不写了)
00652137   BA60246500             mov     edx, $00652460

* Reference to TApplication instance
|
0065213C   A1B8896D00             mov     eax, dword ptr [$006D89B8]
00652141   8B00                   mov     eax, [eax]

* Reference to : TApplication._PROC_00457374()
|
00652143   E82C52E0FF             call    00457374


经查是从00651FDD跳来的,

00651FD5   5A                     pop     edx

* Reference to: Unit_00484DE4.Proc_00485348
|
00651FD6   E86D33E3FF             call    00485348
00651FDB   84C0                   test    al, al
00651FDD   0F844D010000           jz      00652130 
好了,让我们打开调试软件装入(我用的是ollyDbg,我只会用滚动条拉动设断点,哪位大侠有直接打入地址的方法请告诉我),在00651FD5处设断
当按下注册按纽时中断,按F8跳过00651FD6这个call时al变成了0,哈哈就是这个call,重装入,F7进入这个call,
00485348  /$  53            PUSH EBX
00485349  |.  56            PUSH ESI
0048534A  |.  57            PUSH EDI
0048534B  |.  8BF9          MOV EDI,ECX
0048534D  |.  8BF2          MOV ESI,EDX
0048534F  |.  8BD8          MOV EBX,EAX
00485351  |.  33C0          XOR EAX,EAX
00485353  |.  E8 20050000   CALL REPORT.00485878      算机器码(每台电脑都不同,算法不研究,反正软件里有生成了)
00485358  |.  8BC8          MOV ECX,EAX
0048535A  |.  8BD6          MOV EDX,ESI
0048535C  |.  8BC3          MOV EAX,EBX
0048535E  |.  E8 19070000   CALL REPORT.00485A7C   关键call,算法全靠它了,进去!
00485363  |.  3BF8          CMP EDI,EAX 算出来的注册码放在EAX,EDI放你输进去的注册码
00485365  |.  0F94C0        SETE AL   不相等设0
00485368  |.  5F            POP EDI
00485369  |.  5E            POP ESI
0048536A  |.  5B            POP EBX
0048536B  \.  C3            RETN

进入
00485A7C
.
.
.
.
(上面都是判断输入内容的格试对错,不理它,看下面的算法
00485AF0  |.  BB 01000000   MOV EBX,1                                ;  放入计算姓名初始长度
00485AF5  |>  8B45 FC       /MOV EAX,DWORD PTR SS:[EBP-4]            ;  得到用户的姓名
00485AF8  |.  33C9          |XOR ECX,ECX                             ;  清零
00485AFA  |.  8A4C18 FF     |MOV CL,BYTE PTR DS:[EAX+EBX-1]          ;  放入姓名的循环字节到cl(第一个字节,第二个字节,循环..)
00485AFE  |.  83E1 07       |AND ECX,7                               ;  和7作与运算后的值(以下简称X)
00485B01  |.  8B45 FC       |MOV EAX,DWORD PTR SS:[EBP-4]            ;  得到用户的姓名
00485B04  |.  0FB64418 FF   |MOVZX EAX,BYTE PTR DS:[EAX+EBX-1]       ;  放入姓名的循环字节到EAX
00485B09  |.  50            |PUSH EAX
00485B0A  |.  8B45 F4       |MOV EAX,DWORD PTR SS:[EBP-C]            ;  EAX得到机器码DWORD
00485B0D  |.  5A            |POP EDX                                 ;  字节放回到EDX
00485B0E  |.  51            |PUSH ECX                                ;  X放入堆栈ECX
00485B0F  |.  8BCA          |MOV ECX,EDX
00485B11  |.  99            |CDQ                                     ;  机器码扩展放入EDX:EAX
00485B12  |.  F7F9          |IDIV ECX                                ;  机器码除以循环字节
00485B14  |.  59            |POP ECX                                 ;  把和7作与运算的后的字节放ECX
00485B15  |.  D3E2          |SHL EDX,CL                              ;  余数向左移动X,CL
00485B17  |.  03FA          |ADD EDI,EDX                             ;  EDI加上EDXED
00485B19  |.  43            |INC EBX
00485B1A  |.  4E            |DEC ESI
00485B1B  |.^ 75 D8         \JNZ SHORT REPORT.00485AF5
00485B1D  |>  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]             ;  单位名称
00485B20  |.  E8 ABE7F7FF   CALL REPORT.004042D0                   ;  得到单位名称的长度
00485B25  |.  8BF0          MOV ESI,EAX
00485B27  |.  85F6          TEST ESI,ESI
00485B29  |.  7E 21         JLE SHORT REPORT.00485B4C
00485B2B  |.  BB 01000000   MOV EBX,1
00485B30  |>  8B45 F8       /MOV EAX,DWORD PTR SS:[EBP-8]            ;  单位名称放入EAX,DWO
00485B33  |.  0FB64418 FF   |MOVZX EAX,BYTE PTR DS:[EAX+EBX-1]       ;  循环字节X
00485B38  |.  8BD0          |MOV EDX,EAX
00485B3A  |.  83CA FF       |OR EDX,FFFFFFFF                         ;  or EDX
00485B3D  |.  2355 F4       |AND EDX,DWORD PTR SS:[EBP-C]            ;  与机器码作与运算
00485B40  |.  8B4D F8       |MOV ECX,DWORD PTR SS:[EBP-8]            ;  单位名称放入ECX
00485B43  |.  0FAFD0        |IMUL EDX,EAX
00485B46  |.  03FA          |ADD EDI,EDX
00485B48  |.  43            |INC EBX
00485B49  |.  4E            |DEC ESI
00485B4A  |.^ 75 E4         \JNZ SHORT REPORT.00485B30
00485B4C  |>  8BC7          MOV EAX,EDI
00485B4E  |.  E8 AD2BF8FF   CALL REPORT.00408700                   ;  得到EAX的前四位
00485B53  |.  8BD8          MOV EBX,EAX
00485B55  |.  66:0FAF5D F4  IMUL BX,WORD PTR SS:[EBP-C]              ;  前四位乘以后机器码四位
00485B5A  |.  0FB7DB        MOVZX EBX,BX
00485B5D  |.  03DF          ADD EBX,EDI
00485B5F  |.  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-C]             ;  机器码放入EAX
00485B62  |.  E8 992BF8FF   CALL REPORT.00408700    机器码前四位放入EAX
00485B67  |.  66:F7EF       IMUL DI                                  ;  AX*DI
00485B6A  |.  0FB7C0        MOVZX EAX,AX
00485B6D  |.  03D8          ADD EBX,EAX
00485B6F  |.  8BFB          MOV EDI,EBX (EDI数值就是注册码,此进算完成)
00485B71  |.  33C0          XOR EAX,EAX
00485B73  |.  5A            POP EDX
00485B74  |.  59            POP ECX
00485B75  |.  59            POP ECX
00485B76  |.  64:8910       MOV DWORD PTR FS:[EAX],EDX
00485B79  |.  68 A05B4800   PUSH REPORT.00485BA0
00485B7E  |>  8D45 EC       LEA EAX,DWORD PTR SS:[EBP-14]
00485B81  |.  BA 02000000   MOV EDX,2
00485B86  |.  E8 E9E4F7FF   CALL REPORT.00404074
00485B8B  |.  8D45 F8       LEA EAX,DWORD PTR SS:[EBP-8]
00485B8E  |.  BA 02000000   MOV EDX,2
00485B93  |.  E8 DCE4F7FF   CALL REPORT.00404074
00485B98  \.  C3            RETN

看出来算法,怎样把它编出来呢,我不会asm,会用delphi,好吧,就用delphi。

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, forms,
 Dialogs, StdCtrls;

type
 Tform1 = class(Tform)
   Edit1: TEdit;
   Label1: TLabel;
   Label2: TLabel;
   Edit2: TEdit;
   Button1: TButton;
   Label3: TLabel;
   Edit3: TEdit;
   Edit4: TEdit;
   Label4: TLabel;
   Label5: TLabel;

   procedure Button1Click(Sender: TObject);
 private

   { Private declarations }
 public
   { Public declarations }
 end;
 function strto16(achar:char):integer;
 function strto16h(astr:string):integer;
var
 form1: Tform1;

implementation

{$R *.dfm}
function Add1(i, j: Integer): Integer;
var
 Temp: Integer;
 k: Integer;
begin
 Temp := 0;
 for k := 1 to j do
   Inc(Temp, i);
 Result := Temp;
end;

function Add2(i, j: Integer): Integer;
var
 temp: Integer;
 k: Integer;
begin
if j=0 then
begin
 result:=1;
 exit;
end;
 temp := 1;
 for k := 1 to j do
   temp := Add1(temp, i);
 Result := temp;
end;

function strto16(achar:char):integer;
begin
case achar of
'0': result:=0;
'1':result:=1;
'2':result:=2;
'3':result:=3;
'4':result:=4;
'5':result:=5;
'6':result:=6;
'7':result:=7;
'8':result:=8;
'9':result:=9;
'A':result:=10;
'B':result:=11;
'C':result:=12;
'D':result:=13;
'E':result:=14;
'F':result:=15;
end;
end;

function strto16h(astr:string):integer;
var heji,i:integer;
begin
heji:=0;
for i:=length(astr)downto 1 do
begin
heji:=heji+strto16(astr[i])*add2(16,length(astr)-i);
end;
result:=heji;
end;

//上面主要是编一个strto16的函数,把十六进制转成10进制,不知道有没有现成的。

procedure Tform1.Button1Click(Sender: TObject);
var len1,len2,i,cx1,cx2,cx3,cx4:integer;
sumsum1,sumsum:integer;
temp1,namestr,danweistr,serialstr:string;
begin
namestr:=edit1.text; //姓名字串

len1:=length(namestr); //姓名长度

danweistr:=edit2.text;  //单位字串

len2:=length(danweistr); //单位长度

serialstr:=edit3.text;  //机器码字串
cx2:=strto16h(edit3.Text);//把字符机器码转成10进制的形式,如机器码是'A012BC01'十进制就是2685582337。

asm
xor edi,edi
xor edx,edx
xor eax,eax
xor ebx,ebx
MOV ESI,len1
MOV EBX,1          //                      ;  放入计算姓名初始长度
@sub1:
MOV EAX,namestr       //       ;  得到用户的姓名
XOR ECX,ECX                     //        ;  清零
MOV CL,BYTE PTR DS:[EAX+EBX-1]   //       ;  放入姓名的循环字节到CL
AND ECX,7          //                     ;  和7作与运算后的值(以下简称X)
MOV EAX,namestr    //        ;  得到用户的姓名
MOVZX EAX,BYTE PTR DS:[EAX+EBX-1]     //  ;  放入姓名的循环字节到EAX
PUSH EAX      //
MOV EAX,cx2   //         ;  EAX得到机器码DWORD
POP EDX    //                             ;  字节放回到EDX
PUSH ECX   //                             ;  X放入堆栈ECX
MOV ECX,EDX  //
CDQ       //                              ;  机器码扩展放入EDX:EAX
IDIV ECX  //                              ;  机器码除以循环字节
POP ECX       //                          ;  把和7作与运算的后的字节放ECX
SHL EDX,CL       //                       ;  余数向左移动X,CL
ADD EDI,EDX    //                         ;  EDI加上EDX
INC EBX
DEC ESI
JNZ @sub1                 //
MOV EAX,danweistr //
//00485B20  |.  E8 ABE7F7FF   CALL REPORT.004042D0        
MOV ESI,len2  //直接使用长单位长度
TEST ESI,ESI
JLE @sub3
MOV EBX,1
@sub2:
MOV EAX,danweistr   //   单位放入EAX
MOVZX EAX,BYTE PTR DS:[EAX+EBX-1]    //   循环字节X
MOV EDX,EAX
OR EDX,$FFFFFFFF //       or EDX
AND EDX,cx2  //     与机器码作与运算DWORD
MOV ECX,danweistr  // 单位放入ECX,DWO
IMUL EDX,EAX
ADD EDI,EDX
INC EBX
DEC ESI
JNZ @sub2
@sub3:
MOV EAX,EDI
//CALL REPORT.00408700  这句用下面句代替
SHR  EAX ,16   //
MOV  EBX,EAX //
 IMUL BX,WORD PTR cx2 //                前四位乘以后机器码四位
 MOVZX EBX,BX
 ADD EBX,EDI
 MOV EAX,cx2          //    机器码EAX
 SHR EAX,16
//CALL REPORT.00408700
 IMUL DI            //   低字AXD
 MOVZX EAX,AX        
 ADD EBX,EAX        
 MOV EDI,EBX

 MOV EAX,EDI
 shr eax,16    
 MOV &sumsum,EAX (放前四位到变量sumsum)
 shl edi,16
 shr edi,16
 mov &sumsum1,edi(放后四位到变量sumsum1)
 end;
//为什么要分开,因为数值变量放不下
 showmessage('你要的注册码是:'+IntToHex(sumsum,4)+'-'+IntToHex(sumsum1,4));
//intohex函数是把十进制转成十六进制字符  
end;
//好了,就这样,运行你打入姓名,单位,机器码,就会弹出注册码!
//但为什么sumsum,sumsum1变量不能进行赋值操作,象Edit4.text:=sumsum+sumsum1就出错,我就弄不懂了,哪位能教我?
end.

初学crack,菜鸟一只,希望共同进步!