wzwgp 发表于 2006-2-17 16:56:00

CrackMe#4破解学习笔记

CrackMe#4破解学习笔记

脱壳和算法都很简单,适合我这样的新手学习,以提高破解能力。

PEiD查壳:UPX0.89.6-1.02/1.05-1.24(Delphi)stub->Markus&Laszlo

根据教材提示:
UPX脱壳断点:bp LoadLibraryA  bp GetProcAddress
UPX加壳入口第一句是:PUSHAD
出口关键字:POPAD
一般经过JMP跨段跳转到入口处。

一、脱壳:

OD载入,OD提示程序加壳等等,选不继续分析。
下断:bp GetProcAddress, F9 运行,  
断在:7C80AC28 >8BFF   MOV EDI,EDI 处,双击取消断点。

寄存器窗口内容
0012FF98   0046F805/CALL 到 GetProcAddress 来自 CrackMe0.0046F7FF
0012FF9C   7C800000|hModule = 7C800000 (kernel32)
0012FFA0   0046D009\ProcNameOrOrdinal = "GetCurrentThreadId"
0012FFA4   7C930738ntdll.7C930738

在堆栈器窗口中(0012FF98   0046F805/CALL 到 GetProcAddress 来自 CrackMe0.0046F7FF)
右键选“反汇编窗口跟随”,来到:

0046F805    09C0            OR EAX,EAX          (F4 F8)        
0046F807    74 07         JE SHORT CrackMe0.0046F810  (F8)
0046F809    8903            MOV DWORD PTR DS:,EAX  (F8)
0046F80B    83C3 04         ADD EBX,4           (F8)
0046F80E^ EB E1         JMP SHORT CrackMe0.0046F7F1  (此处回跳,避开)
0046F810    FF96 64010700   CALL DWORD PTR DS:(此处程序运行,避开)
0046F816    61            POPAD                        (F4 F8)(出口关键字)
0046F817^ E9 348AFEFF   JMP CrackMe0.00458250          (F8)(此处跨段跳转到入口处)

跳转来到入口处,(也可以在0046F817处F4、F8)

00458250    55            PUSH EBP                  (入口处,用Od的Dump插件直接脱壳)
00458251    8BEC            MOV EBP,ESP
00458253    83C4 F4         ADD ESP,-0C
00458256    B8 28814500   MOV EAX,CrackMe0.00458128
0045825B    E8 84D9FAFF   CALL CrackMe0.00405BE4
00458260    A1 98A54500   MOV EAX,DWORD PTR DS:
00458265    8B00            MOV EAX,DWORD PTR DS:
00458267    E8 D47CFEFF   CALL CrackMe0.0043FF40
0045826C    A1 98A54500   MOV EAX,DWORD PTR DS:
00458271    8B00            MOV EAX,DWORD PTR DS:

在入口处:00458250 这一行右键,选“用OllyDump脱壳调试进程”
在OllyDump的对话框中点“脱壳”,命名up1,保存。
CrackMe脱壳前180 KB (184,832 字节),脱壳后463 KB (474,112 字节)
PEiD再查:Borland Delphi 4.0 - 5.0

二、算法分析:

bp MessageBoxA

77D5050B >8BFF            MOV EDI,EDI                        ; up1.00457F98
77D5050D    55            PUSH EBP
77D5050E    8BEC            MOV EBP,ESP
77D50510    833D 1C04D777 0>CMP DWORD PTR DS:,0
77D50517    74 24         JE SHORT USER32.77D5053D

在堆栈器窗口中(0012F8F8   00440213/CALL 到 MessageBoxA 来自 up1.0044020E)
右键选“转到EBP”,看到:
0012F994|00D6B438ASCII "1356"
0012F998|00D6B424ASCII "wzwgpa"
0012F99C|00D6B410ASCII "wzwgpa"
0012F9A0|00D6B3FCASCII "wzwgpa"
0012F9A4|00D6B3E8ASCII "wzwgpa"
0012F9A8|00D6B3C0ASCII "wzwgpa"
0012F9AC|00D6B44CASCII "12345678"

