欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

一个简单的注册机程序破解

程序员文章站 2022-04-22 10:46:35
先运行程序,标题为CrackMe,第一行输出“Type your serial”,因为没有任何提示,随便输入一些字符串,都是输出“Ops! Wrong se...
先运行程序,标题为CrackMe,第一行输出“Type your serial”,因为没有任何提示,随便输入一些字符串,都是输出“Ops! Wrong serial, try again.”,回车后程序结束。

   用ida 载入,看反汇编代码:

代码:

.text:00401290 ; =============== S U B R O U T I N E =======================================

.text:00401290

.text:00401290 ; Attributes: bp-based frame

.text:00401290

.text:00401290 ; int __cdecl main(int argc, const char **argv, const char **envp)

.text:00401290 _main           proc near               ; CODE XREF: ___mingw_CRTStartup+E2p

.text:00401290

.text:00401290 var_8C          = dword ptr -8Ch

.text:00401290 var_80          = dword ptr -80h

.text:00401290 var_7C          = dword ptr -7Ch

.text:00401290 var_78          = dword ptr -78h

.text:00401290 var_74          = dword ptr -74h

.text:00401290 var_70          = dword ptr -70h

.text:00401290 var_6A          = byte ptr -6Ah

.text:00401290 var_69          = byte ptr -69h

.text:00401290 var_68          = byte ptr -68h

.text:00401290 var_64          = dword ptr -64h

.text:00401290 var_60          = dword ptr -60h

.text:00401290 var_5C          = dword ptr -5Ch

.text:00401290 var_58          = dword ptr -58h

.text:00401290 var_54          = dword ptr -54h

.text:00401290 var_50          = dword ptr -50h

.text:00401290 var_4C          = word ptr -4Ch

.text:00401290 var_48          = byte ptr -48h

.text:00401290 var_44          = dword ptr -44h

.text:00401290 var_40          = dword ptr -40h

.text:00401290 var_3C          = dword ptr -3Ch

.text:00401290 var_38          = dword ptr -38h

.text:00401290 var_34          = dword ptr -34h

.text:00401290 var_30          = dword ptr -30h

.text:00401290 var_2C          = dword ptr -2Ch

.text:00401290 var_28          = byte ptr -28h

.text:00401290 var_24          = dword ptr -24h

.text:00401290 var_20          = dword ptr -20h

.text:00401290 var_1C          = dword ptr -1Ch

.text:00401290 var_18          = byte ptr -18h

.text:00401290 argc            = dword ptr  8

.text:00401290 argv            = dword ptr  0Ch

.text:00401290 envp            = dword ptr  10h

 

;定义了很多变量

 

.text:00401290

.text:00401290                 push    ebp

.text:00401291                 mov     ebp, esp

.text:00401293                 sub     esp, 0B8h

.text:00401299                 and     esp, 0FFFFFFF0h

.text:0040129C                 mov     eax, 0

.text:004012A1                 add     eax, 0Fh

.text:004012A4                 add     eax, 0Fh

.text:004012A7                 shr     eax, 4

.text:004012AA                 shl     eax, 4

.text:004012AD                 mov     [ebp+var_8C], eax

.text:004012B3                 mov     eax, [ebp+var_8C]

.text:004012B9                 call    ___chkstk

.text:004012BE                 call    ___main

.text:004012C3                 mov     dword ptr [esp], offset aTitleCrackme ; "title CrackMe"

.text:004012CA                 call    system

 

;从这里开始,看到是一系列赋值操作

.text:004012CF                 mov     eax, ds:dword_40300E

.text:004012D4                 mov     dword ptr [ebp+var_28], eax

.text:004012D7                 mov     eax, ds:dword_403012

.text:004012DC                 mov     [ebp+var_24], eax

.text:004012DF                 mov     eax, ds:dword_403016

.text:004012E4                 mov     [ebp+var_20], eax

.text:004012E7                 mov     eax, ds:dword_40301A

