飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

12
返回列表 发新帖
楼主: jzyjd

[原创] 上次发错了,这个才是不明码比较的。高手飘过。

[复制链接]
  • TA的每日心情
    开心
    3 天前
  • 签到天数: 1260 天

    [LV.10]以坛为家III

    发表于 2009-3-4 20:05:29 | 显示全部楼层
    上几楼的高手真厉害啊 学习了 呵呵
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-5-7 09:43
  • 签到天数: 28 天

    [LV.4]偶尔看看III

     楼主| 发表于 2009-3-10 23:10:34 | 显示全部楼层
    答案:
    破文标题】 CrackMe之chap203 破解分析

    【使用工具】 peid,olldbg

    【破解平台】 Win2000/XP

    【软件名称】 chap203

    【软件大小】 12KB

    【编程语言】 MASM32/TASM32

    【软件简介】 加密和解密第一版第二章第三个CrackMe。

    【破解目的】 从头学起,打好基础。


    【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)

    ------------------------------------------------------------

    首先 Peid 检测程序编程语言是MASM32 / TASM32,运行程序。

    没输入或错误注册码提示

    "Your registration info is invalid... Note that most of the special chars may raise registration problems!"
    这次W32Dasm败下阵来了,看不到任何字符参考。
    这次OD直接披挂上阵。
    载入程序,点右键-搜索-字符参考。

    004010E1   push chap203.00402061                     ASCII "Congratulations! Please send your keygen (working one) to [email protected]!"

    00401224   push chap203.004020AE                     ASCII "Your registration info is invalid... Note that most of the special chars may raise registration problems!"  

    //先双击00401224 到失败处代码段看看。

    这两句让我们感兴趣。

    0040121A   > \68 00200000   push 2000  //这句有个>箭头表示从某处跳转过来,根据OD的红线向上找。

    0040121F   .  68 01204000   push chap203.00402001                    ; |Title = "Duelist's Crackme #4"

    00401224   .  68 AE204000   push chap203.004020AE                    ; |Text = "Your registration info is invalid... Note that most of the special chars may raise registration problems!"

    00401229   .  6A 00         push 0                                   ; |hOwner = NULL

    0040122B   .  E8 36010000   call <jmp.&USER32.MessageBoxA>           ; \MessageBoxA

    ...........................................................................

    于是截取了一段关键代码。

    填入用户

    Mr.David
    注册码
    123456789

    这个程序不是用 GetDlgItemTextA 或 GetWindowTextA 获取字符,而是用消息函数SendDlgItemMessageA 获取字符信息,我们把断点下在00401127处,点Check按钮立即中断。注意用Alt+F5前台显示切换便于调试。

    004010D7   > /68 00200000   push 2000                                ; /Style = MB_OK|MB_TASKMODAL

    004010DC   . |68 01204000   push chap203.00402001                    ; |Title = "Duelist's Crackme #4"

    004010E1   . |68 61204000   push chap203.00402061                    ; |Text = "Congratulations! Please send your keygen (working one) to [email protected]!"

    004010E6   . |6A 00         push 0                                   ; |hOwner = NULL

    004010E8   . |E8 79020000   call <jmp.&USER32.MessageBoxA>           ; \MessageBoxA

    004010ED   . |B8 01000000   mov eax, 1

    004010F2   . |EB 25         jmp short chap203.00401119

    004010F4   > |817D 0C 11010>cmp dword ptr ss:[ebp+C], 111

    004010FB   . |0F84 FA000000 je chap203.004011FB

    00401101   . |817D 0C 10010>cmp dword ptr ss:[ebp+C], 110

    00401108   . |74 16         je short chap203.00401120

    0040110A   . |837D 0C 10    cmp dword ptr ss:[ebp+C], 10

    0040110E   . |0F84 F7000000 je chap203.0040120B

    00401114   . |B8 00000000   mov eax, 0

    00401119   > |5F            pop edi

    0040111A   . |5E            pop esi

    0040111B   . |5B            pop ebx

    0040111C   . |C9            leave

    0040111D   . |C2 1000       retn 10

    00401120   > |B8 01000000   mov eax, 1

    00401125   .^|EB F2         jmp short chap203.00401119

    00401127   > |6A 00         push 0                                   ; /lParam = 0

    00401129   . |6A 00         push 0                                   ; |wParam = 0

    0040112B   . |6A 0E         push 0E                                  ; |Message = WM_GETTEXTLENGTH

    0040112D   . |6A 03         push 3                                   ; |ControlID = 3

    0040112F   . |FF75 08       push dword ptr ss:[ebp+8]                ; |hWnd

    00401132   . |E8 41020000   call <jmp.&USER32.SendDlgItemMessageA>   ; \SendDlgItemMessageA

    00401137   . |A3 AF214000   mov dword ptr ds:[4021AF], eax  //eax返回用户字符数目5

    0040113C   . |83F8 00       cmp eax, 0   //比较eax是否为0

    0040113F   . |0F84 D5000000 je chap203.0040121A //是则跳走Over。

    00401145   . |83F8 08       cmp eax, 8  //比较eax是否大于8个字符。

    00401148   . |0F8F CC000000 jg chap203.0040121A //是则跳走Over。

    0040114E   . |8BF0          mov esi, eax

    00401150   . |6A 00         push 0                                   ; /lParam = 0

    00401152   . |6A 00         push 0                                   ; |wParam = 0

    00401154   . |6A 0E         push 0E                                  ; |Message = WM_GETTEXTLENGTH

    00401156   . |6A 04         push 4                                   ; |ControlID = 4

    00401158   . |FF75 08       push dword ptr ss:[ebp+8]                ; |hWnd

    0040115B   . |E8 18020000   call <jmp.&USER32.SendDlgItemMessageA>   ; \SendDlgItemMessageA

    00401160   . |83F8 00       cmp eax, 0  //直接比较eax返回注册码字符数目9是否为0

    00401163   . |0F84 B1000000 je chap203.0040121A  //是则跳走Over。

    00401169   . |3BF0          cmp esi, eax  //比较用户名和注册码的长度是否相同。

    0040116B   . |0F85 A9000000 jnz chap203.0040121A  //不同跳走Over。



    这里修改用户名



    David

    注册码
    12345

    再次来到这里。

    00401171   . |68 60214000   push chap203.00402160                    ; /lParam = 402160

    00401176   . |6A 08         push 8                                   ; |wParam = 8

    00401178   . |6A 0D         push 0D                                  ; |Message = WM_GETTEXT

    0040117A   . |6A 03         push 3                                   ; |ControlID = 3

    0040117C   . |FF75 08       push dword ptr ss:[ebp+8]                ; |hWnd

    0040117F   . |E8 F4010000   call <jmp.&USER32.SendDlgItemMessageA>   ; \SendDlgItemMessageA

    00401184   . |68 79214000   push chap203.00402179                    ; /lParam = 402179

    00401189   . |6A 10         push 10                                  ; |wParam = 10

    0040118B   . |6A 0D         push 0D                                  ; |Message = WM_GETTEXT

    0040118D   . |6A 04         push 4                                   ; |ControlID = 4

    0040118F   . |FF75 08       push dword ptr ss:[ebp+8]                ; |hWnd

    00401192   . |E8 E1010000   call <jmp.&USER32.SendDlgItemMessageA>   ; \SendDlgItemMessageA

    00401197   . |B9 FFFFFFFF   mov ecx, -1

    0040119C   > |41            inc ecx

    0040119D   . |0FBE81 602140>movsx eax, byte ptr ds:[ecx+402160]  //逐位取用户名的16进制。

    004011A4   . |83F8 00       cmp eax, 0   比较是否为0,判断输入是否是字符。

    004011A7   . |74 32         je short chap203.004011DB  //不是则跳走Over。

    004011A9   . |BE FFFFFFFF   mov esi, -1

    004011AE   . |83F8 41       cmp eax, 41  //比较eax是否小于41(A)

    004011B1   . |7C 67         jl short chap203.0040121A  //小于over,不能是数字等字符。

    004011B3   . |83F8 7A       cmp eax, 7A //比较eax是否大于7A(z)

    004011B6   . |77 62         ja short chap203.0040121A //大于over,不能是数字等字符。

    004011B8   . |83F8 5A       cmp eax, 5A  //比较eax是否大于5A(Z)

    004011BB   . |7C 03         jl short chap203.004011C0 //小于则跳走,不处理。

    004011BD   . |83E8 20       sub eax, 20    //将小写字符转为大写。

    004011C0   >  46            inc esi                                                            

    004011C1   . |0FBE96 172040>movsx edx, byte ptr ds:[esi+402017] //计算序列号的原始字串。

    004011C8   . |3BC2          cmp eax, edx  //判断当前字符串是否等于edx。

    004011CA   .^|75 F4         jnz short chap203.004011C0  //不等则循环。

    004011CC   . |0FBE86 3C2040>movsx eax, byte ptr ds:[esi+40203C] //如相等则eax=正确字符。

    004011D3   . |8981 94214000 mov dword ptr ds:[ecx+402194], eax //将字符存贮在00402194

    004011D9   .^|EB C1         jmp short chap203.0040119C  //循环。

    004011DB   > |FF35 AF214000 push dword ptr ds:[4021AF]     //序列号数目5进堆栈。

    004011E1   . |68 94214000   push chap203.00402194         //真码进入堆栈。

    004011E6   . |68 79214000   push chap203.00402179        //假码入堆栈。

    004011EB   . |E8 54000000   call chap203.00401244   //比较Call,跟进。

    004011F0   . |83F8 01       cmp eax, 1  //EAX=1则注册正确。

    004011F3   .^\0F84 DEFEFFFF je chap203.004010D7  //跳到注册成功对话框处。

    004011F9   .  EB 1F         jmp short chap203.0040121A

    004011FB   >  837D 10 01    cmp dword ptr ss:[ebp+10], 1             ; |

    004011FF   .^ 0F84 22FFFFFF je chap203.00401127                      ; |

    00401205   .  837D 10 02    cmp dword ptr ss:[ebp+10], 2             ; |

    00401209   .  75 2F         jnz short chap203.0040123A               ; |

    0040120B   >  E8 B4000000   call <jmp.&KERNEL32.ExitProcess>         ; \ExitProcess

    00401210   .  B8 01000000   mov eax, 1

    00401215   .^ E9 FFFEFFFF   jmp chap203.00401119

    0040121A   >  68 00200000   push 2000                                ; /Style = MB_OK|MB_TASKMODAL; Default case of switch 004011A4

    0040121F   .  68 01204000   push chap203.00402001                    ; |Title = "Duelist's Crackme #4"

    00401224   .  68 AE204000   push chap203.004020AE                    ; |Text = "Your registration info is invalid... Note that most of the special chars may raise registration problems!"

    00401229   .  6A 00         push 0                                   ; |hOwner = NULL

    0040122B   .  E8 36010000   call <jmp.&USER32.MessageBoxA>  //错误提示。

    .....................................................................



    转存信息



    00402017  41 31 4C 53 4B 32 44 4A  A1LSK2DJ

    0040201F  46 34 48 47 50 33 51 57  F4HGP3QW

    00402027  4F 35 45 49 52 36 55 54  O5EIR6UT

    0040202F  59 5A 38 4D 58 4E 37 43  YZ8MXN7C

    00402037  42 56 39 00 20 53 55 37  BV9. SU7

    0040203F  43 53 4A 4B 46 30 39 4E  CSJKF09N

    00402047  43 53 44 4F 39 53 44 46  CSDO9SDF

    0040204F  30 39 53 44 52 4C 56 4B  09SDRLVK

    00402057  37 38 30 39 53 34 4E 46  7809S4NF



    004011EB   . |E8 54000000   call chap203.00401244   //比较Call,跟进。



    00401244  /$  C8 000000     enter 0, 0

    00401248  |.  B8 01000000   mov eax, 1

    0040124D  |.  8B7D 08       mov edi, dword ptr ss:[ebp+8]

    00401250  |.  8B75 0C       mov esi, dword ptr ss:[ebp+C]

    00401253  |.  8B4D 10       mov ecx, dword ptr ss:[ebp+10]  //esi 存放真码 KSN0K

    00401256  |.  F3:A6         repe cmps byte ptr es:[edi], byte ptr ds>

    00401258  |.  67:E3 05      jcxz short chap203.00401260

    0040125B  |.  B8 00000000   mov eax, 0

    00401260  |>  C9            leave

    00401261  \.  C2 0C00       retn 0C



    注册码算法

    取地址
    [esi+402017] 处的字符与注册码第一位比较,不相等则esi加1,直到两者相同为止。

    然后取[esi+40203C] 算出注册码第一位。

    后面位数的一样。


    【内存注册机】

    修改内存

    修改地址
    401148

    修改长度

    6

    原始指令

    0F8FCC000000
    修改指令
    909090909090

    添加
    修改地址
    40116B
    修改长度
    6
    原始指令
    0F85A9000000
    修改指令
    909090909090
    添加
    中断地址
    4011EB
    中断次数 1
    第一字节 E8
    指令长度 5
    继续添加
    中断地址
    401256
    中断次数 1
    第一字节 F3
    指令长度 2
    最后内存方式寄存器 Esi

    [ 本帖最后由 jzyjd 于 2009-3-10 23:14 编辑 ]
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表