邪恶八进制信息安全团队技术讨论组's Archiver

twisters 2007-11-17 10:14

[原创]注册软件完全破解(初学破解)

文章作者:twisters(foxyfish#qq.com)
信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])

这是我第一次写这种东东。有什么不周之处请谅解。要破解程序在附件中。
先运行程序看看。
[attach]10771[/attach]
随便输入。结果会看到“无效的序列号,请正确输入您的用户名称和序列号”
好开工了,用w32dasm反汇编。找到字符“无效的序列号,请正确输入您的用户名称和序列号”
所在的代码。
如下:
[code]* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00406508(C)
|
:004065DA 56           push esi
:004065DB 56           push esi

* Possible StringData Ref from Data Obj ->"无效的序列号,请正确输入您的用户名称和序列号,并"
                    ->"确信没有输入多余的空格符!"
                 |
:004065DC 6820174400       push 00441720
:004065E1 EB07          jmp 004065EA[/code]


这段代码是用来显示“无效的序列号,请正确输入您的用户名称和序列号”的。找到调用它的地方
如下:
[code]:004064F1 8BCB          mov ecx, ebx
:004064F3 8BF8          mov edi, eax
:004064F5 E8EC200200       call 004285E6
:004064FA 8BD8          mov ebx, eax
:004064FC 53           push ebx
:004064FD 57           push edi
:004064FE E8DDFEFFFF       call 004063E0   ;此处是序列号比较
:00406503 83C408         add esp, 00000008
:00406506 85C0          test eax, eax
:00406508 0F84CC000000      je 004065DA    ;在此处被调用,一般的序列号比较一定在前
:0040650E 89742410        mov dword ptr [esp+10], esi
:00406512 8D442418        lea eax, dword ptr [esp+18]
:00406516 8D4C240C        lea ecx, dword ptr [esp+0C]



call 004063E0的函数; 下面的代码是从OD中取出的。不过和W32DASM中的一样

004063E0 /$ 83EC 14    sub   esp, 14
004063E3 |. 83C9 FF    or   ecx, FFFFFFFF
004063E6 |. 33C0     xor   eax, eax
004063E8 |. 33D2     xor   edx, edx
004063EA |. 53      push  ebx
004063EB |. 55      push  ebp
004063EC |. 56      push  esi
004063ED |. 8B7424 24   mov   esi, dword ptr [esp+24]
004063F1 |. 57      push  edi
004063F2 |. 8BFE     mov   edi, esi
004063F4 |. 32DB     xor   bl, bl
004063F6 |. F2:AE     repne  scas byte ptr es:[edi] ;把name输入的
004063F8 |. F7D1     not   ecx                ;字符数
004063FA |. 49      dec   ecx                 ;
004063FB |. 74 16     je   short 00406413
004063FD |> 8A0C32    /mov   cl, byte ptr [edx+esi];把name输入字符的
00406400 |. 8BFE     |mov   edi, esi              ;ASCLL码
00406402 |. 02D9     |add   bl, cl                ;累加到BL中
00406404 |. 83C9 FF    |or   ecx, FFFFFFFF         ;  
00406407 |. 33C0     |xor   eax, eax              ;
00406409 |. 42      |inc   edx                   ;
0040640A |. F2:AE     |repne  scas byte ptr es:[edi]   ;
0040640C |. F7D1     |not   ecx                 ;
0040640E |. 49      |dec   ecx                   ;
0040640F |. 3BD1     |cmp   edx, ecx            ;
00406411 |.^ 72 EA     \jb   short 004063FD      ;
00406413 |> A1 F0164400  mov   eax, dword ptr [4416F0]
00406418 |. 8B0D F4164400 mov   ecx, dword ptr [4416F4]
0040641E |. 8B15 F8164400 mov   edx, dword ptr [4416F8]
00406424 |. 894424 10   mov   dword ptr [esp+10], eax
00406428 |. A1 FC164400  mov   eax, dword ptr [4416FC]
0040642D |. 894C24 14   mov   dword ptr [esp+14], ecx
00406431 |. 8A0D 00174400 mov   cl, byte ptr [441700]
00406437 |. 894424 1C   mov   dword ptr [esp+1C], eax
0040643B |. 8B4424 2C   mov   eax, dword ptr [esp+2C]
0040643F |. 884C24 20   mov   byte ptr [esp+20], cl
00406443 |. BF 01000000  mov   edi, 1
00406448 |. 33C9     xor   ecx, ecx
0040644A |. 895424 18   mov   dword ptr [esp+18], edx
0040644E |. 2BF8     sub   edi, eax
00406450 |> 02D9     /add   bl, cl                   ; ECX中放的是循环次数--18次
00406452 |. BD 05000000  |mov   ebp, 5                ;产生18位序列号
00406457 |. 8AD3     |mov   dl, bl                    ;把CL加到BL中
00406459 |. 83E2 0F    |and   edx, 0F                  ;去掉BL的高4位
0040645C |. 8A4414 10   |mov   al, byte ptr [esp+edx+10] ; [esp+10]处有一个字符数组
‘0’,‘1’。。。‘F’这行代码就是把BL表示的16进制数转为字符
00406460 |. 8B5424 2C   |mov   edx, dword ptr [esp+2C]  ;
00406464 |. 884424 28   |mov   byte ptr [esp+28], al      ;
00406468 |. 8D3411    |lea   esi, dword ptr [ecx+edx]     ;
0040646B |. 33D2     |xor   edx, edx                  ;
0040646D |. 8D0437    |lea   eax, dword ptr [edi+esi]    ;  EAX中存放已从code字符中取出几个字符
00406470 |. F7F5     |div   ebp                     ;模5
00406472 |. B0 2D     |mov   al, 2D                  ;
00406474 |. 85D2     |test  edx, edx                 ;若为0就跳;
00406476 |. 74 04     |je   short 0040647C             ;
00406478 |. 8A4424 28   |mov   al, byte ptr [esp+28]     ;取出刚才算出的字符
0040647C |> 3806     |cmp   byte ptr [esi], al         ;CODE中对应的字符和算出的比较
0040647E   75 13     jnz   short 00406493           ;
00406480 |. 41      |inc   ecx                     ;
00406481 |. 83F9 18    |cmp   ecx, 18               ;是否运行了18次
00406484 |.^ 72 CA     \jb   short 00406450         ;
00406486 |. 5F      pop   edi
00406487 |. 5E      pop   esi
00406488 |. 5D      pop   ebp
00406489 |. B8 01000000  mov   eax, 1
0040648E |. 5B      pop   ebx
0040648F |. 83C4 14    add   esp, 14
00406492 |. C3      retn
00406493 |> 5F      pop   edi
00406494 |. 5E      pop   esi
00406495 |. 5D      pop   ebp
00406496 |. 33C0     xor   eax, eax
00406498 |. 5B      pop   ebx
00406499 |. 83C4 14    add   esp, 14
0040649C \. C3      retn[/code]
这个序列产生器的算法就是把name的各个字符累加到BL中
然后BL加0
将BL中低4位表示的16进制数转为字符输出,
然后BL加1
将BL中低4位表示的16进制数转为字符输出,
循环18次输出18个字符,
不过要将第5,10,15,20位的字符换为‘-’
这样就得到了注册码。
name:123456
code:568B-4A19-C730-DDE0-7C29
从算法可以看出123456与6554321的序列号相同
知道算法注册机就不是问题了。。
代码:
[code]unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls,Unit2;

