潜水这么多年,看过很多大侠的文章 ,还有wynney的盗版破解教程,我认为该做出点贡献了,还有我有个疑问,
我看了 论坛精华9 里面的一些大侠的练习方式找不到啊,可否加一下小弟的QQ190037386.
大侠有softworm Riijj 红火蚁 。
首先,od载入程序 ,点击help ->register ,输入用户名字wfwfwfwf和注册码12345678,这时不要动,
在od下面的命令框种填入 bp MessageBoxA 回车下断点,然后点击crackme注册框的那个ok按钮,这是就
断在了MessageBoxA 这个api这里,这时候点击f12或者上面的那个暂停图标,再点击右边那个K按钮,也
就是看堆栈的按钮,看到了这里,
堆栈界面内容
Call stack of main thread
Address Stack Procedure / arguments Called from
Frame
0012FE8C 0040137D <jmp.&USER32.MessageBoxA> crackme.00401378
0012FEB4
0012FE90 000409A0 hOwner = 000409A0 ('CrackMe v1.0',
0012FE94 00402169 Text = "Incorrect!,Try Again"
0012FE98 00402160 Title = "Error! "
0012FE9C 00000030 Style = MB_OK|MB_ICONEXCLAMATION|M
0012FEA0 0040124A crackme.00401362 crackme.00401245
然后点击called from 列的 crackme.00401245 这里,因为上面那个crackme.00401378是调用
MessageBoxA的子程序,根据堆栈先进后出的原理,下面的crackme.00401245更接近关键的跳转来到这里
00401209 > \6A 00 push 0 ; /lParam = NULL
0040120B . 68 53124000 push 00401253 ; |DlgProc =
crackme.00401253
00401210 . FF75 08 push dword ptr [ebp+8] ; |hOwner
00401213 . 68 15214000 push 00402115 ; |dlg_regis
00401218 . FF35 CA204000 push dword ptr [4020CA] ; |hInst = 00400000
0040121E . E8 7D020000 call <jmp.&USER32.DialogBoxParamA> ; \DialogBoxParamA
00401223 . 83F8 00 cmp eax, 0
00401226 .^ 74 BE je short 004011E6
00401228 . 68 8E214000 push 0040218E ; ASCII "WFWFWFWF"
0040122D . E8 4C010000 call 0040137E
00401232 . 50 push eax
00401233 . 68 7E214000 push 0040217E ; ASCII "12345678"
00401238 . E8 9B010000 call 004013D8
0040123D . 83C4 04 add esp, 4
00401240 . 58 pop eax
00401241 . 3BC3 cmp eax, ebx
00401243 74 07 je short 0040124C
00401245 . E8 18010000 call 00401362 这里是填出错误提示
messagebox
0040124A .^ EB 9A jmp short 004011E6
0040124C > E8 FC000000 call 0040134D
00401245 这个地址的call 就是上面那个调用了MessageBoxA的call ,看上面的je跳过了这里,说明有
戏,我们在更上面的00401209下断点,重载,单步,看到0040122D 这个call的参数是“WFWFWFWF”说明
这个call跟用户名的处理有关系。00401238 这个地址的call的参数是我们的密码,那么这里就应该和我
们的密码的处理有关系。
这里是0040122D 这个call
0040137E /$ 8B7424 04 mov esi, dword ptr [esp+4] 将我们的用户名字符串地址给
esi
00401382 |. 56 push esi 将这个地址压人栈
00401383 |> 8A06 /mov al, byte ptr [esi] 把字符串第一个字节给al
00401385 |. 84C0 |test al, al 看看是不是0
00401387 |. 74 13 |je short 0040139C 如果相等就会到401245这个
call弹出错误MessageBoxA
00401389 |. 3C 41 |cmp al, 41 比较比ascii码41小么 或者说
是大写字母A以上的字母么
0040138B |. 72 1F |jb short 004013AC 不是,跳
0040138D |. 3C 5A |cmp al, 5A 比较ascii码5A么,也就是小于
Z么
0040138F |. 73 03 |jnb short 00401394 小于等于Z就说明是大写字母。
00401391 |. 46 |inc esi 转下一个字母
00401392 |.^ EB EF |jmp short 00401383 继续循环上面的步骤
00401394 |> E8 39000000 |call 004013D2 如果不是大写字母这里改成大
写字母
00401399 |. 46 |inc esi 转下一个字母
0040139A |.^ EB E7 \jmp short 00401383 退出这个call
0040139C |> 5E pop esi
0040139D |. E8 20000000 call 004013C2 这里将所有的大写字母的ascii
码相加
004013A2 |. 81F7 78560000 xor edi, 5678
004013A8 |. 8BC7 mov eax, edi
004013AA |. EB 15 jmp short 004013C1
004013AC |> 5E pop esi
004013AD |. 6A 30 push 30 ; /Style =
MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL
004013AF |. 68 60214000 push 00402160 ; |error!
004013B4 |. 68 69214000 push 00402169 ; |incorrect!,try
again
004013B9 |. FF75 08 push dword ptr [ebp+8] ; |hOwner
004013BC |. E8 79000000 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
004013C1 \> C3 retn
这里是401238的call
004013D8 /$ 33C0 xor eax, eax 清零
004013DA |. 33FF xor edi, edi 清零
004013DC |. 33DB xor ebx, ebx 清零
004013DE |. 8B7424 04 mov esi, dword ptr [esp+4] 把密码字符串地址给esi
004013E2 |> B0 0A /mov al, 0A 把0A 数字给al
004013E4 |. 8A1E |mov bl, byte ptr [esi] 把第一位密码给bl
004013E6 |. 84DB |test bl, bl 是不是0
004013E8 |. 74 0B |je short 004013F5 0就弹错
004013EA |. 80EB 30 |sub bl, 30 减30h 变成数字1
004013ED |. 0FAFF8 |imul edi, eax 有符号乘以Ah
004013F0 |. 03FB |add edi, ebx 加上这个1
004013F2 |. 46 |inc esi 下一位密码
004013F3 |.^ EB ED \jmp short 004013E2 跳上去,继续循环
004013F5 |> 81F7 34120000 xor edi, 1234
004013FB |. 8BDF mov ebx, edi
这里是401241 的cmp eax ebx,就是说,eax 是0040122D的结果,结果含义是将字符名字变大写后,
ascii码相加,再与5678h抑或,ebx是401238的结果,结果含义是 假如每位密码为n, edi=n+edi*A,结
果就是edi,再与1234抑或。都是16进制数,再传给ebx自己理解,语言实在解释很难, 然后将eax与
ebx相比较,如果想等就注册成功。注册机的机理是将用户名的每位字母ascii码相加,然后除以A取余。
看我的C#源码吧。语言解释很痛苦。看我的C#源码吧。C#是注册机源码
完成
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课