运行CrackMe#4 填入用户名:wzwgpa 注册码:1356  出现破解成功信息:

you cracked the cff crackme #4 ! please send your solution to [email protected] !

现在要学的是算法,要知道1356是怎么来的?继续往下走。F2取消断点。

此时,信息窗口:
EDI=00457F98 (up1.00457F98), ASCII "Serial not valid"

右键选“反汇编窗口跟随数值”,来到:

00457F98   .53 65 72 69 6>ASCII "Serial not valid"
00457FA8   .00            ASCII 0
00457FA9      00            DB 00
00457FAA      00            DB 00
00457FAB      00            DB 00

右键选“转到->上个函数过程”,来到:

00457BAC/.55            PUSH EBP                ;EBP=0012F9D4 入栈   ESP=0012F9B4(ASCII"hRB")
00457BAD|.8BEC          MOV EBP,ESP                         ;EBP=ESP=0012F9B0
00457BAF|.33C9          XOR ECX,ECX                         ;ECX=0012F988 现清零
00457BB1|.51            PUSH ECX
00457BB2|.51            PUSH ECX
00457BB3|.51            PUSH ECX
00457BB4|.51            PUSH ECX
00457BB5|.51            PUSH ECX
00457BB6|.51            PUSH ECX
00457BB7|.51            PUSH ECX
00457BB8|.53            PUSH EBX                            ;EBX=00D6597C 入栈EDX=00D6597C
00457BB9|.56            PUSH ESI                            ;ESI=00D6597C 入栈
00457BBA|.8BD8          MOV EBX,EAX                         ;EBX=EAX=00D61E9C
00457BBC|.33C0          XOR EAX,EAX                         ;EAX的值已存入EBX,现清零
00457BBE|.55            PUSH EBP                            ;EBP=0012F9B0 入栈
00457BBF|.68 8A7E4500   PUSH up1.00457E8A                   ;up1.00457E8A 入栈
00457BC4|.64:FF30       PUSH DWORD PTR FS:             ;FS:==0012FBCC
00457BC7|.64:8920       MOV DWORD PTR FS:,ESP          ;ESP=0012F980 数值=0012FBCC
00457BCA|.8D55 FC       LEA EDX,DWORD PTR SS:      ;堆栈地址=0012F9AC=00000000  
00457BCD|.8B83 D8020000 MOV EAX,DWORD PTR DS:      ;DS:=00D61AC0=EAX
00457BD3|.E8 08C3FCFF   CALL up1.00423EE0                   ;取用户名位数(EAX=00000006)
00457BD8|.837D FC 00    CMP DWORD PTR SS:,0          ;检查是否输入用户名,堆栈 SS:

=00D6B3C0, (ASCII "wzwgpa")
00457BDC|.75 18         JNZ SHORT up1.00457BF6            ;大于0实现跳转
00457BDE|.6A 00         PUSH 0
00457BE0|.B9 987E4500   MOV ECX,up1.00457E98                ;enter your name !
00457BE5|.BA AC7E4500   MOV EDX,up1.00457EAC                ;you must enter your name !
00457BEA|.A1 98A54500   MOV EAX,DWORD PTR DS:
00457BEF|.8B00          MOV EAX,DWORD PTR DS:
00457BF1|.E8 3A85FEFF   CALL up1.00440130
00457BF6|>8D55 FC       LEA EDX,DWORD PTR SS:      ;堆栈中 地址=0012F9AC 数值=00D6B3C0

