首页
社区
课程
招聘
[原创]一个名为CKGM1a的CrackMe算法分析
发表于: 2011-2-11 19:05 10000

[原创]一个名为CKGM1a的CrackMe算法分析

2011-2-11 19:05
10000

【文章标题】: 一个名为CKGM1a的CrackMe算法分析
【文章作者】: Root
【作者邮箱】: cppcoffee@gmail.com
【软件名称】: CKGM1a
【下载地址】: 附件
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  闲话一则: 由于在2010年末裸辞了,比较有多余的时间来充电了(其实鸭梨也挺大的).每天都会看下订阅的RSS,看到http://crackmes.de/更新了,随手就下载了一个CrackMe来分析.
  未加壳,嘿嘿.以下是分析过程:
  -------------------------->8------------------------------------------------------------
  00401682  /.  55            PUSH EBP                                      ;  对话框回调函数入口
  00401683  |.  89E5          MOV EBP,ESP
  00401685  |.  83EC 28       SUB ESP,0x28
  00401688  |.  895D F4       MOV DWORD PTR SS:[EBP-0xC],EBX
  0040168B  |.  8975 F8       MOV DWORD PTR SS:[EBP-0x8],ESI
  0040168E  |.  897D FC       MOV DWORD PTR SS:[EBP-0x4],EDI
  00401691  |.  8B7D 08       MOV EDI,DWORD PTR SS:[EBP+0x8]                ;  hWnd
  00401694  |.  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+0xC]                ;  uMsg
  00401697  |.  8B55 10       MOV EDX,DWORD PTR SS:[EBP+0x10]               ;  wParam
  0040169A  |.  3D 11010000   CMP EAX,0x111                                 ;  MSG == WM_COMMAND
  0040169F  |.  0F84 EF000000 JE CKGM1a.00401794                            ;  是WM_COMMAND消息则跳
  
  ..........................................................................;  中间省略一堆代码
  
  00401794  |>  83FA 01       CMP EDX,0x1                                   ;  wParam == IDOK
  00401797  |.  74 0E         JE SHORT CKGM1a.004017A7                      ;  跳转到Check Serial按钮点击
  00401799  |.  83FA 02       CMP EDX,0x2                                   ;  wParam == IDCANCEL
  0040179C  |.  0F84 25010000 JE CKGM1a.004018C7                            ;  跳转到结束对话框语句
  004017A2  |.  E9 3A010000   JMP CKGM1a.004018E1
  004017A7  |>  C74424 04 ED0>MOV DWORD PTR SS:[ESP+0x4],0x3ED              ; |Check Serial按钮点击处理
  004017AF  |.  893C24        MOV DWORD PTR SS:[ESP],EDI                    ; |
  004017B2  |.  E8 99080000   CALL <JMP.&USER32.GetDlgItem>                 ; \获取Serial Edit窗口句柄
  004017B7  |.  83EC 08       SUB ESP,0x8
  004017BA  |.  8945 F0       MOV DWORD PTR SS:[EBP-0x10],EAX               ; |
  004017BD  |.  890424        MOV DWORD PTR SS:[ESP],EAX                    ; |
  004017C0  |.  E8 9B080000   CALL <JMP.&USER32.GetWindowTextLengthA>       ; \获取输入的序列号长度
  004017C5  |.  83EC 04       SUB ESP,0x4
  004017C8  |.  85C0          TEST EAX,EAX                                  ; |输入的序列号长度是否0
  004017CA  |.  75 2D         JNZ SHORT CKGM1a.004017F9                     ; |序列号长度不为0则跳
  004017CC  |.  C74424 0C 100>MOV DWORD PTR SS:[ESP+0xC],0x10               ; |
  004017D4  |.  C74424 08 794>MOV DWORD PTR SS:[ESP+0x8],CKGM1a.00404079    ; |ASCII "Error"
  004017DC  |.  C74424 04 804>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.00404080    ; |ASCII "Please enter your serial number."
  004017E4  |.  893C24        MOV DWORD PTR SS:[ESP],EDI                    ; |
  004017E7  |.  E8 84080000   CALL <JMP.&USER32.MessageBoxA>                ; \MessageBoxA
  004017EC  |.  83EC 10       SUB ESP,0x10
  004017EF  |.  B8 FFFFFFFF   MOV EAX,-0x1
  004017F4  |.  E9 ED000000   JMP CKGM1a.004018E6
  004017F9  |>  83F8 63       CMP EAX,0x63                                  ; |序列号长度与100比较
  004017FC  |.  7E 2D         JLE SHORT CKGM1a.0040182B                     ; |小于等于100则跳
  004017FE  |.  C74424 0C 100>MOV DWORD PTR SS:[ESP+0xC],0x10               ; |
  00401806  |.  C74424 08 794>MOV DWORD PTR SS:[ESP+0x8],CKGM1a.00404079    ; |ASCII "Error"
  0040180E  |.  C74424 04 A14>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.004040A1    ; |ASCII "Serial is too long..."
  00401816  |.  893C24        MOV DWORD PTR SS:[ESP],EDI                    ; |
  00401819  |.  E8 52080000   CALL <JMP.&USER32.MessageBoxA>                ; \MessageBoxA
  0040181E  |.  83EC 10       SUB ESP,0x10
  00401821  |.  B8 FFFFFFFF   MOV EAX,-0x1
  00401826  |.  E9 BB000000   JMP CKGM1a.004018E6
  0040182B  |>  8D70 01       LEA ESI,DWORD PTR DS:[EAX+0x1]                ; |||ESI = 序列号长度增加1,以存放'0'结尾的字符串
  0040182E  |.  893424        MOV DWORD PTR SS:[ESP],ESI                    ; |||
  00401831  |.  E8 6A070000   CALL <JMP.&msvcrt.malloc>                     ; ||\分配指定的长度
  00401836  |.  89C3          MOV EBX,EAX                                   ; ||
  00401838  |.  897424 08     MOV DWORD PTR SS:[ESP+0x8],ESI                ; ||
  0040183C  |.  C74424 04 000>MOV DWORD PTR SS:[ESP+0x4],0x0                ; ||
  00401844  |.  890424        MOV DWORD PTR SS:[ESP],EAX                    ; ||
  00401847  |.  E8 44070000   CALL <JMP.&msvcrt.memset>                     ; |\将分配的内存全部置0
  0040184C  |.  C74424 08 640>MOV DWORD PTR SS:[ESP+0x8],0x64               ; |
  00401854  |.  895C24 04     MOV DWORD PTR SS:[ESP+0x4],EBX                ; |
  00401858  |.  8B45 F0       MOV EAX,DWORD PTR SS:[EBP-0x10]               ; |
  0040185B  |.  890424        MOV DWORD PTR SS:[ESP],EAX                    ; |
  0040185E  |.  E8 1D080000   CALL <JMP.&USER32.GetWindowTextA>             ; \获取序列号长度,存放到刚才分配的内存空间中
  00401863  |.  83EC 0C       SUB ESP,0xC
  00401866  |.  891C24        MOV DWORD PTR SS:[ESP],EBX                    ;  将序列号内存地址存入堆栈
  00401869  |.  E8 C4FAFFFF   CALL <CKGM1a.IsValidSerial>                   ;  是否有效的序列号(见下面分析)
  0040186E  |.  83F8 FF       CMP EAX,-0x1                                  ; |根据返回值判断是否有效的序列号
  00401871  |.  75 2A         JNZ SHORT CKGM1a.0040189D                     ; |
  00401873  |.  C74424 0C 100>MOV DWORD PTR SS:[ESP+0xC],0x10               ; |无效序列号弹窗
  0040187B  |.  C74424 08 794>MOV DWORD PTR SS:[ESP+0x8],CKGM1a.00404079    ; |ASCII "Error"
  00401883  |.  C74424 04 B74>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.004040B7    ; |ASCII "Invalid serial number."
  0040188B  |.  893C24        MOV DWORD PTR SS:[ESP],EDI                    ; |
  0040188E  |.  E8 DD070000   CALL <JMP.&USER32.MessageBoxA>                ; \MessageBoxA
  00401893  |.  83EC 10       SUB ESP,0x10
  00401896  |.  B8 FFFFFFFF   MOV EAX,-0x1
  0040189B  |.  EB 49         JMP SHORT CKGM1a.004018E6
  0040189D  |>  C74424 0C 300>MOV DWORD PTR SS:[ESP+0xC],0x30               ; |正确序列号弹窗
  004018A5  |.  C74424 08 CE4>MOV DWORD PTR SS:[ESP+0x8],CKGM1a.004040CE    ; |ASCII "Congratulation!"
  004018AD  |.  C74424 04 E04>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.004040E0    ; |ASCII "You have found a valid serial!"
  004018B5  |.  893C24        MOV DWORD PTR SS:[ESP],EDI                    ; |
  004018B8  |.  E8 B3070000   CALL <JMP.&USER32.MessageBoxA>                ; \MessageBoxA
  004018BD  |.  83EC 10       SUB ESP,0x10
  004018C0  |.  B8 FFFFFFFF   MOV EAX,-0x1
  004018C5  |.  EB 1F         JMP SHORT CKGM1a.004018E6
  004018C7  |>  C74424 04 000>MOV DWORD PTR SS:[ESP+0x4],0x0                ; |IDCANCEL按钮处理(Quit)
  004018CF  |.  893C24        MOV DWORD PTR SS:[ESP],EDI                    ; |hDlgWnd
  004018D2  |.  E8 B9070000   CALL <JMP.&USER32.EndDialog>                  ; \EndDialog
  004018D7  |.  83EC 08       SUB ESP,0x8
  004018DA  |.  B8 00000000   MOV EAX,0x0                                   ;  return 0
  004018DF  |.  EB 05         JMP SHORT CKGM1a.004018E6
  004018E1  |>  B8 00000000   MOV EAX,0x0
  004018E6  |>  8B5D F4       MOV EBX,DWORD PTR SS:[EBP-0xC]
  004018E9  |.  8B75 F8       MOV ESI,DWORD PTR SS:[EBP-0x8]
  004018EC  |.  8B7D FC       MOV EDI,DWORD PTR SS:[EBP-0x4]
  004018EF  |.  89EC          MOV ESP,EBP
  004018F1  |.  5D            POP EBP
  004018F2  \.  C2 1000       RETN 0x10
  
  -------------------------->8------------------------------------------------------------
  
  ; IsValidSerial 函数(是否有效的序列号)
  <CKGM1a.I>/$  55            PUSH EBP                                 ;  序列号是否有效,函数入口点
  00401333  |.  89E5          MOV EBP,ESP
  00401335  |.  57            PUSH EDI
  00401336  |.  56            PUSH ESI
  00401337  |.  53            PUSH EBX
  00401338  |.  83EC 7C       SUB ESP,0x7C
  0040133B  |.  8B5D 08       MOV EBX,DWORD PTR SS:[EBP+0x8]           ; |EBX = 输入的序列号
  0040133E  |.  66:C745 D8 00>MOV WORD PTR SS:[EBP-0x28],0x0           ; |
  00401344  |.  C645 DA 00    MOV BYTE PTR SS:[EBP-0x26],0x0           ; |
  00401348  |.  8D7D A8       LEA EDI,DWORD PTR SS:[EBP-0x58]          ; |SS:[EBP-0x58] = 输入的序列号
  0040134B  |.  FC            CLD                                      ; |
  0040134C  |.  B9 08000000   MOV ECX,0x8                              ; |
  00401351  |.  B8 00000000   MOV EAX,0x0                              ; |
  00401356  |.  F3:AB         REP STOS DWORD PTR ES:[EDI]              ; |清空SS:[EBP-0x58]的内容
  00401358  |.  C607 00       MOV BYTE PTR DS:[EDI],0x0                ; |
  0040135B  |.  89DF          MOV EDI,EBX                              ; |EDI = 输入的序列号
  0040135D  |.  B9 FFFFFFFF   MOV ECX,-0x1                             ; |
  00401362  |.  F2:AE         REPNE SCAS BYTE PTR ES:[EDI]             ; |计算输入序列号的长度
  00401364  |.  BA FFFFFFFF   MOV EDX,-0x1                             ; |
  00401369  |.  83F9 D3       CMP ECX,-0x2D                            ; |输入序列号长度是否是45个
  0040136C  |.  0F85 0C020000 JNZ CKGM1a.0040157E                      ; |如果不是44个字符,则结束
  00401372  |.  8D55 A8       LEA EDX,DWORD PTR SS:[EBP-0x58]          ; |
  00401375  |.  8D45 C0       LEA EAX,DWORD PTR SS:[EBP-0x40]          ; |
  00401378  |.  894424 18     MOV DWORD PTR SS:[ESP+0x18],EAX          ; |存放第五组序列号的缓冲区(长度8)
  0040137C  |.  8D45 B8       LEA EAX,DWORD PTR SS:[EBP-0x48]          ; |
  0040137F  |.  894424 14     MOV DWORD PTR SS:[ESP+0x14],EAX          ; |存放第四组序列号的缓冲区(长度8)
  00401383  |.  8D45 B0       LEA EAX,DWORD PTR SS:[EBP-0x50]          ; |
  00401386  |.  894424 10     MOV DWORD PTR SS:[ESP+0x10],EAX          ; |存放第三组序列号的缓冲区(长度8)
  0040138A  |.  895424 0C     MOV DWORD PTR SS:[ESP+0xC],EDX           ; |存放第二组序列号的缓冲区(长度8)
  0040138E  |.  8D45 D8       LEA EAX,DWORD PTR SS:[EBP-0x28]          ; |
  00401391  |.  894424 08     MOV DWORD PTR SS:[ESP+0x8],EAX           ; |存放第一组序列号的缓冲区(长度4)
  00401395  |.  C74424 04 004>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.004040>; |ASCII "CKGM1%2s-%8s-%8s-%8s-%8s"
  0040139D  |.  891C24        MOV DWORD PTR SS:[ESP],EBX               ; |
  004013A0  |.  E8 0B0C0000   CALL <JMP.&msvcrt.sscanf>                ; \进行sscanf格式化
  004013A5  |.  BA FFFFFFFF   MOV EDX,-0x1
  004013AA  |.  83F8 05       CMP EAX,0x5                              ;  格式化是否完成
  004013AD  |.  0F85 CB010000 JNZ CKGM1a.0040157E                      ;  没有完成则Over
  004013B3  |.  C74424 04 A43>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.004032>;  特征码字符串1: ACEGIKMOQSUWY(参数2)
  004013BB  |.  0FBE45 D8     MOVSX EAX,BYTE PTR SS:[EBP-0x28]         ;  第一组序列号的第一个字符
  004013BF  |.  890424        MOV DWORD PTR SS:[ESP],EAX
  004013C2  |.  E8 8F020000   CALL <CKGM1a.IsCharacter>                ;  字符是否在特征码中
  {
    ; IsCharacter函数
    <CKGM1a.I>/$  55            PUSH EBP                                 ;  函数功能: 字符是否在特征码中
    00401657  |.  89E5          MOV EBP,ESP
    00401659  |.  53            PUSH EBX
    0040165A  |.  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+0xC]           ;  特征码字符串地址
    0040165D  |.  0FB64D 08     MOVZX ECX,BYTE PTR SS:[EBP+0x8]          ;  所请求的字符
    00401661  |.  BB FFFFFFFF   MOV EBX,-0x1                             ;  EBX: 存放返回值
    00401666  |.  BA 00000000   MOV EDX,0x0                              ;  置计数器0
    0040166B  |>  380C02        /CMP BYTE PTR DS:[EDX+EAX],CL            ;  字符与特征码进行比较
    0040166E  |.  75 07         |JNZ SHORT CKGM1a.00401677               ;  不相等则跳
    00401670  |.  BB 00000000   |MOV EBX,0x0                             ;  置有效的返回值
    00401675  |.  EB 06         |JMP SHORT CKGM1a.0040167D
    00401677  |>  42            |INC EDX                                 ;  计数器增1(下一个特征码的位置)
    00401678  |.  83FA 0C       |CMP EDX,0xC                             ;  结束条件(特征码是否循环结束)
    0040167B  |.^ 7E EE         \JLE SHORT CKGM1a.0040166B
    0040167D  |>  89D8          MOV EAX,EBX                              ;  将保存的返回值给EAX
    0040167F  |.  5B            POP EBX
    00401680  |.  5D            POP EBP
    00401681  \.  C3            RETN
  }
  004013C7  |.  BA FFFFFFFF   MOV EDX,-0x1
  004013CC  |.  83F8 FF       CMP EAX,-0x1
  004013CF  |.  0F84 A9010000 JE CKGM1a.0040157E                       ;  不在特征码中则Over
  004013D5  |.  C74424 04 B23>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.004032>;  特征码字符串2: BDFHYLNPRTVXZ
  004013DD  |.  0FBE45 D9     MOVSX EAX,BYTE PTR SS:[EBP-0x27]         ;  第一组序列号的第二个字符
  004013E1  |.  890424        MOV DWORD PTR SS:[ESP],EAX
  004013E4  |.  E8 6D020000   CALL <CKGM1a.IsCharacter>                ;  字符是否在特征码中(具体实现见上面的函数)
  004013E9  |.  BA FFFFFFFF   MOV EDX,-0x1
  004013EE  |.  83F8 FF       CMP EAX,-0x1
  004013F1  |.  0F84 87010000 JE CKGM1a.0040157E                       ;  不在特征码中则Over
  004013F7  |. /EB 1E         JMP SHORT CKGM1a.00401417
  004013F9  |> |BA FFFFFFFF   MOV EDX,-0x1
  004013FE  |. |E9 7B010000   JMP CKGM1a.0040157E
  00401403  |> |BA FFFFFFFF   MOV EDX,-0x1
  00401408  |. |E9 71010000   JMP CKGM1a.0040157E
  0040140D  |> |BA FFFFFFFF   MOV EDX,-0x1
  00401412  |. |E9 67010000   JMP CKGM1a.0040157E
  00401417  |> \C74424 04 A43>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.004032>;  特征码字符串1: ACEGIKMOQSUWY
  0040141F  |.  0FBE45 D8     MOVSX EAX,BYTE PTR SS:[EBP-0x28]         ;  第一组序列号的第一个字符
  00401423  |.  890424        MOV DWORD PTR SS:[ESP],EAX
  00401426  |.  E8 0F020000   CALL <CKGM1a.GetCharacterPos>            ;  获取字符在特征码中的位置
  {
    ; GetCharacterPos函数
    <CKGM1a.G>/$  55            PUSH EBP                                 ;  函数功能: 获取字符在特征码中的位置
    0040163B  |.  89E5          MOV EBP,ESP
    0040163D  |.  8B4D 0C       MOV ECX,DWORD PTR SS:[EBP+0xC]           ;  特征码参数地址
    00401640  |.  0FB655 08     MOVZX EDX,BYTE PTR SS:[EBP+0x8]          ;  要查找的字符
    00401644  |.  B8 00000000   MOV EAX,0x0                              ;  置计数器
    00401649  |>  381408        /CMP BYTE PTR DS:[EAX+ECX],DL            ;  字符与指定特征码进行比较
    0040164C  |.  74 06         |JE SHORT CKGM1a.00401654                ;  相等则跳
    0040164E  |.  40            |INC EAX                                 ;  增加计数器
    0040164F  |.  83F8 0C       |CMP EAX,0xC                             ;  结束条件
    00401652  |.^ 7E F5         \JLE SHORT CKGM1a.00401649
    00401654  |>  5D            POP EBP
    00401655  \.  C3            RETN
  }
  0040142B  |.  89C2          MOV EDX,EAX                              ;  EDX = 字符在特征码的位置
  0040142D  |.  BF 00000000   MOV EDI,0x0                              ;  计数器 i = 0
  00401432  |>  0FB682 A43240>/MOVZX EAX,BYTE PTR DS:[EDX+0x4032A4]    ;  EAX = 当前位置的特征码
  00401439  |.  8887 18504000 |MOV BYTE PTR DS:[EDI+0x405018],AL       ;  保存特征码数组1
  0040143F  |.  42            |INC EDX                                 ;  位置增加1
  00401440  |.  83FA 0D       |CMP EDX,0xD                             ;  确定位置不超出范围
  00401443  |.  0F95C0        |SETNE AL                                ;  根据Z标志位设置al的值
  00401446  |.  0FB6C0        |MOVZX EAX,AL
  00401449  |.  F7D8          |NEG EAX                                 ;  对EAX取反
  0040144B  |.  21C2          |AND EDX,EAX
  0040144D  |.  47            |INC EDI                                 ;  i++
  0040144E  |.  83FF 0C       |CMP EDI,0xC                             ;  i与12进行比较
  00401451  |.^ 7E DF         \JLE SHORT CKGM1a.00401432
  00401453  |.  C74424 04 B23>MOV DWORD PTR SS:[ESP+0x4],CKGM1a.004032>;  特征码2: BDFHYLNPRTVXZ
  0040145B  |.  0FBE45 D9     MOVSX EAX,BYTE PTR SS:[EBP-0x27]         ;  第一组注册码第二个字符
  0040145F  |.  890424        MOV DWORD PTR SS:[ESP],EAX
  00401462  |.  E8 D3010000   CALL <CKGM1a.GetCharacterPos>            ;  获取字符在特征码的位置(具体实现见上面的函数)
  00401467  |.  89C2          MOV EDX,EAX
  00401469  |.  BF 00000000   MOV EDI,0x0                              ;  i = 0
  0040146E  |>  0FB682 B23240>/MOVZX EAX,BYTE PTR DS:[EDX+0x4032B2]    ;  EAX = 当前位置的特征码
  00401475  |.  8887 26504000 |MOV BYTE PTR DS:[EDI+0x405026],AL       ;  保存到特征码数组2
  0040147B  |.  42            |INC EDX                                 ;  位置增加1
  0040147C  |.  83FA 0D       |CMP EDX,0xD                             ;  确定位置不超出范围
  0040147F  |.  0F95C0        |SETNE AL                                ;  根据Z标志位设置al值
  00401482  |.  0FB6C0        |MOVZX EAX,AL
  00401485  |.  F7D8          |NEG EAX                                 ;  对EAX取反
  00401487  |.  21C2          |AND EDX,EAX
  00401489  |.  47            |INC EDI                                 ;  i++
  0040148A  |.  83FF 0C       |CMP EDI,0xC                             ;  i与12进行比较
  0040148D  |.^ 7E DF         \JLE SHORT CKGM1a.0040146E
  0040148F  |.  8D7D A8       LEA EDI,DWORD PTR SS:[EBP-0x58]          ;  EDI = 第2,3,4,5组序列号起始地址
  00401492  |.  FC            CLD
  00401493  |.  B9 FFFFFFFF   MOV ECX,-0x1
  00401498  |.  B0 00         MOV AL,0x0
  0040149A  |.  F2:AE         REPNE SCAS BYTE PTR ES:[EDI]
  0040149C  |.  F7D1          NOT ECX
  0040149E  |.  8D59 FF       LEA EBX,DWORD PTR DS:[ECX-0x1]           ;  以上代码是计算2,3,4,5组序列号的字符长度
  004014A1  |.  BF 00000000   MOV EDI,0x0                              ;  i = 0
  004014A6  |.  39DF          CMP EDI,EBX                              ;  长度是否为0
  004014A8  |.  7D 42         JGE SHORT CKGM1a.004014EC                ;  跳转到长度为0的处理
  004014AA  |> /F7C7 01000000 /TEST EDI,0x1                            ;  i整除2是否为0
  004014B0  |. |74 17         |JE SHORT CKGM1a.004014C9                ;  结果为0则跳
  004014B2  |. |C74424 04 265>|MOV DWORD PTR SS:[ESP+0x4],CKGM1a.00405>;  ASCII "ZBDFHYLNPRTVX"
  004014BA  |. |0FBE442F A8   |MOVSX EAX,BYTE PTR DS:[EDI+EBP-0x58]    ;  EDI指定的序列号字符位置
  004014BF  |. |890424        |MOV DWORD PTR SS:[ESP],EAX
  004014C2  |. |E8 8F010000   |CALL <CKGM1a.IsCharacter>               ;  字符是否在序列号中
  004014C7  |. |EB 15         |JMP SHORT CKGM1a.004014DE
  004014C9  |> |C74424 04 185>|MOV DWORD PTR SS:[ESP+0x4],CKGM1a.00405>;  ASCII "YACEGIKMOQSUW"
  004014D1  |. |0FBE442F A8   |MOVSX EAX,BYTE PTR DS:[EDI+EBP-0x58]    ;  EDI指定的序列号字符位置
  004014D6  |. |890424        |MOV DWORD PTR SS:[ESP],EAX
  004014D9  |. |E8 78010000   |CALL <CKGM1a.IsCharacter>               ;  序列号的字符是否在特征码中
  004014DE  |> |83F8 FF       |CMP EAX,-0x1
  004014E1  |.^|0F84 12FFFFFF |JE CKGM1a.004013F9                      ;  不再特征码中则Over
  004014E7  |. |47            |INC EDI                                 ;  i++
  004014E8  |. |39DF          |CMP EDI,EBX                             ;  序列号长度与i进行比较(保证不超出范围)
  004014EA  |.^\7C BE         \JL SHORT CKGM1a.004014AA
  004014EC  |>  C745 A4 FFFFF>MOV DWORD PTR SS:[EBP-0x5C],-0x1         ;  用来保存位置1变量,初始化操作
  004014F3  |.  C745 A0 FFFFF>MOV DWORD PTR SS:[EBP-0x60],-0x1         ;  用来保存位置2变量,初始化操作
  004014FA  |.  BF 00000000   MOV EDI,0x0                              ;  重置循环次数
  004014FF  |> /0FBE447D A8   /MOVSX EAX,BYTE PTR SS:[EBP+EDI*2-0x58]       ;  EAX = EDI指定的序列号组合位置字符
  00401504  |. |0FBE5C7D A9   |MOVSX EBX,BYTE PTR SS:[EBP+EDI*2-0x57]       ;  EBX = EDI指定的序列号组合位置的后一个字符
  00401509  |.  C74424 04 185>|MOV DWORD PTR SS:[ESP+0x4],CKGM1a.00405018     ;  重组后的特征码1
  00401511  |.  890424        |MOV DWORD PTR SS:[ESP],EAX
  00401514  |.  E8 21010000   |CALL <CKGM1a.GetCharacterPos>                  ;  得到字符在特征码中的位置
  00401519  |.  89C6          |MOV ESI,EAX                                    ;  保存到ESI中
  0040151B  |.  C74424 04 265>|MOV DWORD PTR SS:[ESP+0x4],CKGM1a.00405026     ;  重组后的特征码2
  00401523  |. |891C24        |MOV DWORD PTR SS:[ESP],EBX
  00401526  |. |E8 0F010000   |CALL <CKGM1a.GetCharacterPos>                ;  得到字符在特征码的位置
  0040152B  |. |89C3          |MOV EBX,EAX                                  ;  保存到EBX中
  0040152D  |.  C74424 08 003>|MOV DWORD PTR SS:[ESP+0x8],CKGM1a.00403000   ;  注意这个地址
  -------------------------->8------------------------------------------------------------
  
  去这个地址看看 db 403000:
  00403000  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403010  01 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00  .............
  00403020  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403030  01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  .............
  00403040  00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  .............
  00403050  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
  00403060  01 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00  .............
  00403070  01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  .............
  00403080  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403090  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  004030A0  01 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ..............
  004030B0  01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  .............
  004030C0  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  004030D0  01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00  ..............
  004030E0  01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00  ..............
  004030F0  00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  .............
  00403100  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403110  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403120  00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00  ..............
  00403130  00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00  ..............
  00403140  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403150  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403160  01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ...............
  00403170  01 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00  .............
  00403180  01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00  ..............
  00403190  00 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  .............
  004031A0  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  004031B0  00 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00  ..............
  004031C0  01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  .............
  004031D0  01 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00  .............
  004031E0  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  004031F0  01 00 00 00 00 00 00 00 01 00 00 00 01 00 00 00  .............
  00403200  01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  .............
  00403210  01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ...............
  00403220  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403230  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403240  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403250  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403260  00 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  ..............
  00403270  01 00 00 00 01 00 00 00 01 00 00 00 01 00 00 00  ............
  00403280  01 00 00 00 01 00 00 00 01 00 00 00 00 00 00 00  .............
  00403290  00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00  ...............
  004032A0  01 00 00 00                                      ...
  
  Alt+M打开内存映射窗口,看下地址的信息:
  Memory map, 条目 15
   地址=00403000
   大小=00001000 (4096.)
   属主=CKGM1a   00400000
   区段=.data
   包含=数据
   类型=Imag 01001002
   访问=R
   初始访问=RWE
  
  根据上面的数据,得知403000是一个常量数组的地址.
  处理后的数据(4字节长度):
  1111101111111110011100001101111011111111100111101111110010100111111111110011001111111111100010111100011111110011111011011111101111101000111111111111111101101111111000011
  
  目前还不知道它是干什么的,只能继续看代码:
  
  -------------------------->8------------------------------------------------------------
  00401535  |.  894424 04     |MOV DWORD PTR SS:[ESP+0x4],EAX               ;  EAX = 特征码位置1
  00401539  |.  893424        |MOV DWORD PTR SS:[ESP],ESI                   ;  ESI = 特征码位置2
  0040153C  |.  E8 D9000000   |CALL <CKGM1a.IsValidPosValue>                ;  是否有效的位置
  {
    ; IsValidPosValue函数
    <CKGM1a.I>/$  55            PUSH EBP                                      ;  IsValidPosValue函数入口点
    0040161B  |.  89E5          MOV EBP,ESP
    0040161D  |.  8B45 0C       MOV EAX,DWORD PTR SS:[EBP+0xC]
    00401620  |.  8D1440        LEA EDX,DWORD PTR DS:[EAX+EAX*2]              ;  nCount = nPos2 + nPos2 * 2
    00401623  |.  8D1490        LEA EDX,DWORD PTR DS:[EAX+EDX*4]              ;  nCount = nPos2 + nCount * 4
    00401626  |.  0355 08       ADD EDX,DWORD PTR SS:[EBP+0x8]                ;  nCount += nPos1
    00401629  |.  8B45 10       MOV EAX,DWORD PTR SS:[EBP+0x10]
    0040162C  |.  833C90 01     CMP DWORD PTR DS:[EAX+EDX*4],0x1              ;  pdwPosArray[nCount] == 1 ??
    00401630  |.  0F94C0        SETE AL                                       ;  相等则置1
    00401633  |.  0FB6C0        MOVZX EAX,AL                                  ;  扩展到EAX
    00401636  |.  48            DEC EAX                                       ;  将结果减1
    00401637  |.  5D            POP EBP
    00401638  \.  C3            RETN
  }
  
  额,分析得知原来是进行特征码位置计算后的值在全局数组中的数据是否为1
  
  00401541  |.  83F8 FF       |CMP EAX,-0x1
  00401544  |.^ 0F84 B9FEFFFF |JE CKGM1a.00401403                           ;  无效的位置值,则Over
  0040154A  |.  895C24 0C     |MOV DWORD PTR SS:[ESP+0xC],EBX               ;  第二个字符的特征码位置
  0040154E  |.  897424 08     |MOV DWORD PTR SS:[ESP+0x8],ESI               ;  第一个字符的特征码位置
  00401552  |.  8B45 A0       |MOV EAX,DWORD PTR SS:[EBP-0x60]              ;  用来保存位置的变量2
  00401555  |.  894424 04     |MOV DWORD PTR SS:[ESP+0x4],EAX
  00401559  |.  8B45 A4       |MOV EAX,DWORD PTR SS:[EBP-0x5C]              ;  用来保存位置的变量1
  0040155C  |.  890424        |MOV DWORD PTR SS:[ESP],EAX
  0040155F  |.  E8 24000000   |CALL <CKGM1a.IsValidCalcValue>               ;  计算值是否有效
  {
    ; IsValidCalcValue 用来计算值是否有效
    <CKGM1a.I>/$  55            PUSH EBP                                      ;  用来计算值是否有效的入口点
    00401589  |.  89E5          MOV EBP,ESP
    0040158B  |.  83EC 0C       SUB ESP,0xC
    0040158E  |.  891C24        MOV DWORD PTR SS:[ESP],EBX
    00401591  |.  897424 04     MOV DWORD PTR SS:[ESP+0x4],ESI
    00401595  |.  897C24 08     MOV DWORD PTR SS:[ESP+0x8],EDI                ;  以上是保存寄存器的操作(用于堆栈使用)
    00401599  |.  8B5D 08       MOV EBX,DWORD PTR SS:[EBP+0x8]                ;  参数1 --- 保存位置1的值
    0040159C  |.  8B7D 0C       MOV EDI,DWORD PTR SS:[EBP+0xC]                ;  参数2 --- 保存位置2的值
    0040159F  |.  8B75 10       MOV ESI,DWORD PTR SS:[EBP+0x10]               ;  参数3 --- 位置1的值
    004015A2  |.  83FB FF       CMP EBX,-0x1                                  ;  nSavePos1 == -1
    004015A5  |.  0F94C2        SETE DL                                       ;  如果nSavePos1的值是-1,置dl为1
    004015A8  |.  85F6          TEST ESI,ESI                                  ;  nPos1 > 0
    004015AA  |.  0F9FC0        SETG AL                                       ;  nPos1大于0,则值al为1
    004015AD  |.  B9 FFFFFFFF   MOV ECX,-0x1
    004015B2  |.  84D0          TEST AL,DL                                    ;  两个结果必须有效
    004015B4  |.  75 52         JNZ SHORT CKGM1a.00401608                     ;  无效则Over
    004015B6  |.  83FB 0C       CMP EBX,0xC
    004015B9  |.  74 4D         JE SHORT CKGM1a.00401608                      ;  nSavePos1如果等于12,则Over
    004015BB  |.  89D8          MOV EAX,EBX
    004015BD  |.  F7D0          NOT EAX                                       ;  ~nSavePos1 取反操作
    004015BF  |.  C1E8 1F       SHR EAX,0x1F                                  ;  nSavePos1 >> 31
    004015C2  |.  89FA          MOV EDX,EDI
    004015C4  |.  F7D2          NOT EDX                                       ;  ~nSavePos2 取反操作
    004015C6  |.  C1EA 1F       SHR EDX,0x1F                                  ;  nSavePos2 >> 31
    004015C9  |.  20D0          AND AL,DL                                     ;  nSavePos1 & nSavePos2
    004015CB  |.  B9 00000000   MOV ECX,0x0
    004015D0  |.  84C0          TEST AL,AL                                    ;  两个值相与的结果是否为0
    004015D2  |.  74 34         JE SHORT CKGM1a.00401608                      ;  如果两个值的高位不为1,则Over
    004015D4  |.  39F3          CMP EBX,ESI                                   ;  nSavePos2与nPos1比较
    004015D6  |.  75 14         JNZ SHORT CKGM1a.004015EC                     ;  跳转到不等的处理位置
    004015D8  |.  8B45 14       MOV EAX,DWORD PTR SS:[EBP+0x14]
    004015DB  |.  48            DEC EAX                                       ;  nPos2 - 1
    004015DC  |.  39F8          CMP EAX,EDI                                   ;  nPos2 - 1的结果与nSavePos2进行比较
    004015DE  |.  74 28         JE SHORT CKGM1a.00401608                      ;  相等则Over
    004015E0  |.  39F3          CMP EBX,ESI                                   ;  nSavePos1与nPos1比较
    004015E2  |.  75 08         JNZ SHORT CKGM1a.004015EC                     ;  不等,则跳
    004015E4  |.  8B45 14       MOV EAX,DWORD PTR SS:[EBP+0x14]               ;  EAX = nPos2
    004015E7  |.  40            INC EAX                                       ;  nPos2 + 1
    004015E8  |.  39F8          CMP EAX,EDI                                   ;  nPos2+1后的结果与nSavePos2进行比较
    004015EA  |.  74 1C         JE SHORT CKGM1a.00401608                      ;  相等则Over
    004015EC  |>  8D46 FF       LEA EAX,DWORD PTR DS:[ESI-0x1]                ;  EAX = nPos1 - 1
    004015EF  |.  39D8          CMP EAX,EBX                                   ;  nPos1-1的结果与nSavePos1进行比较
    004015F1  |.  0F94C2        SETE DL                                       ;  相等则置DL为1
    004015F4  |.  3B7D 14       CMP EDI,DWORD PTR SS:[EBP+0x14]               ;  nSavePos2与nPos2进行比较
    004015F7  |.  0F94C0        SETE AL                                       ;  相等则置al为1
    004015FA  |.  B9 00000000   MOV ECX,0x0                                   ;  ECX = 临时返回值
    004015FF  |.  84D0          TEST AL,DL                                    ;  两结果进行与操作
    00401601  |.  75 05         JNZ SHORT CKGM1a.00401608
    00401603  |.  B9 FFFFFFFF   MOV ECX,-0x1
    00401608  |>  89C8          MOV EAX,ECX                                   ;  EAX = 临时的返回值
    0040160A  |.  8B1C24        MOV EBX,DWORD PTR SS:[ESP]                    ;  以下操作是平衡堆栈前,寄存器的还原操作
    0040160D  |.  8B7424 04     MOV ESI,DWORD PTR SS:[ESP+0x4]
    00401611  |.  8B7C24 08     MOV EDI,DWORD PTR SS:[ESP+0x8]
    00401615  |.  89EC          MOV ESP,EBP
    00401617  |.  5D            POP EBP
    00401618  \.  C3            RETN
  }
  00401564  |.  83F8 FF       |CMP EAX,-0x1                                 ;  返回值是否有效
  00401567  |.^ 0F84 A0FEFFFF |JE CKGM1a.0040140D                           ;  无效则Over
  0040156D  |.  8975 A4       |MOV DWORD PTR SS:[EBP-0x5C],ESI              ;  保存位置1
  00401570  |.  895D A0       |MOV DWORD PTR SS:[EBP-0x60],EBX              ;  保存位置2
  00401573  |.  47            |INC EDI                                      ;  增加循环次数计数
  00401574  |.  83FF 0F       |CMP EDI,0xF                                  ;  循环必须高于15次
  00401577  |.^ 7E 86         \JLE SHORT CKGM1a.004014FF
  00401579  |.  BA 00000000   MOV EDX,0x0                                   ;  EDX存放序列号正确的标志位
  0040157E  |>  89D0          MOV EAX,EDX                                   ;  EDX做返回值
  00401580  |.  83C4 7C       ADD ESP,0x7C
  00401583  |.  5B            POP EBX
  00401584  |.  5E            POP ESI
  00401585  |.  5F            POP EDI
  00401586  |.  5D            POP EBP
  00401587  \.  C3            RETN
  -------------------------->8------------------------------------------------------------
  
  到此,注册算法已经分析完毕了.
  由于鄙人功力不够,注册机还没能力写出来.楼下哪位兄台能帮个忙,写出注册机,万分感谢.
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2011年02月11日 19:01:47


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (13)
雪    币: 108
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
好长。。。慢慢看
2011-2-11 20:57
0
雪    币: 428
活跃值: (293)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
不错,顶个!
2011-2-11 21:04
0
雪    币: 108
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
很详细。。不过不懂sscanf函数,可以讲下吗
2011-2-11 21:37
0
雪    币: 248
活跃值: (188)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
5
sscanf MSDN: Read formatted data from a string.
2011-2-12 09:27
0
雪    币: 192
活跃值: (70)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
楼主功力渐增啊
2011-2-12 09:39
0
雪    币: 2194
活跃值: (1001)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
IsValidCalcValue的过程有点复杂
写注册机有点难度
2011-2-12 14:06
0
雪    币: 248
活跃值: (188)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
8
在跟踪的时候,被这个IsValidCalcValue给混淆了好久....
还必须努力修行.谢谢大伙的支持
2011-2-12 15:19
0
雪    币: 783
活跃值: (586)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
不错,学习一下
2011-2-12 16:38
0
雪    币: 108
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
2011-2-12 18:10
0
雪    币: 248
活跃值: (188)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
11
自己顶一下
2011-2-14 10:24
0
雪    币: 20
活跃值: (99)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
学习下~~~~~~
2011-10-21 14:36
0
雪    币: 34
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
下来看看 谢谢
2011-10-21 16:03
0
雪    币: 278
活跃值: (709)
能力值: ( LV15,RANK:520 )
在线值:
发帖
回帖
粉丝
14
好复杂
2011-11-11 13:11
0
游客
登录 | 注册 方可回帖
返回
//