首页
社区
课程
招聘
[原创]一个简单有趣的CM
发表于: 2009-11-28 19:54 3780

[原创]一个简单有趣的CM

2009-11-28 19:54
3780
这个CM很简单,没有任何保护,适合新手练习,老手飘过。

我喜欢将软件先拖到IDA中分析一下(这是一个好习惯),很快它的执行流程图就呈现在面前。

看到这里:

loc_4015AE:             ; "name?"
push    offset s_Name?
call    puts
push    offset byte_43F1C0 ; char *
call    gets
xor     ecx, ecx
很明显是输入验证码。
复制地址4015AE,用OD打开程序,Ctrl+G到这里。下段,重新运行,断在这里。F8单步运行,输入用户名:pediy
到这里:
004015C2   .  31C9          XOR ECX,ECX                              ;  msvcrt.773B76C7
004015C4   >  8A1401        MOV DL,BYTE PTR DS:[ECX+EAX]
004015C7   .  41            INC ECX
004015C8   .  80FA 00       CMP DL,0
004015CB   .^ 75 F7         JNZ SHORT FJLJ_cra.004015C4              ;循环得到用户名的长度,如果大于8则失败
004015CD   .  83F9 09       CMP ECX,9
004015D0   .  7E 18         JLE SHORT FJLJ_cra.004015EA              ;跳到用户名验证过程
004015D2   >  68 03164000   PUSH FJLJ_cra.00401603                   ; /s = "NO!"
004015D7   .  E8 E4F20000   CALL <JMP.&msvcrt.puts>                  ; \puts
004015DC   . /EB 10         JMP SHORT FJLJ_cra.004015EE
004015DE   . |68 FE154000   PUSH FJLJ_cra.004015FE                   ; /s = "YAY!"
004015E3   . |E8 D8F20000   CALL <JMP.&msvcrt.puts>                  ; \puts
004015E8   . |EB 04         JMP SHORT FJLJ_cra.004015EE
004015EA   >^|EB 84         JMP SHORT FJLJ_cra.00401570

下面就是用户名验证(动态):
00401570   > /31D2          XOR EDX,EDX                              ;  ntdll.77519A00
00401572   . |31C9          XOR ECX,ECX
00401574   . |31DB          XOR EBX,EBX
00401576   > |8A1C01        MOV BL,BYTE PTR DS:[ECX+EAX]             ;依次取注册码相加取低位,DL=1B
00401579   . |00DA          ADD DL,BL
0040157B   . |41            INC ECX
0040157C   . |80FB 00       CMP BL,0
0040157F   .^|75 F5         JNZ SHORT FJLJ_cra.00401576
00401581   . |B8 00F24300   MOV EAX,FJLJ_cra.43F200               
00401586   . |01D0          ADD EAX,EDX                              ;eax=43F21B
00401588   . |89C1          MOV ECX,EAX
0040158A   . |B8 D9154000   MOV EAX,FJLJ_cra.004015D9               
0040158F   . |29C8          SUB EAX,ECX                              ;43F21B-4015D9  
00401591   . |66:89C3       MOV BX,AX                                ;低位放bx
00401594   . |C1C8 10       ROR EAX,10
00401597   . |66:89C2       MOV DX,AX                                ;高位放dx
0040159A   . |31C0          XOR EAX,EAX
0040159C   . |C601 E9       MOV BYTE PTR DS:[ECX],0E9                ;依次将0E9,bx,dx,90放入地址43F21B
0040159F   . |8859 01       MOV BYTE PTR DS:[ECX+1],BL
004015A2   . |8879 02       MOV BYTE PTR DS:[ECX+2],BH
004015A5   . |8851 03       MOV BYTE PTR DS:[ECX+3],DL
004015A8   .^|E9 3EFFFFFF   JMP FJLJ_cra.004014EB

继续跟入:
004014EB   > /8871 04       MOV BYTE PTR DS:[ECX+4],DH
004014EE   . |C641 05 90    MOV BYTE PTR DS:[ECX+5],90
004014F2   . |51            PUSH ECX
004014F3   . |68 F6154000   PUSH FJLJ_cra.004015F6                   ; /s = "serial?"
004014F8   . |E8 C3F30000   CALL <JMP.&msvcrt.puts>                  ; \puts
004014FD   . |8B44E4 04     MOV EAX,DWORD PTR SS:[ESP+4]
00401501   . |89C3          MOV EBX,EAX
00401503   . |81F3 00F24300 XOR EBX,43F200                           ;ebx=1B
00401509   . |01D8          ADD EAX,EBX                              ;eax=43F21B+1B
0040150B   . |90            NOP
0040150C   . |90            NOP
0040150D   . |90            NOP
0040150E   . |90            NOP
0040150F   . |90            NOP
00401510   . |31DB          XOR EBX,EBX
00401512   . |90            NOP
00401513   . |90            NOP
00401514   . |90            NOP
00401515   . |90            NOP
00401516   . |83C0 10       ADD EAX,10                               ;eax=43F246,下面将验证码放入43F246
00401519   . |50            PUSH EAX                                 ; /s       ;输入1234567
0040151A   . |E8 91F30000   CALL <JMP.&msvcrt.gets>                  ; \gets
0040151F   . |33C9          XOR ECX,ECX
00401521   . |33D2          XOR EDX,EDX
00401523   . |33DB          XOR EBX,EBX
00401525   . |8BD8          MOV EBX,EAX                              ebx=43F246
00401527   > |8A1408        MOV DL,BYTE PTR DS:[EAX+ECX]             ;取验证码之和+ebx
0040152A   . |03DA          ADD EBX,EDX
0040152C   . |41            INC ECX
0040152D   . |8A1408        MOV DL,BYTE PTR DS:[EAX+ECX]
00401530   . |03DA          ADD EBX,EDX                              ;ebx=0043F3B2
00401532   . |41            INC ECX
00401533   . |80FA 00       CMP DL,0
00401536   .^|75 EF         JNZ SHORT FJLJ_cra.00401527
00401538   > |83E9 02       SUB ECX,2
0040153B   . |8A1408        MOV DL,BYTE PTR DS:[EAX+ECX]             ;ebx-偶数位
0040153E   . |2BDA          SUB EBX,EDX
00401540   . |83F9 00       CMP ECX,0
00401543   .^|7F F3         JG SHORT FJLJ_cra.00401538
00401545   .^|EB 84         JMP SHORT FJLJ_cra.004014CB
00401547     |90            NOP