ASCII "wzwgpa"
00457BF9|.8B83 DC020000 MOV EAX,DWORD PTR DS:      ;DS:=00D670F0
00457BFF|.E8 DCC2FCFF   CALL up1.00423EE0
00457C04|.837D FC 00    CMP DWORD PTR SS:,0          ;检查是否输入序列号
00457C08|.75 18         JNZ SHORT up1.00457C22            ;大于0实现跳转
00457C0A|.6A 00         PUSH 0
00457C0C|.B9 C87E4500   MOV ECX,up1.00457EC8                ;enter a serial !
00457C11|.BA DC7E4500   MOV EDX,up1.00457EDC                ;you must enter a serial !
00457C16|.A1 98A54500   MOV EAX,DWORD PTR DS:
00457C1B|.8B00          MOV EAX,DWORD PTR DS:
00457C1D|.E8 0E85FEFF   CALL up1.00440130
00457C22|>33C0          XOR EAX,EAX                         ;EAX的值为注册码位数,现清零
00457C24|.A3 40B84500   MOV DWORD PTR DS:,EAX       ;DS:=0000054C=EAX=00000000
00457C29|.8D55 FC       LEA EDX,DWORD PTR SS:      ;注册码存入EDX
00457C2C|.8B83 D8020000 MOV EAX,DWORD PTR DS:      ;DS:=00D61AC0=EAX
00457C32|.E8 A9C2FCFF   CALL up1.00423EE0                   ;取用户名位数
00457C37|.8B45 FC       MOV EAX,DWORD PTR SS:      ;用户名存入EAX(堆栈 SS:

=00D6B3C0, (ASCII "wzwgpa"))
00457C3A|.E8 F9BFFAFF   CALL up1.00403C38
00457C3F|.A3 44B84500   MOV DWORD PTR DS:,EAX
00457C44|.A1 44B84500   MOV EAX,DWORD PTR DS:
00457C49|.E8 82FDFAFF   CALL up1.004079D0
00457C4E|.83F8 06       CMP EAX,6                           ;用户名位数与6相比
00457C51|.73 1D         JNB SHORT up1.00457C70            ;大于或等于6 转移
00457C53|.6A 00         PUSH 0
00457C55|.B9 F87E4500   MOV ECX,up1.00457EF8                ;name too short !
00457C5A|.BA 0C7F4500   MOV EDX,up1.00457F0C                ;your name must be at least 6 chars long