.text:004012EC                 mov     [ebp+var_1C], eax

.text:004012EF                 movzx   eax, ds:byte_40301E

.text:004012F6                 mov     [ebp+var_18], al

.text:004012F9                 mov     eax, ds:dword_403020

.text:004012FE                 mov     dword ptr [ebp+var_48], eax

.text:00401301                 mov     eax, ds:dword_403024

.text:00401306                 mov     [ebp+var_44], eax

.text:00401309                 mov     eax, ds:dword_403028

.text:0040130E                 mov     [ebp+var_40], eax

.text:00401311                 mov     eax, ds:dword_40302C

.text:00401316                 mov     [ebp+var_3C], eax

.text:00401319                 mov     eax, ds:dword_403030

.text:0040131E                 mov     [ebp+var_38], eax

.text:00401321                 mov     eax, ds:dword_403034

.text:00401326                 mov     [ebp+var_34], eax

.text:00401329                 mov     eax, ds:dword_403038

.text:0040132E                 mov     [ebp+var_30], eax

.text:00401331                 mov     eax, ds:dword_40303C

.text:00401336                 mov     [ebp+var_2C], eax

.text:00401339                 mov     eax, ds:dword_403040

.text:0040133E                 mov     dword ptr [ebp+var_68], eax

.text:00401341                 mov     eax, ds:dword_403044

.text:00401346                 mov     [ebp+var_64], eax

.text:00401349                 mov     eax, ds:dword_403048

.text:0040134E                 mov     [ebp+var_60], eax

.text:00401351                 mov     eax, ds:dword_40304C

.text:00401356                 mov     [ebp+var_5C], eax

.text:00401359                 mov     eax, ds:dword_403050

.text:0040135E                 mov     [ebp+var_58], eax

.text:00401361                 mov     eax, ds:dword_403054

.text:00401366                 mov     [ebp+var_54], eax

.text:00401369                 mov     eax, ds:dword_403058

.text:0040136E                 mov     [ebp+var_50], eax

.text:00401371                 movzx   eax, ds:word_40305C

.text:00401378                 mov     [ebp+var_4C], ax

.text:0040137C                 lea     eax, [ebp+var_28]

.text:0040137F                 mov     [esp], eax      ; char *

.text:00401382                 call    puts

;这里执行puts输出字符串命令,首地址是ebp+var_28,再看前面的赋值操作,可以确定这里输出的正是提示字符串“Type your serial”。

 

.text:00401387                 lea     eax, [ebp+var_78]

.text:0040138A                 mov     [esp+14h], eax

.text:0040138E                 lea     eax, [ebp+var_6A]

.text:00401391                 mov     [esp+10h], eax

.text:00401395                 lea     eax, [ebp+var_74]

.text:00401398                 mov     [esp+0Ch], eax

.text:0040139C                 lea     eax, [ebp+var_69]

.text:0040139F                 mov     [esp+8], eax

.text:004013A3                 lea     eax, [ebp+var_70]

.text:004013A6                 mov     [esp+4], eax

.text:004013AA                 mov     dword ptr [esp], offset aDCDCD ; "%d%c%d%c%d"

.text:004013B1                 call    scanf

;这里执行scanf命令,输入三个int数据,两个字符,三个int分别保存在[ebp+var_70],[ebp+var_74],[ebp+var_78]

 

 

.text:004013B6                 mov     edx, [ebp+var_70]  ;取输入的第一个int

.text:004013B9                 mov     eax, edx

.text:004013BB                 shl     eax, 2

.text:004013BE                 add     eax, edx

.text:004013C0                 add     eax, eax

.text:004013C2                 mov     [ebp+var_7C], eax

.text:004013C5                 lea     eax, [ebp+var_7C]

.text:004013C8                 add     dword ptr [eax], 7Dh

.text:004013CB                 mov     eax, [ebp+var_7C]

.text:004013CE                 add     eax, eax