type
TForm1 = class(TForm)
  Panel1: TPanel;
  Panel2: TPanel;
  Label3: TLabel;
  Panel5: TPanel;
  Panel6: TPanel;
  Panel7: TPanel;
  Panel8: TPanel;
  Panel9: TPanel;
  Edit1: TEdit;
  Edit2: TEdit;
  procedure Panel7Click(Sender: TObject);
  procedure Panel6Click(Sender: TObject);
  procedure Panel5Click(Sender: TObject);
private
  { Private declarations }
  procedure caculate(str:string;var resl:string);
public
  { Public declarations }
end;

var
Form1: TForm1;
  Form2: TForm2;
implementation

{$R *.dfm}
procedure tform1.caculate(str:string;var resl:string);


var

result:string;
len,i:integer;
  a,c:byte;
  b:char;

  const
Digits: array[0..15] of char =
('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');


begin
  len:=length(str);
  Result := '';
begin

    a:=$00;

   for i:=0 to len-1 do

    a:=a + ord(str[i+1]);


   end;



begin
// c:= a and $12;

for i := 0 to 23 do
begin
  a:=ord(a)+i;
  b:= Digits[(a and $000f)];
  if (i+1) mod 5=0 then
   b:='-';
Result := Result +b;
   end;
   end;
   resl:=result;
end;


procedure TForm1.Panel7Click(Sender: TObject);
begin
close;
end;

procedure TForm1.Panel6Click(Sender: TObject);
begin
close;
end;

procedure TForm1.Panel5Click(Sender: TObject);
var resl:string;
var strl:string;
begin

  strl:=edit1.text;
   if (length(strl)<4) then
  begin
     Form2:=TForm2.Create(self);
  Form2.Show;
   //showmessage(&#39;输入字符应大于4位!&#39;);
   exit;
  end;
caculate(strl,resl);
edit2.text:=resl;
end;


end.[/code]

cyg07 2007-11-18 16:54

直接从帖上看,我对楼主的注解有异议。反汇编后的代码和直接写汇编代码或其他高级语言都是有点
区别。下面是我的注解 。

004063E0 /$ 83EC 14   sub  esp, 14
//堆栈操作
004063E3 |. 83C9 FF   or   ecx, FFFFFFFF
//ECX=FFFFFFF;结合后面的取反操作
004063E6 |. 33C0     xor  eax, eax
//清空eax,为scasb指令提供比较对象,实际上为数组中的结尾&#39;\0&#39;
004063E8 |. 33D2     xor  edx, edx
//清空edx
004063EA |. 53      push  ebx
004063EB |. 55      push  ebp
004063EC |. 56      push  esi
//堆栈操作
004063ED |. 8B7424 24  mov  esi, dword ptr [esp+24]
//获取name数组的首地址
004063F1 |. 57      push  edi
//压栈操作
004063F2 |. 8BFE     mov  edi, esi
//edi=esi
004063F4 |. 32DB     xor  bl, bl
//清空bl
004063F6 |. F2:AE    repne scas byte ptr es:[edi]
//查找数组中的"/0"
004063F8 |. F7D1     not  ecx
//取反得到整个数组的完整长度               
004063FA |. 49      dec  ecx
//减去"/0",获取输入的name字符长度               
004063FB |. 74 16    je   short 00406413
//判断是否查找到"/0"

eros412 2007-11-30 02:37

不只是654321,只要用户名的每个字符的ascii码加起来等于0x35就获得相同的序列号

00406481 |. 83F9 18   |cmp  ecx, 18              ; //这边不是是否运行了18次,而是24,18是16进
                                                    制,所以是24次,序列号的长度     

冷血书生 2007-12-1 21:06

楼上正解,楼主忽略了进制转换问题!

00406481 |. 83F9 18   |cmp  ecx, 18              ; 这里是循环次数的比较!

页: [1]
© 1999-2008 EvilOctal Security Team