!
00457C5F|.A1 98A54500   MOV EAX,DWORD PTR DS:
00457C64|.8B00          MOV EAX,DWORD PTR DS:
00457C66|.E8 C584FEFF   CALL up1.00440130
00457C6B|.E9 59010000   JMP up1.00457DC9
00457C70|>8D55 FC       LEA EDX,DWORD PTR SS:
00457C73|.8B83 D8020000 MOV EAX,DWORD PTR DS:
00457C79|.E8 62C2FCFF   CALL up1.00423EE0
00457C7E|.8B45 FC       MOV EAX,DWORD PTR SS:      ;用户名存入EAX
00457C81|.BA 01000000   MOV EDX,1                           ;EDX=00140608 现EDX=1
00457C86|.4A            DEC EDX                           ;EDX=1-1=0
00457C87|.3B50 FC       CMP EDX,DWORD PTR DS:      ;DS:=00000006
00457C8A|.72 05         JB SHORT up1.00457C91               ;EDX小于DS:转移
00457C8C|.E8 F3AEFAFF   CALL up1.00402B84
00457C91|>42            INC EDX                           ;EDX加1
00457C92|.0FB64410 FF   MOVZX EAX,BYTE PTR DS:   ;取用户名第一位的ASCII值(w=77)
00457C97|.6BF0 02       IMUL ESI,EAX,2                      ;ESI=EAX*2=000000EE
00457C9A|.71 05         JNO SHORT up1.00457CA1            ;不溢出时转移
00457C9C|.E8 EBAEFAFF   CALL up1.00402B8C
00457CA1|>8D55 F8       LEA EDX,DWORD PTR SS:      ;堆栈地址=0012F9A8数值=00000000
00457CA4|.8B83 D8020000 MOV EAX,DWORD PTR DS:      ;DS:=00D61AC0
00457CAA|.E8 31C2FCFF   CALL up1.00423EE0
00457CAF|.8B45 F8       MOV EAX,DWORD PTR SS:      ;用户名存入EAX
00457CB2|.BA 02000000   MOV EDX,2                           ;EDX=2
00457CB7|.4A            DEC EDX                           ;EDX=2-1=1
00457CB8|.3B50 FC       CMP EDX,DWORD PTR DS:      ;DS:=00000006
00457CBB|.72 05         JB SHORT up1.00457CC2               ;EDX小于DS:转移
00457CBD|.E8 C2AEFAFF   CALL up1.00402B84           
00457CC2|>42            INC EDX                           ;EDX=1+1=2
00457CC3|.0FB64410 FF   MOVZX EAX,BYTE PTR DS:   ;取用户名第二位的ASCII值(z=7a)
00457CC8|.6BC0 02       IMUL EAX,EAX,2                      ;EAX=EAX*2=0000007A*2=000000F4
00457CCB|.71 05         JNO SHORT up1.00457CD2
00457CCD|.E8 BAAEFAFF   CALL up1.00402B8C
00457CD2|>03F0          ADD ESI,EAX                         ;ESI=000000EE+000000F4=000001E2
00457CD4|.71 05         JNO SHORT up1.00457CDB
00457CD6|.E8 B1AEFAFF   CALL up1.00402B8C
00457CDB|>8D55 F4       LEA EDX,DWORD PTR SS:      ;堆栈地址=0012F9A4数值=00000000
00457CDE|.8B83 D8020000 MOV EAX,DWORD PTR DS:      ;DS:=00D61AC0
00457CE4|.E8 F7C1FCFF   CALL up1.00423EE0                   ;取用户名
00457CE9|.8B45 F4       MOV EAX,DWORD PTR SS:      ;放入EAX
00457CEC|.BA 03000000   MOV EDX,3                           ;EDX=00000003
00457CF1|.4A            DEC EDX                           ;EDX=3-1=2
00457CF2|.3B50 FC       CMP EDX,DWORD PTR DS:
00457CF5|.72 05         JB SHORT up1.00457CFC               ;EDX=2 < 6 转移
00457CF7|.E8 88AEFAFF   CALL up1.00402B84
00457CFC|>42            INC EDX                           ;EDX=2+1=3
00457CFD|.0FB64410 FF   MOVZX EAX,BYTE PTR DS:   ;取用户名第三位的ASCII值(w=77)
00457D02|.6BC0 02       IMUL EAX,EAX,2                      ;EAX=EAX*2=00000077*2=000000EE
00457D05|.71 05         JNO SHORT up1.00457D0C
00457D07|.E8 80AEFAFF   CALL up1.00402B8C
00457D0C|>03F0          ADD ESI,EAX                         ;ESI=000001E2+EAX=000000EE=000002D0
00457D0E|.71 05         JNO SHORT up1.00457D15
00457D10|.E8 77AEFAFF   CALL up1.00402B8C
00457D15|>8D55 F0       LEA EDX,DWORD PTR SS:       ;堆栈地址=0012F9A0数值=00000000
00457D18|.8B83 D8020000 MOV EAX,DWORD PTR DS:      ;DS:=00D61AC0
00457D1E|.E8 BDC1FCFF   CALL up1.00423EE0
00457D23|.8B45 F0       MOV EAX,DWORD PTR SS:       ;堆栈 SS:=00D6B3FC, (ASCII

"wzwgpa")
00457D26|.BA 04000000   MOV EDX,4
00457D2B|.4A            DEC EDX
00457D2C|.3B50 FC       CMP EDX,DWORD PTR DS:
00457D2F|.72 05         JB SHORT up1.00457D36
00457D31|.E8 4EAEFAFF   CALL up1.00402B84
00457D36|>42            INC EDX
00457D37|.0FB64410 FF   MOVZX EAX,BYTE PTR DS:   ;取用户名第四位的ASCII值(g=67)
00457D3C|.6BC0 02       IMUL EAX,EAX,2                      ;EAX=EAX*2=00000067*2=000000CE
00457D3F|.71 05         JNO SHORT up1.00457D46
00457D41|.E8 46AEFAFF   CALL up1.00402B8C
00457D46|>03F0          ADD ESI,EAX                         ;ESI=000002D0+000000CE=0000039E
00457D48|.71 05         JNO SHORT up1.00457D4F
00457D4A|.E8 3DAEFAFF   CALL up1.00402B8C
00457D4F|>8D55 EC       LEA EDX,DWORD PTR SS:       ;堆栈地址=0012F99C数值=00000000
00457D52|.8B83 D8020000 MOV EAX,DWORD PTR DS:
00457D58|.E8 83C1FCFF   CALL up1.00423EE0
00457D5D|.8B45 EC       MOV EAX,DWORD PTR SS:
00457D60|.BA 05000000   MOV EDX,5
00457D65|.4A            DEC EDX
00457D66|.3B50 FC       CMP EDX,DWORD PTR DS:
00457D69|.72 05         JB SHORT up1.00457D70
00457D6B|.E8 14AEFAFF   CALL up1.00402B84
00457D70|>42            INC EDX
00457D71|.0FB64410 FF   MOVZX EAX,BYTE PTR DS:   ;取用户名第五位的ASCII值(p=70)
00457D76|.6BC0 02       IMUL EAX,EAX,2                      ;EAX=00000070*2=000000E0
00457D79|.71 05         JNO SHORT up1.00457D80
00457D7B|.E8 0CAEFAFF   CALL up1.00402B8C
00457D80|>03F0          ADD ESI,EAX                         ;ESI=0000039E+000000E0=0000047E
00457D82|.71 05         JNO SHORT up1.00457D89
00457D84|.E8 03AEFAFF   CALL up1.00402B8C
00457D89|>8D55 E8       LEA EDX,DWORD PTR SS:       ;堆栈地址=0012F998数值=00000000
00457D8C|.8B83 D8020000 MOV EAX,DWORD PTR DS:
00457D92|.E8 49C1FCFF   CALL up1.00423EE0
00457D97|.8B45 E8       MOV EAX,DWORD PTR SS:       ;堆栈 SS:=00D6B424, (ASCII

"wzwgpa")
00457D9A|.BA 06000000   MOV EDX,6
00457D9F|.4A            DEC EDX
00457DA0|.3B50 FC       CMP EDX,DWORD PTR DS:
00457DA3|.72 05         JB SHORT up1.00457DAA
00457DA5|.E8 DAADFAFF   CALL up1.00402B84
00457DAA|>42            INC EDX
00457DAB|.0FB64410 FF   MOVZX EAX,BYTE PTR DS:   ;取用户名第六位的ASCII值(a=61)
00457DB0|.6BC0 02       IMUL EAX,EAX,2                      ;EAX=00000061*2=000000C2
00457DB3|.71 05         JNO SHORT up1.00457DBA
00457DB5|.E8 D2ADFAFF   CALL up1.00402B8C
00457DBA|>03F0          ADD ESI,EAX                         ;ESI=0000047E+000000C2=00000540
00457DBC|.71 05         JNO SHORT up1.00457DC3
00457DBE|.E8 C9ADFAFF   CALL up1.00402B8C
00457DC3|>8935 40B84500 MOV DWORD PTR DS:,ESI       ;ESI存入DS:=00000000
00457DC9|>A1 44B84500   MOV EAX,DWORD PTR DS:       ;=00D6B3C0 EAX=00D6B3C0