.text:004013D0                 mov     [ebp+var_7C], eax

.text:004013D3                 lea     eax, [ebp+var_7C]

.text:004013D6                 inc     dword ptr [eax]

.text:004013D8                 lea     eax, [ebp+var_7C]

.text:004013DB                 sub     dword ptr [eax], 15h

.text:004013DE                 lea     eax, [ebp+var_7C]

.text:004013E1                 add     dword ptr [eax], 58h

;这里是一系列运算,假设第一个int表示为a,[ebp+var_7C]表示为tmp1,那么tmp1=((a*4+a)*2 +0x7D ) *2 + 1 - 0x15 + 0x58

;化简得 tmp1 = 20*a + 318

 

.text:004013E4                 mov     eax, [ebp+var_70]

.text:004013E7                 add     eax, eax

.text:004013E9                 mov     [ebp+var_80], eax

.text:004013EC                 lea     eax, [ebp+var_80]

.text:004013EF                 add     dword ptr [eax], 0FDh

.text:004013F5                 mov     eax, [ebp+var_80]

.text:004013F8                 add     eax, eax

.text:004013FA                 mov     [ebp+var_80], eax

.text:004013FD                 lea     eax, [ebp+var_80]

.text:00401400                 inc     dword ptr [eax]

;跟上面类似,这是也是取第一个输入的数,然后进行操作,结果放到[ebp+var_80]中,不妨将其标记为tmp2,则tmp2=( 2*a + 0xFD ) * 2 + 1

;化简一下 tmp2 = 4*a + 507

 

.text:00401402                 mov     eax, [ebp+var_80]

.text:00401405                 add     eax, [ebp+var_7C]

.text:00401408                 add     eax, 2

.text:0040140B                 mov     [ebp+var_80], eax

;这里可以看到,tmp2 = tmp2 + tmp1 + 2 = 24*a + 827

 

.text:0040140E                 mov     eax, [ebp+var_74]  ;eax=输入的第二个整数b

.text:00401411                 cmp     eax, [ebp+var_7C]  ;eax和tmp1比较

.text:00401414                 jnz     short loc_40142B      ;不相等直接退出

.text:00401416                 mov     eax, [ebp+var_78]   ;相等则令 eax = 输入的第三个整数

.text:00401419                 cmp     eax, [ebp+var_80]   ;eax和tmp2比较

.text:0040141C                 jnz     short loc_40142B      ;不相等退出

.text:0040141E                 lea     eax, [ebp+var_48]

.text:00401421                 mov     [esp], eax      ; char *

.text:00401424                 call    puts

.text:00401429                 jmp     short locret_401442   ;跳到正确的输出

.text:0040142B ; ---------------------------------------------------------------------------

 

 

.text:0040142B

.text:0040142B loc_40142B:                             ; CODE XREF: _main+184j

.text:0040142B                                         ; _main+18Cj

.text:0040142B                 lea     eax, [ebp+var_68]

.text:0040142E                 mov     [esp], eax      ; char *

.text:00401431                 call    puts

.text:00401436                 mov     dword ptr [esp], offset aPauseNul ; "Pause >NUL"

.text:0040143D                 call    system       ;这里是错误的输出

.text:00401442

 

 

.text:00401442 locret_401442:                          ; CODE XREF: _main+199j

.text:00401442                 leave

.text:00401443                 retn

.text:00401443 _main           endp               ;这里是正确的输出

     这样就很容易构造出一个正确的字符串输入了。

   但是结果一闪就过去了,我没想到什么好办法,只好用od动态调试,这样显示出正确结果后就挺下来了。

   字符串合法情况下输出“Right Crack, now write a KeyGen”。

 

   这个注册机真是非常非常简陋,只是用到了基本的运算,连除法都没有。不过我都想不太明白源程序怎么会搞出那么多的赋值操作~~~
crackme下载:
http://up.2cto.com/2013/0627/20130627095859133.rar