一个简单的CrackMe分析
2014-04-03 23:09
417 查看
有一段时间没分析过CrackMe了,是不敢去分析,因为破解这东西,耗时间,现在大学正是学东西的时候,不敢耗太多时间进去。
在csdn上写破文有种不伦不类的感觉,没办法,大牛都去看雪发帖了。
入门级别CrackMe开始,根据这个CrackMe的加密过程写了个注册码生成的程序。
CrackMe个人觉得就是个小程序,只有注册的过程,我们不好拿软件来破解,软件首先要安装,然后再注册,而CrackMe不安装,就相当于把软件的注册部分分出来,就是crackMe了。有点挑逗的意思,come on,CrackMe。
一般我是在http://crackmes.de/users/deurus/humanoid_asm_keygenme/上找CrackMe的。这次的CrackMe也不例外。
运行的界面如下
当点击check的时候,如果不正确会什么也不提示。所以就不用像从MessageBox入手了,不过像这种软件实在太简单了,我们自己都能写,一个对话框,我们要找的就是对话框回调函数。用OD载入
00401064 E8 40030000 CALL KeyGenMe.004013A9
00401069 |. 6A 00 PUSH 0 ; /pModule = NULL
0040106B |. E8 90020000 CALL <JMP.&kernel32.GetModuleHandleA> ; \GetModuleHandleA
00401070 |. A3 B0614000 MOV DWORD PTR DS:[4061B0],EAX
00401075 |. 6A 00 PUSH 0 ; /lParam = NULL
00401077 |. 68 91104000 PUSH KeyGenMe.00401091 ; |DlgProc = KeyGenMe.00401091
0040107C |. 6A 00 PUSH 0 ; |hOwner = NULL
0040107E |. 6A 65 PUSH 65 ; |pTemplate = 65
00401080 |. FF35 B0614000 PUSH DWORD PTR DS:[4061B0] ; |hInst = NULL
00401086 |. E8 BD020000 CALL <JMP.&user32.DialogBoxParamA> ; \DialogBoxParamA
0040108B |. 50 PUSH EAX ; /ExitCode
0040108C \. E8 5D020000 CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
主程序就这样,再看看回调函数的反汇编代码
00401091 . 55 PUSH EBP
00401092 . 8BEC MOV EBP,ESP
00401094 . 81C4 FCFCFFFF ADD ESP,-304
0040109A . 817D 0C 110100>CMP DWORD PTR SS:[EBP+C],111
004010A1 . 0F85 E4010000 JNZ KeyGenMe.0040128B
004010A7 . 817D 10 EB0300>CMP DWORD PTR SS:[EBP+10],3EB
004010AE . 0F85 B0010000 JNZ KeyGenMe.00401264
004010B4 . C705 C4614000 >MOV DWORD PTR DS:[4061C4],0
004010BE . C705 C8614000 >MOV DWORD PTR DS:[4061C8],1 ; 获取username
004010C8 > 68 00010000 PUSH 100 ; /Count = 100 (256.)
004010CD . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100] ; |
004010D3 . 50 PUSH EAX ; |Buffer
004010D4 . 68 E9030000 PUSH 3E9 ; |ControlID = 3E9 (1001.)
004010D9 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004010DC . E8 73020000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004010E1 . 83F8 02 CMP EAX,2
004010E4 . 0F86 1A010000 JBE KeyGenMe.00401204 ; 最少三个字符
004010EA . 68 00010000 PUSH 100 ; /Length = 100 (256.)
004010EF . 8D85 00FEFFFF LEA EAX,DWORD PTR SS:[EBP-200] ; |
004010F5 . 50 PUSH EAX ; |Destination
004010F6 . E8 23020000 CALL <JMP.&kernel32.RtlZeroMemory> ; \RtlZeroMemory
004010FB . 8DBD 00FFFFFF LEA EDI,DWORD PTR SS:[EBP-100]
00401101 . EB 0E JMP SHORT KeyGenMe.00401111
00401103 > 803F 61 CMP BYTE PTR DS:[EDI],61
00401106 . 72 08 JB SHORT KeyGenMe.00401110
00401108 . 803F 7A CMP BYTE PTR DS:[EDI],7A
0040110B . 77 03 JA SHORT KeyGenMe.00401110
0040110D . 802F 20 SUB BYTE PTR DS:[EDI],20 ; 将用户名中的小写字符转换成大写字符
00401110 > 47 INC EDI
00401111 > 803F 00 CMP BYTE PTR DS:[EDI],0
00401114 .^75 ED JNZ SHORT KeyGenMe.00401103
00401116 . 33D2 XOR EDX,EDX
00401118 . 8DB5 00FFFFFF LEA ESI,DWORD PTR SS:[EBP-100]
0040111E . EB 49 JMP SHORT KeyGenMe.00401169
00401120 > 8D3D 8B604000 LEA EDI,DWORD PTR DS:[40608B]
00401126 . B9 FFFFFFFF MOV ECX,-1
0040112B . 0FB606 MOVZX EAX,BYTE PTR DS:[ESI]
0040112E . F2:AE REPNE SCAS BYTE PTR ES:[EDI] ;
00401130 . F7D1 NOT ECX ; ecx为扫描过后的字符数
00401132 . 49 DEC ECX
00401133 . 833D C4614000 >CMP DWORD PTR DS:[4061C4],1 ;
0040113A . 74 13 JE SHORT KeyGenMe.0040114F ;
0040113C . 0FB681 B060400>MOVZX EAX,BYTE PTR DS:[ECX+4060B0] ;
00401143 . C705 C4614000 >MOV DWORD PTR DS:[4061C4],1
0040114D . EB 11 JMP SHORT KeyGenMe.00401160
0040114F > 0FB681 D560400>MOVZX EAX,BYTE PTR DS:[ECX+4060D5] ;
00401156 . C705 C4614000 >MOV DWORD PTR DS:[4061C4],0
00401160 > 888415 00FEFFF>MOV BYTE PTR SS:[EBP+EDX-200],AL ;
00401167 . 42 INC EDX
00401168 . 46 INC ESI
00401169 > 803E 00 CMP BYTE PTR DS:[ESI],0
0040116C .^75 B2 JNZ SHORT KeyGenMe.00401120
0040116E . 8DB5 00FFFFFF LEA ESI,DWORD PTR SS:[EBP-100]
00401174 . 8B15 C4614000 MOV EDX,DWORD PTR DS:[4061C4]
0040117A . 33DB XOR EBX,EBX
0040117C . EB 15 JMP SHORT KeyGenMe.00401193
0040117E > 0FB606 MOVZX EAX,BYTE PTR DS:[ESI]
00401181 . 33C2 XOR EAX,EDX
00401183 . C1E0 0A SHL EAX,0A
00401186 . 35 F7D04E0A XOR EAX,0A4ED0F7
0040118B . 2D 9A020000 SUB EAX,29A
00401190 . 03D8 ADD EBX,EAX
00401192 . 46 INC ESI
00401193 > 803E 00 CMP BYTE PTR DS:[ESI],0
00401196 .^75 E6 JNZ SHORT KeyGenMe.0040117E
00401198 . 68 6F604000 PUSH KeyGenMe.0040606F ; /StringToAdd = "-%.d"
0040119D . 8D85 00FEFFFF LEA EAX,DWORD PTR SS:[EBP-200] ; |
004011A3 . 50 PUSH EAX ; |ConcatString
004011A4 . E8 81010000 CALL <JMP.&kernel32.lstrcatA> ; \lstrcatA
004011A9 . 53 PUSH EBX
004011AA . 8D85 00FEFFFF LEA EAX,DWORD PTR SS:[EBP-200] ; 将用户名的字符用整数输出
004011B0 . 50 PUSH EAX ; |Format
004011B1 . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100] ; |
004011B7 . 50 PUSH EAX ; |s
004011B8 . E8 85010000 CALL <JMP.&user32.wsprintfA> ; \wsprintfA
004011BD . 83C4 0C ADD ESP,0C
004011C0 . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100]
004011C6 . 50 PUSH EAX ; /String
004011C7 . E8 70010000 CALL <JMP.&kernel32.lstrlenA> ; \lstrlenA
004011CC . 83F8 18 CMP EAX,18
004011CF 76 11 JBE SHORT KeyGenMe.004011E2
004011D1 . 68 FA604000 PUSH KeyGenMe.004060FA ; /String2 = "Long Name"
004011D6 . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100] ; |
004011DC . 50 PUSH EAX ; |String1
004011DD . E8 54010000 CALL <JMP.&kernel32.lstrcpyA> ; \lstrcpyA
004011E2 > 833D C8614000 >CMP DWORD PTR DS:[4061C8],0
004011E9 . 74 17 JE SHORT KeyGenMe.00401202 ; 只有这个跳转实现了才能获取密码
004011EB . FF0D C8614000 DEC DWORD PTR DS:[4061C8]
004011F1 . C705 C4614000 >MOV DWORD PTR DS:[4061C4],1
004011FB .^E9 C8FEFFFF JMP KeyGenMe.004010C8
00401200 . EB 14 JMP SHORT KeyGenMe.00401216
00401202 > EB 12 JMP SHORT KeyGenMe.00401216
00401204 > 68 74604000 PUSH KeyGenMe.00406074 ; /Text = "Min 3 charts!"
00401209 . 68 EA030000 PUSH 3EA ; |ControlID = 3EA (1002.)
0040120E . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401211 . E8 50010000 CALL <JMP.&user32.SetDlgItemTextA> ; \SetDlgItemTextA
00401216 > 68 00010000 PUSH 100 ; /Count = 100 (256.)
0040121B . 8D85 00FDFFFF LEA EAX,DWORD PTR SS:[EBP-300] ; |
00401221 . 50 PUSH EAX ; |Buffer
00401222 . 68 EA030000 PUSH 3EA ; |ControlID = 3EA (1002.)
00401227 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040122A . E8 25010000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
0040122F . 8D85 00FDFFFF LEA EAX,DWORD PTR SS:[EBP-300] ; 获取密码
00401235 . 50 PUSH EAX ; /String2
00401236 . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100] ; |
0040123C . 50 PUSH EAX ; |String1
0040123D . E8 EE000000 CALL <JMP.&kernel32.lstrcmpA> ; \lstrcmpA
00401242 . 0BC0 OR EAX,EAX ; 判断是否是0
00401244 . 75 19 JNZ SHORT KeyGenMe.0040125F
00401246 . 6A 20 PUSH 20 ; /Style = MB_OK|MB_ICONQUESTION|MB_APPLMODAL
00401248 . 68 15614000 PUSH KeyGenMe.00406115 ; |Title = "Info"
0040124D . 68 0C614000 PUSH KeyGenMe.0040610C ; |Text = "Good boy"
00401252 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
00401255 . E8 00010000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
0040125A . E9 88000000 JMP KeyGenMe.004012E7
0040125F > E9 83000000 JMP KeyGenMe.004012E7
00401264 > 817D 10 EC0300>CMP DWORD PTR SS:[EBP+10],3EC
0040126B . 75 7A JNZ SHORT KeyGenMe.004012E7
0040126D . 6A 00 PUSH 0
0040126F . E8 35010000 CALL KeyGenMe.004013A9
00401274 . FF35 D0614000 PUSH DWORD PTR DS:[4061D0] ; /hMem = NULL
0040127A . E8 8D000000 CALL <JMP.&kernel32.GlobalFree> ; \GlobalFree
0040127F . 6A 00 PUSH 0 ; /Result = 0
00401281 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401284 . E8 C5000000 CALL <JMP.&user32.EndDialog> ; \EndDialog
00401289 . EB 5C JMP SHORT KeyGenMe.004012E7
0040128B > 837D 0C 10 CMP DWORD PTR SS:[EBP+C],10
0040128F . 75 0C JNZ SHORT KeyGenMe.0040129D
00401291 . 6A 00 PUSH 0 ; /Result = 0
00401293 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401296 . E8 B3000000 CALL <JMP.&user32.EndDialog> ; \EndDialog
0040129B . EB 4A JMP SHORT KeyGenMe.004012E7
0040129D > 817D 0C 100100>CMP DWORD PTR SS:[EBP+C],110
004012A4 . 75 25 JNZ SHORT KeyGenMe.004012CB
004012A6 . 68 B4614000 PUSH KeyGenMe.004061B4 ; /pLocaltime = KeyGenMe.004061B4
004012AB . E8 4A000000 CALL <JMP.&kernel32.GetLocalTime> ; \GetLocalTime
004012B0 . A1 B4614000 MOV EAX,DWORD PTR DS:[4061B4]
004012B5 . A1 B6614000 MOV EAX,DWORD PTR DS:[4061B6]
004012BA . A1 B8614000 MOV EAX,DWORD PTR DS:[4061B8]
004012BF . A1 BA614000 MOV EAX,DWORD PTR DS:[4061BA]
004012C4 . A1 BC614000 MOV EAX,DWORD PTR DS:[4061BC]
004012C9 . EB 1C JMP SHORT KeyGenMe.004012E7
004012CB > 817D 0C 010200>CMP DWORD PTR SS:[EBP+C],201
004012D2 . 75 13 JNZ SHORT KeyGenMe.004012E7
004012D4 . 8B45 14 MOV EAX,DWORD PTR SS:[EBP+14]
004012D7 . 50 PUSH EAX ; /lParam
004012D8 . 6A 02 PUSH 2 ; |wParam = 2
004012DA . 68 A1000000 PUSH 0A1 ; |Message = WM_NCLBUTTONDOWN
004012DF . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004012E2 . E8 79000000 CALL <JMP.&user32.PostMessageA> ; \PostMessageA
004012E7 > 33C0 XOR EAX,EAX
004012E9 . C9 LEAVE
004012EA . C2 1000 RETN 10
暴力破解这东西就不要说了,我们要做的是找到加密过程,然后根据这个加密过程我们写个注册机
我们直接在回调函数下断点。然后跟着走,获取用户名,然后用户名叫经过一系列加密,然后得出一个字符串,,和序列号比较,相等就对。我们的肯定不等那,相等的几率是非常小的。
下面我将自己在跟踪的过程中遇到的加密过程写下,
①获取username
②将username中的字母转换成大写
③进行第一次加密。
对于username中的单号字符,在key1密文中找对应的字符,至于索引的过程,索引号是这样来生成的,
0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z在这串字符中扫描到相等,然后记录下下标比如说A,对应的下标是10,那我就把第Key1中的第十个找出来。
对于username中的双号字符,在key2密文中找对应的字符,跟上面的方法是一样的。
④进行一系列的运算,其实也没几个运算,就像下面那样
00401174 . 8B15 C4614000 MOV EDX,DWORD PTR DS:[4061C4]
0040117A . 33DB XOR EBX,EBX
0040117C . EB 15 JMP SHORT KeyGenMe.00401193
0040117E > 0FB606 MOVZX EAX,BYTE PTR DS:[ESI]
00401181 . 33C2 XOR EAX,EDX
00401183 . C1E0 0A SHL EAX,0A
00401186 . 35 F7D04E0A XOR EAX,0A4ED0F7
0040118B . 2D 9A020000 SUB EAX,29A
00401190 . 03D8 ADD EBX,EAX
00401192 . 46 INC ESI
00401193 > 803E 00 CMP BYTE PTR DS:[ESI],0
00401196 .^75 E6 JNZ SHORT KeyGenMe.0040117E
迭代求出一个和放进ebx里面,作者还进行了一个比较容易被忽视的处理,00401174 . 8B15 C4614000 MOV EDX,DWORD PTR DS:[4061C4]这一行,个人觉得是用来判断用户名的长度是奇数还是偶数的,因为奇数和偶数加密的过程是不一样的,具体表现在这行指令00401181 . 33C2 XOR EAX,EDX
奇数和偶数edx的值不一样,具体看用vc写的一个控制台的注册码生成的,也没测试几组数据。还望大神指点
CrackMe可以去我的资源下载。
在csdn上写破文有种不伦不类的感觉,没办法,大牛都去看雪发帖了。
入门级别CrackMe开始,根据这个CrackMe的加密过程写了个注册码生成的程序。
CrackMe个人觉得就是个小程序,只有注册的过程,我们不好拿软件来破解,软件首先要安装,然后再注册,而CrackMe不安装,就相当于把软件的注册部分分出来,就是crackMe了。有点挑逗的意思,come on,CrackMe。
一般我是在http://crackmes.de/users/deurus/humanoid_asm_keygenme/上找CrackMe的。这次的CrackMe也不例外。
运行的界面如下
当点击check的时候,如果不正确会什么也不提示。所以就不用像从MessageBox入手了,不过像这种软件实在太简单了,我们自己都能写,一个对话框,我们要找的就是对话框回调函数。用OD载入
00401064 E8 40030000 CALL KeyGenMe.004013A9
00401069 |. 6A 00 PUSH 0 ; /pModule = NULL
0040106B |. E8 90020000 CALL <JMP.&kernel32.GetModuleHandleA> ; \GetModuleHandleA
00401070 |. A3 B0614000 MOV DWORD PTR DS:[4061B0],EAX
00401075 |. 6A 00 PUSH 0 ; /lParam = NULL
00401077 |. 68 91104000 PUSH KeyGenMe.00401091 ; |DlgProc = KeyGenMe.00401091
0040107C |. 6A 00 PUSH 0 ; |hOwner = NULL
0040107E |. 6A 65 PUSH 65 ; |pTemplate = 65
00401080 |. FF35 B0614000 PUSH DWORD PTR DS:[4061B0] ; |hInst = NULL
00401086 |. E8 BD020000 CALL <JMP.&user32.DialogBoxParamA> ; \DialogBoxParamA
0040108B |. 50 PUSH EAX ; /ExitCode
0040108C \. E8 5D020000 CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
主程序就这样,再看看回调函数的反汇编代码
00401091 . 55 PUSH EBP
00401092 . 8BEC MOV EBP,ESP
00401094 . 81C4 FCFCFFFF ADD ESP,-304
0040109A . 817D 0C 110100>CMP DWORD PTR SS:[EBP+C],111
004010A1 . 0F85 E4010000 JNZ KeyGenMe.0040128B
004010A7 . 817D 10 EB0300>CMP DWORD PTR SS:[EBP+10],3EB
004010AE . 0F85 B0010000 JNZ KeyGenMe.00401264
004010B4 . C705 C4614000 >MOV DWORD PTR DS:[4061C4],0
004010BE . C705 C8614000 >MOV DWORD PTR DS:[4061C8],1 ; 获取username
004010C8 > 68 00010000 PUSH 100 ; /Count = 100 (256.)
004010CD . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100] ; |
004010D3 . 50 PUSH EAX ; |Buffer
004010D4 . 68 E9030000 PUSH 3E9 ; |ControlID = 3E9 (1001.)
004010D9 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004010DC . E8 73020000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004010E1 . 83F8 02 CMP EAX,2
004010E4 . 0F86 1A010000 JBE KeyGenMe.00401204 ; 最少三个字符
004010EA . 68 00010000 PUSH 100 ; /Length = 100 (256.)
004010EF . 8D85 00FEFFFF LEA EAX,DWORD PTR SS:[EBP-200] ; |
004010F5 . 50 PUSH EAX ; |Destination
004010F6 . E8 23020000 CALL <JMP.&kernel32.RtlZeroMemory> ; \RtlZeroMemory
004010FB . 8DBD 00FFFFFF LEA EDI,DWORD PTR SS:[EBP-100]
00401101 . EB 0E JMP SHORT KeyGenMe.00401111
00401103 > 803F 61 CMP BYTE PTR DS:[EDI],61
00401106 . 72 08 JB SHORT KeyGenMe.00401110
00401108 . 803F 7A CMP BYTE PTR DS:[EDI],7A
0040110B . 77 03 JA SHORT KeyGenMe.00401110
0040110D . 802F 20 SUB BYTE PTR DS:[EDI],20 ; 将用户名中的小写字符转换成大写字符
00401110 > 47 INC EDI
00401111 > 803F 00 CMP BYTE PTR DS:[EDI],0
00401114 .^75 ED JNZ SHORT KeyGenMe.00401103
00401116 . 33D2 XOR EDX,EDX
00401118 . 8DB5 00FFFFFF LEA ESI,DWORD PTR SS:[EBP-100]
0040111E . EB 49 JMP SHORT KeyGenMe.00401169
00401120 > 8D3D 8B604000 LEA EDI,DWORD PTR DS:[40608B]
00401126 . B9 FFFFFFFF MOV ECX,-1
0040112B . 0FB606 MOVZX EAX,BYTE PTR DS:[ESI]
0040112E . F2:AE REPNE SCAS BYTE PTR ES:[EDI] ;
00401130 . F7D1 NOT ECX ; ecx为扫描过后的字符数
00401132 . 49 DEC ECX
00401133 . 833D C4614000 >CMP DWORD PTR DS:[4061C4],1 ;
0040113A . 74 13 JE SHORT KeyGenMe.0040114F ;
0040113C . 0FB681 B060400>MOVZX EAX,BYTE PTR DS:[ECX+4060B0] ;
00401143 . C705 C4614000 >MOV DWORD PTR DS:[4061C4],1
0040114D . EB 11 JMP SHORT KeyGenMe.00401160
0040114F > 0FB681 D560400>MOVZX EAX,BYTE PTR DS:[ECX+4060D5] ;
00401156 . C705 C4614000 >MOV DWORD PTR DS:[4061C4],0
00401160 > 888415 00FEFFF>MOV BYTE PTR SS:[EBP+EDX-200],AL ;
00401167 . 42 INC EDX
00401168 . 46 INC ESI
00401169 > 803E 00 CMP BYTE PTR DS:[ESI],0
0040116C .^75 B2 JNZ SHORT KeyGenMe.00401120
0040116E . 8DB5 00FFFFFF LEA ESI,DWORD PTR SS:[EBP-100]
00401174 . 8B15 C4614000 MOV EDX,DWORD PTR DS:[4061C4]
0040117A . 33DB XOR EBX,EBX
0040117C . EB 15 JMP SHORT KeyGenMe.00401193
0040117E > 0FB606 MOVZX EAX,BYTE PTR DS:[ESI]
00401181 . 33C2 XOR EAX,EDX
00401183 . C1E0 0A SHL EAX,0A
00401186 . 35 F7D04E0A XOR EAX,0A4ED0F7
0040118B . 2D 9A020000 SUB EAX,29A
00401190 . 03D8 ADD EBX,EAX
00401192 . 46 INC ESI
00401193 > 803E 00 CMP BYTE PTR DS:[ESI],0
00401196 .^75 E6 JNZ SHORT KeyGenMe.0040117E
00401198 . 68 6F604000 PUSH KeyGenMe.0040606F ; /StringToAdd = "-%.d"
0040119D . 8D85 00FEFFFF LEA EAX,DWORD PTR SS:[EBP-200] ; |
004011A3 . 50 PUSH EAX ; |ConcatString
004011A4 . E8 81010000 CALL <JMP.&kernel32.lstrcatA> ; \lstrcatA
004011A9 . 53 PUSH EBX
004011AA . 8D85 00FEFFFF LEA EAX,DWORD PTR SS:[EBP-200] ; 将用户名的字符用整数输出
004011B0 . 50 PUSH EAX ; |Format
004011B1 . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100] ; |
004011B7 . 50 PUSH EAX ; |s
004011B8 . E8 85010000 CALL <JMP.&user32.wsprintfA> ; \wsprintfA
004011BD . 83C4 0C ADD ESP,0C
004011C0 . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100]
004011C6 . 50 PUSH EAX ; /String
004011C7 . E8 70010000 CALL <JMP.&kernel32.lstrlenA> ; \lstrlenA
004011CC . 83F8 18 CMP EAX,18
004011CF 76 11 JBE SHORT KeyGenMe.004011E2
004011D1 . 68 FA604000 PUSH KeyGenMe.004060FA ; /String2 = "Long Name"
004011D6 . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100] ; |
004011DC . 50 PUSH EAX ; |String1
004011DD . E8 54010000 CALL <JMP.&kernel32.lstrcpyA> ; \lstrcpyA
004011E2 > 833D C8614000 >CMP DWORD PTR DS:[4061C8],0
004011E9 . 74 17 JE SHORT KeyGenMe.00401202 ; 只有这个跳转实现了才能获取密码
004011EB . FF0D C8614000 DEC DWORD PTR DS:[4061C8]
004011F1 . C705 C4614000 >MOV DWORD PTR DS:[4061C4],1
004011FB .^E9 C8FEFFFF JMP KeyGenMe.004010C8
00401200 . EB 14 JMP SHORT KeyGenMe.00401216
00401202 > EB 12 JMP SHORT KeyGenMe.00401216
00401204 > 68 74604000 PUSH KeyGenMe.00406074 ; /Text = "Min 3 charts!"
00401209 . 68 EA030000 PUSH 3EA ; |ControlID = 3EA (1002.)
0040120E . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401211 . E8 50010000 CALL <JMP.&user32.SetDlgItemTextA> ; \SetDlgItemTextA
00401216 > 68 00010000 PUSH 100 ; /Count = 100 (256.)
0040121B . 8D85 00FDFFFF LEA EAX,DWORD PTR SS:[EBP-300] ; |
00401221 . 50 PUSH EAX ; |Buffer
00401222 . 68 EA030000 PUSH 3EA ; |ControlID = 3EA (1002.)
00401227 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040122A . E8 25010000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
0040122F . 8D85 00FDFFFF LEA EAX,DWORD PTR SS:[EBP-300] ; 获取密码
00401235 . 50 PUSH EAX ; /String2
00401236 . 8D85 00FFFFFF LEA EAX,DWORD PTR SS:[EBP-100] ; |
0040123C . 50 PUSH EAX ; |String1
0040123D . E8 EE000000 CALL <JMP.&kernel32.lstrcmpA> ; \lstrcmpA
00401242 . 0BC0 OR EAX,EAX ; 判断是否是0
00401244 . 75 19 JNZ SHORT KeyGenMe.0040125F
00401246 . 6A 20 PUSH 20 ; /Style = MB_OK|MB_ICONQUESTION|MB_APPLMODAL
00401248 . 68 15614000 PUSH KeyGenMe.00406115 ; |Title = "Info"
0040124D . 68 0C614000 PUSH KeyGenMe.0040610C ; |Text = "Good boy"
00401252 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hOwner
00401255 . E8 00010000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
0040125A . E9 88000000 JMP KeyGenMe.004012E7
0040125F > E9 83000000 JMP KeyGenMe.004012E7
00401264 > 817D 10 EC0300>CMP DWORD PTR SS:[EBP+10],3EC
0040126B . 75 7A JNZ SHORT KeyGenMe.004012E7
0040126D . 6A 00 PUSH 0
0040126F . E8 35010000 CALL KeyGenMe.004013A9
00401274 . FF35 D0614000 PUSH DWORD PTR DS:[4061D0] ; /hMem = NULL
0040127A . E8 8D000000 CALL <JMP.&kernel32.GlobalFree> ; \GlobalFree
0040127F . 6A 00 PUSH 0 ; /Result = 0
00401281 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401284 . E8 C5000000 CALL <JMP.&user32.EndDialog> ; \EndDialog
00401289 . EB 5C JMP SHORT KeyGenMe.004012E7
0040128B > 837D 0C 10 CMP DWORD PTR SS:[EBP+C],10
0040128F . 75 0C JNZ SHORT KeyGenMe.0040129D
00401291 . 6A 00 PUSH 0 ; /Result = 0
00401293 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401296 . E8 B3000000 CALL <JMP.&user32.EndDialog> ; \EndDialog
0040129B . EB 4A JMP SHORT KeyGenMe.004012E7
0040129D > 817D 0C 100100>CMP DWORD PTR SS:[EBP+C],110
004012A4 . 75 25 JNZ SHORT KeyGenMe.004012CB
004012A6 . 68 B4614000 PUSH KeyGenMe.004061B4 ; /pLocaltime = KeyGenMe.004061B4
004012AB . E8 4A000000 CALL <JMP.&kernel32.GetLocalTime> ; \GetLocalTime
004012B0 . A1 B4614000 MOV EAX,DWORD PTR DS:[4061B4]
004012B5 . A1 B6614000 MOV EAX,DWORD PTR DS:[4061B6]
004012BA . A1 B8614000 MOV EAX,DWORD PTR DS:[4061B8]
004012BF . A1 BA614000 MOV EAX,DWORD PTR DS:[4061BA]
004012C4 . A1 BC614000 MOV EAX,DWORD PTR DS:[4061BC]
004012C9 . EB 1C JMP SHORT KeyGenMe.004012E7
004012CB > 817D 0C 010200>CMP DWORD PTR SS:[EBP+C],201
004012D2 . 75 13 JNZ SHORT KeyGenMe.004012E7
004012D4 . 8B45 14 MOV EAX,DWORD PTR SS:[EBP+14]
004012D7 . 50 PUSH EAX ; /lParam
004012D8 . 6A 02 PUSH 2 ; |wParam = 2
004012DA . 68 A1000000 PUSH 0A1 ; |Message = WM_NCLBUTTONDOWN
004012DF . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004012E2 . E8 79000000 CALL <JMP.&user32.PostMessageA> ; \PostMessageA
004012E7 > 33C0 XOR EAX,EAX
004012E9 . C9 LEAVE
004012EA . C2 1000 RETN 10
暴力破解这东西就不要说了,我们要做的是找到加密过程,然后根据这个加密过程我们写个注册机
我们直接在回调函数下断点。然后跟着走,获取用户名,然后用户名叫经过一系列加密,然后得出一个字符串,,和序列号比较,相等就对。我们的肯定不等那,相等的几率是非常小的。
下面我将自己在跟踪的过程中遇到的加密过程写下,
①获取username
②将username中的字母转换成大写
③进行第一次加密。
对于username中的单号字符,在key1密文中找对应的字符,至于索引的过程,索引号是这样来生成的,
0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z在这串字符中扫描到相等,然后记录下下标比如说A,对应的下标是10,那我就把第Key1中的第十个找出来。
对于username中的双号字符,在key2密文中找对应的字符,跟上面的方法是一样的。
④进行一系列的运算,其实也没几个运算,就像下面那样
00401174 . 8B15 C4614000 MOV EDX,DWORD PTR DS:[4061C4]
0040117A . 33DB XOR EBX,EBX
0040117C . EB 15 JMP SHORT KeyGenMe.00401193
0040117E > 0FB606 MOVZX EAX,BYTE PTR DS:[ESI]
00401181 . 33C2 XOR EAX,EDX
00401183 . C1E0 0A SHL EAX,0A
00401186 . 35 F7D04E0A XOR EAX,0A4ED0F7
0040118B . 2D 9A020000 SUB EAX,29A
00401190 . 03D8 ADD EBX,EAX
00401192 . 46 INC ESI
00401193 > 803E 00 CMP BYTE PTR DS:[ESI],0
00401196 .^75 E6 JNZ SHORT KeyGenMe.0040117E
迭代求出一个和放进ebx里面,作者还进行了一个比较容易被忽视的处理,00401174 . 8B15 C4614000 MOV EDX,DWORD PTR DS:[4061C4]这一行,个人觉得是用来判断用户名的长度是奇数还是偶数的,因为奇数和偶数加密的过程是不一样的,具体表现在这行指令00401181 . 33C2 XOR EAX,EDX
奇数和偶数edx的值不一样,具体看用vc写的一个控制台的注册码生成的,也没测试几组数据。还望大神指点
#include <stdio.h> #include <string.h> //密文1,用于单号字符的加密 char Key1[] = { 'o', '3', 'z', 'Y', 'z', 'a', 'I', '1', '9', '8', '2', 'T', 'v', '2', 'F', 'a', 's', 'g', 'j', 'k', 'k', 'j', 'h', 'k', 'j', 'l', 'J', 't', '5', 'D', 'p', 'e', '3', '2', 'A', 'x' }; //密文2,用于双号密文的加密 char Key2[] = { 'A', 'H', 'y', 'u', 'k', 'j', 's', 'd', 'f', 'k', 'j', 's', 'd', 'f', 'n', 'P', 'Q', 'U', '5', 'x', 'W', 'E', 'R', 'Y', '6', '7', '3', '4', '5', 'a', 'q', '9', 'n', 'F', 'y', 'R' }; //和用户名对比的表,用来索引密文中的字符 char source[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; int main() { char username[24]; int i = 0,length; long result = 0; long temp; printf("输入用户名(只限于3~24个字符):"); scanf("%s",username); length = strlen(username); printf("对应的密码是:"); //接下来是运算过程,将用户名加密,在通过用户名的每个字节进行相关的异或运算从而得到一个数字,转换成十进制之后就是了 while(username[i]!='\0') { int j = 0; if((i+1)%2 !=0) //单号字符处理,从Key1中扫描对比 { while( j<strlen(source) ) { if( source[j] == username[i] ) { //找Key[j] printf("%c",Key1[j]); break; } else j++; } } else //双号字符处理 { while( j<strlen(source) ) { if( source[j] == username[i] ) { //找Key[j] printf("%c",Key2[j]); break; } else j++; } } if(length%2 == 0) username[i] = username[i]^1; temp = username[i]<<0x0A ; //左移十位 temp = temp^0xa4ed0f7; //和0a4ed0f7进行异或运算 temp = temp - 0x29A; // result = result + temp; //这里就是EBX迭代的 过程 i++; } printf("-%d\n",result); return 0; }挺累的,破解这东西挺考验耐性和毅力,没耐性没毅力根本坚持不下来,我也只是偶尔练练而已。破文写的还真是破。思想在,表达出来有点问题,感觉代码表达出来的都比自己在这码字表达的清楚。跟我一样新手的朋友可以拿这个软件来玩玩,就觉得在反汇编里面走多了,慢慢路就好走了点
CrackMe可以去我的资源下载。
相关文章推荐
- 用ASP编写的加密和解密类
- 一些通用跳转地址,XXOXX的时候有点用
- 破解电信检测,突破多用户共享上网补丁包下载
- 密码破解全教程
- VBS脚本加密/解密VBS脚本(简易免杀版1.1)
- BAT加密工具 EncryBat 非编译型bat批处理加密方案与代码
- SQLServer 2008中的代码安全(一) 存储过程加密与安全上下文
- asp MD5加密方式使用建议
- C#对称加密与非对称加密实例
- vbs shellcode转换escape加密
- 加密web.config的方法分享
- VS2005 180天限制破解方法
- asp.net实现md5加密
- 教你如何解密js/vbs/vbscript加密的编码异处理小结
- 简单的加密css地址防止别人下载你的CSS文件的方法
- PHP中的加密功能
- PHP 加密与解密的斗争
- wiki-shan写的php在线加密的解密程序
- php下通过伪造http头破解防盗链的代码