(ASCII "wzwgpa")
00457DCE|.E8 FDFBFAFF   CALL up1.004079D0
00457DD3|.6BC0 02       IMUL EAX,EAX,2                      ;EAX=00000006*2=0000000C
00457DD6|.73 05         JNB SHORT up1.00457DDD
00457DD8|.E8 AFADFAFF   CALL up1.00402B8C
00457DDD|>33D2          XOR EDX,EDX
00457DDF|.52            PUSH EDX
00457DE0|.50            PUSH EAX
00457DE1|.A1 40B84500   MOV EAX,DWORD PTR DS:       ;ESI=00000540存入EAX
00457DE6|.99            CDQ                                 ;把EAX中的字的符号扩展到EDX中去
00457DE7|.030424      ADD EAX,DWORD PTR SS:          ;EAX=00000540+0000000C=0000054C
00457DEA|.135424 04   ADC EDX,DWORD PTR SS:      ;EDX=0000000
00457DEE|.71 05         JNO SHORT up1.00457DF5
00457DF0|.E8 97ADFAFF   CALL up1.00402B8C
00457DF5|>83C4 08       ADD ESP,8                           ;ESP=0012F978=0000000C+8=0012FBCC(地址

0012F980)
00457DF8|.50            PUSH EAX                            ;EAX=0000054C堆栈地址0012F97C
00457DF9|.C1F8 1F       SAR EAX,1F                        ;算术右移.(=SHR)
00457DFC|.3BC2          CMP EAX,EDX
00457DFE|.58            POP EAX                           ;出栈
00457DFF|.74 05         JE SHORT up1.00457E06
00457E01|.E8 7EADFAFF   CALL up1.00402B84                     真假码比较子程序,相等返回到:00457E33
00457E06|>A3 40B84500   MOV DWORD PTR DS:,EAX
00457E0B|.8D55 E4       LEA EDX,DWORD PTR SS:
00457E0E|.A1 40B84500   MOV EAX,DWORD PTR DS:
00457E13|.E8 2CF9FAFF   CALL up1.00407744
00457E18|.8B45 E4       MOV EAX,DWORD PTR SS:       ;堆栈 SS:=00D6B438, (ASCII

"1356")
00457E1B|.50            PUSH EAX
00457E1C|.8D55 FC       LEA EDX,DWORD PTR SS:
00457E1F|.8B83 DC020000 MOV EAX,DWORD PTR DS:
00457E25|.E8 B6C0FCFF   CALL up1.00423EE0
00457E2A|.8B55 FC       MOV EDX,DWORD PTR SS:      ;假注册码入EDX 00D6B44C ASCII "12345678"
00457E2D|.58            POP EAX                           ;堆栈 =00D6B438 (00D6B438),

