riusksk 发表于 2009-8-22 00:28:10

破解某CM

破解某CM
作者:riusksk
主页:http://riusksk.blogbus.com

中午在CCG论坛上看到某兄弟发了个CM,只暴破了,于是就操起家伙,磨刀霍霍向CM,因此就有了本文。那兄弟发的帖子在:
http://www.ccgcn.com/bbs/viewthread.php?tid=1114&extra=page%3D1 ,如果有错误之处,欢迎指正.说实话,有些地方,我也是很模糊的,


首先打开文件,随便输入用户名“riusksk”和注册“78787878“,查看错误提示,发现提示为 “fail”,然后用OD载入,查找所有字符串,具体内容如下:

文本字串参考位于 Crack_Me:.text
地址       反汇编                                    文本字串
004015C1   PUSH Crack_Me.00403038                  ASCII "User Name is empty!"
0040160C   PUSH Crack_Me.00403028                  ASCII "Great! pf! pf!"
0040161A   PUSH Crack_Me.00403020                  ASCII "fail!"
004016A7   PUSH Crack_Me.00403050                  ASCII "C:\"
004016C4   MOV EDX,DWORD PTR SS:             (初始 CPU 选择)
00401899   PUSH Crack_Me.0040304C                  ASCII "%s"

此时鼠标双击ASCII "fail!",窗口自动跳至下面:

00401590   .6A FF         PUSH -1
00401592   .68 381E4000   PUSH Crack_Me.00401E38                                          ;SE 处理程序安装
00401597   .64:A1 0000000>MOV EAX,DWORD PTR FS:
0040159D   .50            PUSH EAX
0040159E   .64:8925 00000>MOV DWORD PTR FS:,ESP
004015A5   .51            PUSH ECX
004015A6   .56            PUSH ESI
004015A7   .8BF1          MOV ESI,ECX
004015A9   .6A 01         PUSH 1
004015AB   .E8 6A050000   CALL <JMP.&MFC42.#6334_?UpdateData@CWnd@@QAEHH@Z>
004015B0   .8B4E 60       MOV ECX,DWORD PTR DS:                                 ;将用户名存入ECX
004015B3   .8D46 60       LEA EAX,DWORD PTR DS:                                 ;用户名指针
004015B6   .8B51 F8       MOV EDX,DWORD PTR DS:                                    ;用户名长度
004015B9   .85D2          TEST EDX,EDX
004015BB   .75 20         JNZ SHORT Crack_Me.004015DD                                     ;用户名不为空则跳,否则提示"User Name is empty"
004015BD   .6A 00         PUSH 0
004015BF   .6A 00         PUSH 0
004015C1   .68 38304000   PUSH Crack_Me.00403038                                          ;ASCII "User Name is empty!"
004015C6   .8BCE          MOV ECX,ESI
004015C8   .E8 47050000   CALL <JMP.&MFC42.#4224_?MessageBoxA@CWnd@@QAEHPBD0I@Z>
004015CD   .5E            POP ESI
004015CE   .8B4C24 04   MOV ECX,DWORD PTR SS:
004015D2   .64:890D 00000>MOV DWORD PTR FS:,ECX
004015D9   .83C4 10       ADD ESP,10
004015DC   .C3            RETN
004015DD   >8D5424 04   LEA EDX,DWORD PTR SS:
004015E1   .50            PUSH EAX                                                      ; /Arg2
004015E2   .52            PUSH EDX                                                      ; |Arg1
004015E3   .8BCE          MOV ECX,ESI                                                   ; |
004015E5   .E8 66000000   CALL Crack_Me.00401650                                          ; \对用户名riusksk进行计算,得出注册码
我们跟进此CALL看看:
{   
0040164F   .C3            RETN
00401650/$6A FF         PUSH -1
00401652|.68 6F1E4000   PUSH Crack_Me.00401E6F                                          ;SE 处理程序安装
00401657|.64:A1 0000000>MOV EAX,DWORD PTR FS:
0040165D|.50            PUSH EAX
0040165E|.64:8925 00000>MOV DWORD PTR FS:,ESP
00401665|.83EC 34       SUB ESP,34
00401668|.33C0          XOR EAX,EAX
0040166A|.53            PUSH EBX
0040166B|.894424 21   MOV DWORD PTR SS:,EAX
0040166F|.55            PUSH EBP
00401670|.894424 29   MOV DWORD PTR SS:,EAX
00401674|.56            PUSH ESI
00401675|.894424 31   MOV DWORD PTR SS:,EAX
00401679|.33DB          XOR EBX,EBX
0040167B|.894424 35   MOV DWORD PTR SS:,EAX
0040167F|.57            PUSH EDI
00401680|.8D4C24 18   LEA ECX,DWORD PTR SS:
00401684|.895C24 20   MOV DWORD PTR SS:,EBX
00401688|.885C24 2C   MOV BYTE PTR SS:,BL
0040168C|.894424 3D   MOV DWORD PTR SS:,EAX
00401690|.E8 55040000   CALL <JMP.&MFC42.#540_??0CString@@QAE@XZ>
00401695|.6A 0A         PUSH 0A                                                         ; /pFileSystemNameSize = 0000000A
00401697|.53            PUSH EBX                                                      ; |pFileSystemNameBuffer
00401698|.53            PUSH EBX                                                      ; |pFileSystemFlags
00401699|.8D4C24 1C   LEA ECX,DWORD PTR SS:                                 ; |
0040169D|.53            PUSH EBX                                                      ; |pMaxFilenameLength
0040169E|.51            PUSH ECX                                                      ; |pVolumeSerialNumber
0040169F|.6A 0C         PUSH 0C                                                         ; |MaxVolumeNameSize = C (12.)
004016A1|.BE 01000000   MOV ESI,1                                                       ; |
004016A6|.53            PUSH EBX                                                      ; |VolumeNameBuffer
004016A7|.68 50304000   PUSH Crack_Me.00403050                                          ; |RootPathName = "C:\"
004016AC|.897424 6C   MOV DWORD PTR SS:,ESI                                 ; |
004016B0|.895C24 34   MOV DWORD PTR SS:,EBX                                 ; |
004016B4|.33ED          XOR EBP,EBP                                                   ; |
004016B6|.895C24 30   MOV DWORD PTR SS:,EBX                                 ; |
004016BA|.FF15 00204000 CALL DWORD PTR DS:[<&KERNEL32.GetVolumeInformationA>]         ; \GetVolumeInformationA
004016C0|.8B4424 10   MOV EAX,DWORD PTR SS:                                 ;C盘序列号48468be9入EAX
004016C4|.8B5424 58   MOV EDX,DWORD PTR SS:
004016C8|.35 26038319   XOR EAX,19830326                                                ;C盘序列号48468be9与19830326异或,长得有点像生日日期,呵呵
004016CD|.83C9 FF       OR ECX,FFFFFFFF                                                 ;令ECX=-1
004016D0|.8B12          MOV EDX,DWORD PTR DS:                                    ;用户名riusksk入EDX
004016D2|.894424 10   MOV DWORD PTR SS:,EAX
004016D6|.8BFA          MOV EDI,EDX                                                   ;将用户名存入EDI
004016D8|.33C0          XOR EAX,EAX
004016DA|.F2:AE         REPNE SCAS BYTE PTR ES:
004016DC|.F7D1          NOT ECX
004016DE|.49            DEC ECX                                                         ;获取用户名长度
004016DF|.895424 1C   MOV DWORD PTR SS:,EDX                                 ;EDX指向用户名
004016E3|.8BF9          MOV EDI,ECX                                                   ;将用户名长度存入EDI
004016E5|.0F84 BC010000 JE Crack_Me.004018A7
004016EB|.3BFE          CMP EDI,ESI
004016ED|.897424 58   MOV DWORD PTR SS:,ESI
004016F1|.0F8C AF000000 JL Crack_Me.004017A6                                          ;用户名长度小于1则跳
004016F7|.DD05 30254000 FLD QWORD PTR DS:                                       ;ST0=0.0
004016FD|.EB 04         JMP SHORT Crack_Me.00401703
004016FF|>8B5424 1C   /MOV EDX,DWORD PTR SS:                                  ;用户名入EDX
00401703|>8A5C32 FF      MOV BL,BYTE PTR DS:                                 ;循环处理用户名每一字符
00401707|.DB4424 58   |FILD DWORD PTR SS:                                     ;用户名位数存入ST0
0040170B|.0FBEC3      |MOVSX EAX,BL                                                   ;BL为用户名中的一个字符,此处先取'r',下面就以它为例进行分析
0040170E|.DD5C24 24   |FSTP QWORD PTR SS:                                     ;用户名位数存入ST7
00401712|.894424 58   |MOV DWORD PTR SS:,EAX                                  ;eax=72("r"),即用户名字符的ASCII值
00401716|.DB4424 58   |FILD DWORD PTR SS:                                     ;ST0=114(十进制)
0040171A|.0FBECB      |MOVSX ECX,BL                                                   ;BL=72 ('r'),即用户名ASCII值
0040171D|.D9FA          |FSQRT                                                          ;开平方根,值保存在ST0
0040171F|.0FAFCE      |IMUL ECX,ESI                                                   ;ecx=0x72*1,即用户名字符乘以其所在位数
00401722|.DC4C24 24   |FMUL QWORD PTR SS:                                     ;ST0=平方根值乘以位数
00401726|.DC05 28254000 |FADD QWORD PTR DS:                                     ;ST0=ST0+1
0040172C|.0FAFCE      |IMUL ECX,ESI                                                   ;用户名字符ASCII乘以位数的值再乘以位数
0040172F|.894C24 58   |MOV DWORD PTR SS:,ECX
00401733|.DB4424 58   |FILD DWORD PTR SS:                                     ;将上面的积存入ST0
00401737|.DEC9          |FMULP ST(1),ST                                                 ;ST0=ST1*ST0
00401739|.D8C1          |FADD ST,ST(1)                                                ;ST0=ST0+ST1
0040173B|.E8 36040000   |CALL <JMP.&MSVCRT._ftol>                                       ;进入浮点数运算
00401740|.99            |CDQ
00401741|.DDD8          |FSTP ST                                                      ;ST7=ST0
00401743|.B9 A0860100   |MOV ECX,186A0
00401748|.F7F9          |IDIV ECX                                                       ;用64位的EDX:EAX除以ECX
0040174A|.895424 14   |MOV DWORD PTR SS:,EDX                                  ;保存余数,记为数据1
0040174E|.0FBED3      |MOVSX EDX,BL                                                   ;BL=72 ('r'),即依次取用户名ASCII码
00401751|.895424 58   |MOV DWORD PTR SS:,EDX
00401755|.DB4424 58   |FILD DWORD PTR SS:                                     ;ST0=114(十进制),相当于0x72,即将用户名ASCII入ST0
00401759|.DD05 20254000 |FLD QWORD PTR DS:                                    ;将位数入ST0
0040175F|.E8 0C040000   |CALL <JMP.&MSVCRT._CIpow>                                    ;运算后ST0=用户名ASCII码平方
00401764|.DC4C24 24   |FMUL QWORD PTR SS:                                     ;ST0*1,即用户名平方后的值乘以其位数
00401768|.E8 09040000   |CALL <JMP.&MSVCRT._ftol>
0040176D|.DB4424 14   |FILD DWORD PTR SS:                                     ;ST0等于上面的余数
00401771|.8BCE          |MOV ECX,ESI                                                    ;用户名位数
00401773|.0FAFCD      |IMUL ECX,EBP                                                   ;用户名位数乘以用户名前一位在本循环算出的值(最初为0)
00401776|.D9C0          |FLD ST                                                         ;ST1=ST0,ST0=ST0
00401778|.D9FA          |FSQRT                                                          ;开平方,值保存在ST0
0040177A|.03C1          |ADD EAX,ECX
0040177C|.B9 A0860100   |MOV ECX,186A0
00401781|.99            |CDQ
00401782|.F7F9          |IDIV ECX
00401784|.8BEA          |MOV EBP,EDX                                                    ;保存余数,记为数据2
00401786|.E8 EB030000   |CALL <JMP.&MSVCRT._ftol>
0040178B|.03C5          |ADD EAX,EBP
0040178D|.B9 A0860100   |MOV ECX,186A0
00401792|.99            |CDQ
00401793|.F7F9          |IDIV ECX                                                       ;除以ECX,余数保存在EDX
00401795|.46            |INC ESI                                                      ;esi为计数器
00401796|.3BF7          |CMP ESI,EDI                                                    ;将ESI与用户名长度比较
00401798|.897424 58   |MOV DWORD PTR SS:,ESI
0040179C|.8BDA          |MOV EBX,EDX                                                    ;保存余数,记为数据3
0040179E|.^ 0F8E 5BFFFFFF \JLE Crack_Me.004016FF                                          ;循环依次对各用户名字符进行以上计算
004017A4|.DDD8          FSTP ST
004017A6|>33C0          XOR EAX,EAX                                                   ;EAX清零
004017A8|>8BD0          /MOV EDX,EAX
004017AA|.8B4C24 14   |MOV ECX,DWORD PTR SS:                                  ;ECX=数据1(参见0040174A)
004017AE|.0FAFD0      |IMUL EDX,EAX
004017B1|.0FAFD0      |IMUL EDX,EAX                                                   ;EDX=EAX^3
004017B4|.8D540A 1F   |LEA EDX,DWORD PTR DS:                              ;EDX=EAX^3+数据1+1F
004017B8|.81E2 7F000080 |AND EDX,8000007F                                             ;将EDX与8000007F与运算
004017BE|.79 05         |JNS SHORT Crack_Me.004017C5
004017C0|.4A            |DEC EDX
004017C1|.83CA 80       |OR EDX,FFFFFF80
004017C4|.42            |INC EDX
004017C5|>885404 2C   |MOV BYTE PTR SS:,DL                              ;保存DL到ESP+EAX+2C
004017C9|.40            |INC EAX                                                      ;EAX为计数器
004017CA|.83F8 05       |CMP EAX,5                                                      ;循环操作5次
004017CD|.^ 7C D9         \JL SHORT Crack_Me.004017A8
004017CF|.B8 05000000   MOV EAX,5
004017D4|>8BC8          /MOV ECX,EAX
004017D6|.0FAFC8      |IMUL ECX,EAX
004017D9|.0FAFC8      |IMUL ECX,EAX
004017DC|.8D5429 1F   |LEA EDX,DWORD PTR DS:                              ;EDX=EAX^3+数据2+1F(参见00401784)
004017E0|.81E2 7F000080 |AND EDX,8000007F                                             ;将EDX与8000007F与运算
004017E6|.79 05         |JNS SHORT Crack_Me.004017ED
004017E8|.4A            |DEC EDX
004017E9|.83CA 80       |OR EDX,FFFFFF80
004017EC|.42            |INC EDX
004017ED|>885404 2C   |MOV BYTE PTR SS:,DL                              ;保存DL到ESP+EAX+2C
004017F1|.40            |INC EAX                                                      ;EAX为计数器
004017F2|.83F8 0A       |CMP EAX,0A                                                   ;循环操作5次
004017F5|.^ 7C DD         \JL SHORT Crack_Me.004017D4
004017F7|.B8 0A000000   MOV EAX,0A
004017FC|>8BC8          /MOV ECX,EAX
004017FE|.0FAFC8      |IMUL ECX,EAX
00401801|.0FAFC8      |IMUL ECX,EAX
00401804|.8D5419 1F   |LEA EDX,DWORD PTR DS:                              ;EDX=EAX^3+数据3+1F(参见0040179C)
00401808|.81E2 7F000080 |AND EDX,8000007F                                             ;将EDX与8000007F与运算
0040180E|.79 05         |JNS SHORT Crack_Me.00401815
00401810|.4A            |DEC EDX
00401811|.83CA 80       |OR EDX,FFFFFF80
00401814|.42            |INC EDX
00401815|>885404 2C   |MOV BYTE PTR SS:,DL                              ;保存DL到ESP+EAX+2C
00401819|.40            |INC EAX                                                      ;EAX为计数器
0040181A|.83F8 0F       |CMP EAX,0F                                                   ;循环以上操作5次
0040181D|.^ 7C DD         \JL SHORT Crack_Me.004017FC
0040181F|.B8 0F000000   MOV EAX,0F
00401824|>8BC8          /MOV ECX,EAX
00401826|.8B5424 10   |MOV EDX,DWORD PTR SS:                                  ;C盘序列号(参见004016C0),现在才发现记忆力在逆向过程中的用处了
0040182A|.0FAFC8      |IMUL ECX,EAX
0040182D|.0FAFC8      |IMUL ECX,EAX
00401830|.8D4C11 1F   |LEA ECX,DWORD PTR DS:                              ;ECX=EAX^3+C盘序列号+1F
00401834|.81E1 7F000080 |AND ECX,8000007F                                             ;将ECX与8000007F与运算
0040183A|.79 05         |JNS SHORT Crack_Me.00401841
0040183C|.49            |DEC ECX
0040183D|.83C9 80       |OR ECX,FFFFFF80
00401840|.41            |INC ECX
00401841|>884C04 2C   |MOV BYTE PTR SS:,CL                              ;保存CL到ESP+EAX+2C
00401845|.40            |INC EAX
00401846|.83F8 14       |CMP EAX,14                                                   ;循环操作5次
00401849|.^ 7C D9         \JL SHORT Crack_Me.00401824
0040184B|.33D2          XOR EDX,EDX
0040184D|.33C9          XOR ECX,ECX                                                   ;下面这段循环计算就是注册算法的关键所在
0040184F|>8A4414 2C   /MOV AL,BYTE PTR SS:
00401853|.3C 30         |CMP AL,30                                                      ;小于数值“0”则跳转
00401855|.7C 04         |JL SHORT Crack_Me.0040185B
00401857|.3C 39         |CMP AL,39                                                      ;小于等于数值“9”则跳转
00401859|.7E 29         |JLE SHORT Crack_Me.00401884
0040185B|>3C 41         |CMP AL,41                                                      ;小于“A”跳转
0040185D|.7C 04         |JL SHORT Crack_Me.00401863
0040185F|.3C 5A         |CMP AL,5A                                                      ;小于等于“Z”则跳转
00401861|.7E 21         |JLE SHORT Crack_Me.00401884
00401863|>3C 61         |CMP AL,61                                                      ;小于“a”则跳转
00401865|.7C 04         |JL SHORT Crack_Me.0040186B
00401867|.3C 7A         |CMP AL,7A                                                      ;小于等于“z”则跳转
00401869|.7E 19         |JLE SHORT Crack_Me.00401884                                    ;非0-9,A-Z,a-z之间的值需进行以下操作转换为以上范围的值
0040186B|>0FBEC0      |MOVSX EAX,AL
0040186E|.8D4408 1F   |LEA EAX,DWORD PTR DS:
00401872|.25 7F000080   |AND EAX,8000007F
00401877|.79 05         |JNS SHORT Crack_Me.0040187E
00401879|.48            |DEC EAX
0040187A|.83C8 80       |OR EAX,FFFFFF80
0040187D|.40            |INC EAX
0040187E|>884414 2C   |MOV BYTE PTR SS:,AL
00401882|.^ EB CB         |JMP SHORT Crack_Me.0040184F
00401884|>83C1 07       |ADD ECX,7                                                      ;ECX为计数器
00401887|.42            |INC EDX
00401888|.81F9 8C000000 |CMP ECX,8C                                                   ;循环计算20次,也就是注册码的位数
0040188E|.^ 7C BF         \JL SHORT Crack_Me.0040184F
00401890|.8D4C24 2C   LEA ECX,DWORD PTR SS:                                 ;真注册码存入ECX
00401894|.8D5424 18   LEA EDX,DWORD PTR SS:
00401898|.51            PUSH ECX                                                       ; 真注册码ASCII "4bJ0UYrqqsbcpEh5n569"
00401899|.68 4C304000   PUSH Crack_Me.0040304C                                          ;ASCII "%s"
0040189E|.52            PUSH EDX
0040189F|.E8 82020000   CALL <JMP.&MFC42.#2818_?Format@CString@@QAAXPBDZZ>
004018A4|.83C4 0C       ADD ESP,0C
004018A7|>8B7424 54   MOV ESI,DWORD PTR SS:
004018AB|.8D4424 18   LEA EAX,DWORD PTR SS:
004018AF|.50            PUSH EAX
004018B0|.8BCE          MOV ECX,ESI
004018B2|.E8 69020000   CALL <JMP.&MFC42.#535_??0CString@@QAE@ABV0@@Z>
004018B7|.C74424 20 010>MOV DWORD PTR SS:,1
004018BF|.8D4C24 18   LEA ECX,DWORD PTR SS:
004018C3|.C64424 4C 00MOV BYTE PTR SS:,0
004018C8|.E8 33010000   CALL <JMP.&MFC42.#800_??1CString@@QAE@XZ>
004018CD|.8B4C24 44   MOV ECX,DWORD PTR SS:
004018D1|.8BC6          MOV EAX,ESI
004018D3|.5F            POP EDI
004018D4|.5E            POP ESI
004018D5|.5D            POP EBP
004018D6|.5B            POP EBX
004018D7|.64:890D 00000>MOV DWORD PTR FS:,ECX
004018DE|.83C4 40       ADD ESP,40
004018E1\.C2 0800       RETN 8


004015EA   .8B46 64       MOV EAX,DWORD PTR DS:                                 ;假注册码78787878
004015ED   .C74424 10 000>MOV DWORD PTR SS:,0
004015F5   .50            PUSH EAX                                                      ; /参数2=假注册码
004015F6   .8B4424 08   MOV EAX,DWORD PTR SS:                                    ; |
004015FA   .50            PUSH EAX                                                      ; |参数1=真注册码
004015FB   .FF15 C8214000 CALL DWORD PTR DS:[<&MSVCRT._mbscmp>]                           ; \进行注册码比较
00401601   .83C4 08       ADD ESP,8
00401604   .85C0          TEST EAX,EAX                                                    ;eax必须为0,也就是上面比较的注册码必须相等
00401606   .6A 00         PUSH 0
00401608   .6A 00         PUSH 0
0040160A   .75 0E         JNZ SHORT Crack_Me.0040161A                                     ;此句可NOP掉,进行暴破
0040160C   .68 28304000   PUSH Crack_Me.00403028                                          ;ASCII "Great! pf! pf!"
00401611   .8BCE          MOV ECX,ESI
00401613   .E8 FC040000   CALL <JMP.&MFC42.#4224_?MessageBoxA@CWnd@@QAEHPBD0I@Z>
00401618   .EB 15         JMP SHORT Crack_Me.0040162F
0040161A   >68 20304000   PUSH Crack_Me.00403020                                          ;ASCII "fail!",正是跳转到此处
0040161F   .8BCE          MOV ECX,ESI
00401621   .E8 EE040000   CALL <JMP.&MFC42.#4224_?MessageBoxA@CWnd@@QAEHPBD0I@Z>
00401626   .6A 00         PUSH 0
00401628   .8BCE          MOV ECX,ESI
0040162A   .E8 EB040000   CALL <JMP.&MFC42.#6334_?UpdateData@CWnd@@QAEHH@Z>
0040162F   >8D4C24 04   LEA ECX,DWORD PTR SS:
00401633   .C74424 10 FFF>MOV DWORD PTR SS:,-1
0040163B   .E8 C0030000   CALL <JMP.&MFC42.#800_??1CString@@QAE@XZ>
00401640   .8B4C24 08   MOV ECX,DWORD PTR SS:
00401644   .5E            POP ESI
00401645   .64:890D 00000>MOV DWORD PTR FS:,ECX
0040164C   .83C4 10       ADD ESP,10
0040164F   .C3            RETN
算法总结:
1.取C盘序列号与19830326做异或运算
2.利用用户名字符u的ASCII值进行计算
数据1=%186A0
数据2=[(ascii(u)^2 *i+数据2*i]%186A0
数据3=[数据2+sqrt(数据1)]%186A0
3.edx=eax^3+数据(包括C盘序列号)+1F(共四组,每组循环计算5次)
4.用上面计算出来的20组数据算出20位注册码

[ 本帖最后由 riusksk 于 2009-8-23 10:08 编辑 ]

HDd1145 发表于 2009-8-22 13:02:49

写得很详细。

MOV 发表于 2009-8-22 16:31:18

强烈学习了

Luckly 发表于 2009-8-22 23:20:35

感谢分享~ 非常详细的分析/:014

riusksk 发表于 2009-8-23 10:06:07

感谢版主的支持,继续努力,哈哈……

老万 发表于 2009-8-23 18:07:03

写得很详细,学习了。

hxqlky 发表于 2009-9-15 21:37:12

支持一个!

小试锋芒 发表于 2009-10-2 11:53:45

我也来学习下,多谢了~/:014
页: [1]
查看完整版本: 破解某CM