binbinbin 发表于 2006-11-25 12:33:26

Savage's Slayer's Crackme # 1算法分析

【破文标题】Savage's Slayer's Crackme # 1算法分析
【破文作者】XXNB
【作者邮箱】支持PYG
【作者主页】http://free.ys168.com/?binbinbin7456
【破解工具】OD
【破解平台】xpsp2
【软件名称】Savage's Slayer's Crackme # 1
【软件大小】
【原版下载】
【保护方式】
【软件简介】Easy for first :)

Difficulty: 1 - Very easy, for newbies
Platform: Windows
Language: Assembler

Published: 25. Nov, 2006
Downloads: 7
【破解声明】向大侠们学习!!!只为学习!请尊重作者的劳动成功!
------------------------------------------------------------------------
【破解过程】

可以去 http://www.crackmes.de 这个网站下载

1、这个crackme非常有趣。我早上下的然后看啊看啊,就是不知道在哪里下断好。不过我在跟踪的过程发现,要用到计算机名,还要用到一个
“reg.key”文件,于是我就建立了个“reg.key”文件。写入:123456789。运行,还是没能找到关键点,因为它根本就没有读取文件,怎么回
事??。然后我就复制我的用户名BINBIN到“reg.key”文件里。跟踪的时候,发现居然能读取BINBIN这个字符串,我当时奇怪得很。

最终,在我的试验下原来发现下面的00401292这句开始是对计算机名运算的,先是得到计算机名Ascii码累加值,然后一个循环减。最终结果要等于0,于是我知道当然是减用户名的Ascii码累加值才能等于0。原来,程序是读取你的剪切板的数据的。

所以,如果要使得register按钮有效,就必须复制自己的计算机名,然后按下check,就会出现“Step 1 ok -> now Register it!”了、。


注册按钮有效后就是读取文件了。首先,读取“reg.key”文件的字节数,一定要大于等于8位字节才有效。具体看下面代码注释。