ASCII "1356"
00457E2E|.E8 51BDFAFF   CALL up1.00403B84         ; 真假码比较子程序,返回到:00457E33
00457E33|.75 1A         JNZ SHORT up1.00457E4F            ;此处不能跳
00457E35|.6A 00         PUSH 0
00457E37|.B9 387F4500   MOV ECX,up1.00457F38                ;congratz !
00457E3C|.BA 447F4500   MOV EDX,up1.00457F44                ;you cracked the cff crackme #4 ! please

send your solution to [email protected] !

算法归纳为:

1.累加每位用户名ASCII值乘以定值2后的值,设为A。用户名必须大于6位,否则有错误提示。
2.用户名位数乘以定值2,设为B。
3.A+B得到的值转换成十进制,即为注册码。
例如:
用户名:wzwgpa
每位用户名ASCII值:w=77z=7aw=77g=67p=70a=61
A=77*2+7a*2+77*2+67*2+70*2+61*2=EE+F4+EE+CE+E0+C2=540
B=6*2=C
A+B=54C
54C成十进制,即为:1356

注册名wzwgpa
注册码1356


   还有许多地方不是很明白,有些地方分析得有错误,还望高手不吝赐教。谢谢!

[ 本帖最后由 wzwgp 于 2006-2-17 09:02 编辑 ]

冷血书生 发表于 2006-2-18 16:42:54

离成员不远了!

ld0825 发表于 2006-3-4 14:10:04

学习!学习!再学习!
页: [1]
查看完整版本: CrackMe#4破解学习笔记