到004014CB:
004014CB   > /8A1408        MOV DL,BYTE PTR DS:[EAX+ECX]             ;将上面的结果-(注册码+(i+4))*10h,i=0,i++
004014CE   . |C1E2 04       SHL EDX,4
004014D1   . |2BDA          SUB EBX,EDX
004014D3   . |83C1 04       ADD ECX,4
004014D6   . |80FE 00       CMP DH,0
004014D9   . |74 04         JE SHORT FJLJ_cra.004014DF
004014DB   . |31D2          XOR EDX,EDX
004014DD   .^ EB EC         JMP SHORT FJLJ_cra.004014CB
004014DF   > |EB 6F         JMP SHORT FJLJ_cra.00401550
跳到00401550:
00401550   > \8B44E4 08     MOV EAX,DWORD PTR SS:[ESP+8]             ;  FJLJ_cra.0043F21B
00401554   .  90            NOP
00401555   .  90            NOP
00401556   .  90            NOP
00401557   .  90            NOP
00401558   .  90            NOP
00401559   .  81C3 D6040000 ADD EBX,4D6                               ;上面的结果+4D6与eax比较
0040155F   .  3BD8          CMP EBX,EAX                               ;比较
00401561   .  74 02         JE SHORT FJLJ_cra.00401565                ;关键跳,不等失败
00401563   .  EB 6D         JMP SHORT FJLJ_cra.004015D2
00401565   >  FFE3          JMP EBX
在这我就有点迷糊了,显然ebx中就是正确的地址,根据分析正确地址是4015DE,再看看ebx中的地址怎么来的,就是上面43F200 +1B,这是不可能的,43F200>4015DE,所以ebx不能为这个值。看来ebx只是个跳转地址。但要怎么才能找到这个地址了。再回头看代码:
00401581   . |B8 00F24300   MOV EAX,FJLJ_cra.43F200               
00401586   . |01D0          ADD EAX,EDX                              ;eax=43F21B
00401588   . |89C1          MOV ECX,EAX
0040158A   . |B8 D9154000   MOV EAX,FJLJ_cra.004015D9               
0040158F   . |29C8          SUB EAX,ECX                              ;43F21B-4015D9  
00401591   . |66:89C3       MOV BX,AX                                ;低位放bx
00401594   . |C1C8 10       ROR EAX,10
00401597   . |66:89C2       MOV DX,AX                                ;高位放dx
0040159A   . |31C0          XOR EAX,EAX
0040159C   . |C601 E9       MOV BYTE PTR DS:[ECX],0E9                ;依次将0E9,bx,dx,90放入地址43F21B
0040159F   . |8859 01       MOV BYTE PTR DS:[ECX+1],BL
004015A2   . |8879 02       MOV BYTE PTR DS:[ECX+2],BH
004015A5   . |8851 03       MOV BYTE PTR DS:[ECX+3],DL
004015A8   .^|E9 3EFFFFFF   JMP FJLJ_cra.004014EB
在汇编窗口看看43F21B:
0043F21B  - E9 BE23FCFF     JMP FJLJ_cra.004015DE
0043F220    90              NOP
0043F221    0000            ADD BYTE PTR DS:[EAX],AL

呵呵,现在一切都明白了。所以对于新手,遇到问题并不可怕,我们只要多看代码,不懂不要紧,只要多看,心里慢慢就明白了。

算法总结:

将用户名相加得t,每次取低位,s=t+43F200 ,再用s-4015D9 就得到一个差值,前面加上E9,就是一个跳转地址了,所以只要注册码算法的地址等于s,注册就成功了。
注册码的计算是:s+t+10h+注册码偶数之和-(注册码+(i+4))*10h【i=0,i++,i<注册码长度】+4D6h,只要结果等于s,就成功了。

一组注册码:name:pediy
            serial:1b3g2f

唉,写文章比破解它更累,在这里感谢那些高手们,是他们不辞辛苦的写破文,才有了我们学习的机会。

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//