0040108B|.51            push    ecx                              ; /pBufferSize => KeyMe1.0040333A
0040108C|.68 3B324000   push    0040323B                         ; |BINBIN
00401091|.E8 86020000   call    <jmp.&KERNEL32.GetComputerNameA> ; \GetComputerNameA
00401096|.68 3B324000   push    0040323B                         ; /BINBIN
0040109B|.E8 A0020000   call    <jmp.&KERNEL32.lstrlenA>         ; \lstrlenA
004010A0|.A3 46334000   mov   dword ptr , eax          ;计算机名长度
004010A5|.59            pop   ecx
004010A6|.58            pop   eax
004010A7|.60            pushad
004010A8|.9C            pushfd
004010A9|.BE 3B324000   mov   esi, 0040323B                  ;计算机名
004010AE|.C705 3E334000>mov   dword ptr , 0
004010B8|>AC            /lods    byte ptr                   ;这里这个循环就是得到计算机名的累加值了
004010B9|.0FB6C0      |movzx   eax, al
004010BC|.0105 3E334000 |add   dword ptr , eax
004010C2|.3C 00         |cmp   al, 0
004010C4|.^ 75 F2         \jnz   short 004010B8
004010C6|.9D            popfd
004010C7|.61            popad
004010C8|.33C0          xor   eax, eax
004010CA|.C9            leave
004010CB|.C2 1000       retn    10
004010CE|>837D 0C 10    cmp   dword ptr , 10
004010D2|.75 0A         jnz   short 004010DE
004010D4|.6A 00         push    0                              ; /Result = 0
004010D6|.FF75 08       push    dword ptr                 ; |hWnd
004010D9|.E8 7A020000   call    <jmp.&USER32.EndDialog>          ; \EndDialog
004010DE|>817D 0C 11010>cmp   dword ptr , 111
004010E5|.0F85 19020000 jnz   00401304
004010EB|.8B45 10       mov   eax, dword ptr
004010EE|.66:83F8 68    cmp   ax, 68                           ;(Initial CPU selection)
004010F2|.75 0A         jnz   short 004010FE
004010F4|.6A 00         push    0                              ; /Result = 0
004010F6|.FF75 08       push    dword ptr                 ; |hWnd
004010F9|.E8 5A020000   call    <jmp.&USER32.EndDialog>          ; \EndDialog
004010FE|>66:83F8 69    cmp   ax, 69
00401102|.75 13         jnz   short 00401117
00401104|.6A 40         push    40                               ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401106|.68 00304000   push    00403000                         ; |[ info ]
0040110B|.68 09304000   push    00403009                         ; |[ KeyMe # 1 coded by Slayer ]\r\n\r\nRules : No patching at all. >> Keygen it <<\r\n\r\nSolutions : [email protected]\r\n\r\nAll accepted solutions will be awarded by source code :)
00401110|.6A 00         push    0                              ; |hOwner = NULL
00401112|.E8 59020000   call    <jmp.&USER32.MessageBoxA>      ; \MessageBoxA
00401117|>66:83F8 6A    cmp   ax, 6A
0040111B|.0F85 41010000 jnz   00401262
00401121|.6A 00         push    0                              ; /hTemplateFile = NULL
00401123|.68 80000000   push    80                               ; |Attributes = NORMAL
00401128|.6A 03         push    3                              ; |Mode = OPEN_EXISTING
0040112A|.6A 00         push    0                              ; |pSecurity = NULL
0040112C|.6A 01         push    1                              ; |ShareMode = FILE_SHARE_READ
0040112E|.68 00000080   push    80000000                         ; |Access = GENERIC_READ
00401133|.68 26314000   push    00403126                         ; |reg.key
00401138|.E8 D3010000   call    <jmp.&KERNEL32.CreateFileA>      ; \CreateFileA
0040113D|.83F8 FF       cmp   eax, -1
00401140|.75 05         jnz   short 00401147
00401142|.E9 E7000000   jmp   0040122E
00401147|>A3 4A334000   mov   dword ptr , eax
0040114C|.6A 00         push    0                              ; /pFileSizeHigh = NULL
0040114E|.FF35 4A334000 push    dword ptr                ; |hFile = 00000088 (window)
00401154|.E8 C9010000   call    <jmp.&KERNEL32.GetFileSize>      ; \GetFileSize
00401159|.83F8 08       cmp   eax, 8                           ;文件的字节一定不能小于8
0040115C|.73 10         jnb   short 0040116E
0040115E|.FF35 4A334000 push    dword ptr                ; /hObject = 00000088 (window)
00401164|.E8 A1010000   call    <jmp.&KERNEL32.CloseHandle>      ; \CloseHandle
00401169|.E9 C0000000   jmp   0040122E
0040116E|>A3 52334000   mov   dword ptr , eax          ;存储计算机名的位数
00401173|.FF35 52334000 push    dword ptr                ; /MemSize = 8
00401179|.6A 40         push    40                               ; |Flags = GPTR
0040117B|.E8 AE010000   call    <jmp.&KERNEL32.GlobalAlloc>      ; \GlobalAlloc
00401180|.0BC0          or      eax, eax
00401182|.75 1F         jnz   short 004011A3
00401184|.68 0D314000   push    0040310D                         ; /Memory allocation error!
00401189|.6A 66         push    66                               ; |ControlID = 66 (102.)
0040118B|.FF75 08       push    dword ptr                 ; |hWnd
0040118E|.E8 EF010000   call    <jmp.&USER32.SetDlgItemTextA>    ; \SetDlgItemTextA
00401193|.FF35 4A334000 push    dword ptr                ; /hObject = 00000088 (window)
00401199|.E8 6C010000   call    <jmp.&KERNEL32.CloseHandle>      ; \CloseHandle
0040119E|.E9 B4000000   jmp   00401257
004011A3|>A3 4E334000   mov   dword ptr , eax
004011A8|.6A 00         push    0                              ; /pOverlapped = NULL
004011AA|.68 2E314000   push    0040312E                         ; |A
004011AF|.FF35 52334000 push    dword ptr                ; |BytesToRead = 8
004011B5|.FF35 4E334000 push    dword ptr                ; |Buffer = 00149A20
004011BB|.FF35 4A334000 push    dword ptr                ; |hFile = 00000088 (window)
004011C1|.E8 74010000   call    <jmp.&KERNEL32.ReadFile>         ; \ReadFile
004011C6|.0BC0          or      eax, eax
004011C8|.75 18         jnz   short 004011E2
004011CA|.FF35 4A334000 push    dword ptr                ; /hObject = 00000088 (window)
004011D0|.E8 35010000   call    <jmp.&KERNEL32.CloseHandle>      ; \CloseHandle
004011D5|.FF35 4E334000 push    dword ptr                ; /hMem = 00149A20
004011DB|.E8 54010000   call    <jmp.&KERNEL32.GlobalFree>       ; \GlobalFree
004011E0|.EB 4C         jmp   short 0040122E
004011E2|>FF35 4A334000 push    dword ptr                ; /hObject = 00000088 (window)
004011E8|.E8 1D010000   call    <jmp.&KERNEL32.CloseHandle>      ; \CloseHandle
004011ED|.56            push    esi
004011EE|.52            push    edx
004011EF|.8B35 4E334000 mov   esi, dword ptr
004011F5|.8B06          mov   eax, dword ptr              ;第一个值到eax。这个值是key文件中前4位倒过来的ascii码值
004011F7|.83C6 04       add   esi, 4
004011FA|.8B16          mov   edx, dword ptr              ;第二个值到edx。这个当然就是5~8位倒过来的ascii码值了
004011FC|.33C2          xor   eax, edx                         ;前面两个值异或。结果在eax
004011FE|.8B15 42334000 mov   edx, dword ptr           ;这里好像总是0的
00401204|.03C2          add   eax, edx                         ;加0相当于没有加
00401206|.5A            pop   edx
00401207|.5E            pop   esi
00401208|.3B05 3E334000 cmp   eax, dword ptr           ;计算机名的ascii累加值和上面运算的结果比较。相等就成功
0040120E      75 1E         jnz   short 0040122E                   ;这里就是关键跳了。
00401210|.68 D9304000   push    004030D9                         ; /Good work. You have done it!
00401215|.6A 66         push    66                               ; |ControlID = 66 (102.)
00401217|.FF75 08       push    dword ptr                 ; |hWnd
0040121A|.E8 63010000   call    <jmp.&USER32.SetDlgItemTextA>    ; \SetDlgItemTextA
0040121F|.6A 00         push    0                              ; /Enable = FALSE
00401221|.FF35 5A334000 push    dword ptr                ; |hWnd = 002A03C2 ('-> Register <-',class='Button',parent=00280320)
00401227|.E8 26010000   call    <jmp.&USER32.EnableWindow>       ; \EnableWindow
0040122C|.EB 29         jmp   short 00401257
0040122E|>68 F6304000   push    004030F6                         ; /Registration failed!!!
00401233|.6A 66         push    66                               ; |ControlID = 66 (102.)
00401235|.FF75 08       push    dword ptr                 ; |hWnd
00401238|.E8 45010000   call    <jmp.&USER32.SetDlgItemTextA>    ; \SetDlgItemTextA
0040123D|.6A 00         push    0                              ; /Enable = FALSE
0040123F|.FF35 5A334000 push    dword ptr                ; |hWnd = 002A03C2 ('-> Register <-',class='Button',parent=00280320)
00401245|.E8 08010000   call    <jmp.&USER32.EnableWindow>       ; \EnableWindow
0040124A|.6A 01         push    1                              ; /Enable = TRUE
0040124C|.FF35 56334000 push    dword ptr                ; |hWnd = 001B0330 ('Check',class='Button',parent=00280320)
00401252|.E8 FB000000   call    <jmp.&USER32.EnableWindow>       ; \EnableWindow
00401257|>FF35 4E334000 push    dword ptr                ; /hMem = 00149A20
0040125D|.E8 D2000000   call    <jmp.&KERNEL32.GlobalFree>       ; \GlobalFree
00401262|>66:83F8 67    cmp   ax, 67
00401266|.0F85 98000000 jnz   00401304
0040126C|.6A 00         push    0                              ; /hWnd = NULL
0040126E|.E8 03010000   call    <jmp.&USER32.OpenClipboard>      ; \OpenClipboard
00401273|.6A 01         push    1                              ; /Format = CF_TEXT
00401275|.E8 E4000000   call    <jmp.&USER32.GetClipboardData>   ; \GetClipboardData
0040127A|.0BC0          or      eax, eax
0040127C|.74 72         je      short 004012F0
0040127E|.A3 33324000   mov   dword ptr , eax
00401283|.60            pushad
00401284|.9C            pushfd
00401285|.BE 33324000   mov   esi, 00403233
0040128A|.8B36          mov   esi, dword ptr
0040128C|.FF35 3E334000 push    dword ptr
00401292|.8F05 42334000 pop   dword ptr                ;计算机名累加值出栈
00401298|.8B0D 46334000 mov   ecx, dword ptr           ;用户名位数
0040129E|>8A5431 FF   /mov   dl, byte ptr       ;从固定字符串的第六位开始倒着取
004012A2|.0FB6D2      |movzx   edx, dl
004012A5|.2915 42334000 |sub   dword ptr , edx         ;计算机名累加值-取得的ascii码值
004012AB|.49            |dec   ecx
004012AC|.^ 75 F0         \jnz   short 0040129E
004012AE|.9D            popfd
004012AF|.61            popad
004012B0|.A1 42334000   mov   eax, dword ptr           ;这里就是上面循环减后的值了
004012B5|.6BC0 FF       imul    eax, eax, -1                     ;eax×(-1)放到eax
004012B8|.83C0 01       add   eax, 1                           ;eax+1
004012BB|.6BC0 FF       imul    eax, eax, -1                     ;eax×(-1)放到eax。又乘以-1干嘛
004012BE|.83C0 01       add   eax, 1                           ;又+1。相当于没事在这里乱弄
004012C1|.0BC0          or      eax, eax                         ;跟到这里,发现计算机名的累加值减甚么东西能得到0能。当然就是减自己了
004012C3|.75 2B         jnz   short 004012F0                   ;所以,一定要复制计算机名到剪切板才能成功。
004012C5|.68 BB304000   push    004030BB                         ; /Step 1 ok -> now Register it!
004012CA|.6A 66         push    66                               ; |ControlID = 66 (102.)
004012CC|.FF75 08       push    dword ptr                 ; |hWnd
004012CF|.E8 AE000000   call    <jmp.&USER32.SetDlgItemTextA>    ; \SetDlgItemTextA
004012D4|.6A 00         push    0                              ; /Enable = FALSE
004012D6|.FF35 56334000 push    dword ptr                ; |hWnd = 001B0330 ('Check',class='Button',parent=00280320)
004012DC|.E8 71000000   call    <jmp.&USER32.EnableWindow>       ; \EnableWindow
004012E1|.6A 01         push    1                              ; /Enable = TRUE
004012E3|.FF35 5A334000 push    dword ptr                ; |hWnd = 002A03C2 ('-> Register <-',class='Button',parent=00280320)
004012E9|.E8 64000000   call    <jmp.&USER32.EnableWindow>       ; \EnableWindow
004012EE|.EB 0F         jmp   short 004012FF
004012F0|>68 F6304000   push    004030F6                         ; /Registration failed!!!
004012F5|.6A 66         push    66                               ; |ControlID = 66 (102.)
004012F7|.FF75 08       push    dword ptr                 ; |hWnd
004012FA|.E8 83000000   call    <jmp.&USER32.SetDlgItemTextA>    ; \SetDlgItemTextA
004012FF|>E8 42000000   call    <jmp.&USER32.CloseClipboard>   ; [CloseClipboard
00401304|>33C0          xor   eax, eax
00401306|.C9            leave
00401307\.C2 1000       retn    10




1、先假设我的计算机名是:BINBIN。

我在“reg.key”文件里输入的是:12345678

读取“reg.key”文件的算法是:读取前4位,倒过来取ascii码值的16进制字符串,得到:34333231;
                           再读取后5~8位,倒过来取ascii码值的16进制字符串,得到:38373635

两个数异或,得到0C040404。这个数和计算机名的ascii码累加值比较,如果相等就注册成功。“Good work. You have done it!”


2、所以,相对于我的计算机名:BINBIN。Ascii码累加值是01B2。甚么东西和甚么东西异或能得到01B2呢???

由于我的计算机名比较特殊经过我的测试,在“reg.key”文件里输入“2210
页: [1]
查看完整版本: Savage's Slayer's Crackme # 1算法分析