能力值:
( LV2,RANK:10 )
|
-
-
2 楼
1、不会分析算法,也没比较出什么来。只有爆了。
不过蒙对了一个(绝不是算出来的)。用户hanyu1 注册码9527888(hanyu和9527888都在程序里,我就在用户hanyu后面加了个字符就行了,加什么都行。这么多天了,蒙对了一个 )
灰色铵钮,下bp EnableWindow断,返到后向上找push 0(0401513处)改成1
确定变亮。
2、不用找字符(找的话更快),bp MessageBoxA断下,返回后向上找到”别灰心,继续努力“看是从哪个地方跳过来的。改了他就爆了。我是0401727 jnz改je。nop掉不行!
看来还得慢慢学算法。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
见鬼了。用注册码注册了以后,在爆就不行了。为什么。只好重起了。
|
能力值:
( LV8,RANK:130 )
|
-
-
4 楼
用资源工具找到‘确定’的标志符ID为1002(3EAH)
载入到OD~~ Ctrl+F 查找命令‘PUSH 3EA’
找到后将上面控制标志的‘PUSH 0’改为‘‘PUSH 1’
保存后灰色按钮解除~~~~
破解的方法也比较多~~ 字符串也全部可见~~~
用户名2位以上且第一位是‘h’(但排除hanyu)
注册码固定为9527888
错误的地方请大虾指教
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
标志符ID为1002(3EAH)
1002咋算成3EAH,用什么算不会。谢谢。
明白了1002是十进制,要换成十六进制的。H是十六进制代表?
|
能力值:
( LV6,RANK:90 )
|
-
-
6 楼
蚊香大侠感觉有点模糊!能说清楚点么!用你的方法好像查找不了啊!狂汗!弱弱!
|
能力值:
( LV8,RANK:130 )
|
-
-
7 楼
绝对菜鸟~~~
<加密与解密>第三版(第一次印刷)116页
|
能力值:
( LV6,RANK:90 )
|
-
-
8 楼
BOOL EnableWindow(HWND hWnd,BOOL bEnable)
push 0 改 push 1其实就是改了调用这个函数的第2个参数。0为False 其他数为True
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
呵呵,强暴了~~~
|
能力值:
( LV3,RANK:20 )
|
-
-
10 楼
0040173D > \68 20304000 push 00403020 ; 别灰心,继续努力!
|
能力值:
( LV9,RANK:180 )
|
-
-
11 楼
1.先在用户名输入 William , 此举可使[确定]按钮 Enable
2.然后用户名只要大于 hanyu (例如: z ' hb ' hao), SN 为 9527888
即会显示注册成功
|
能力值:
( LV9,RANK:200 )
|
-
-
12 楼
11楼的回答是最正确的。^_^
学习了。
|
能力值:
( LV8,RANK:130 )
|
-
-
13 楼
[QUOTE=sessiondiy;509357]1.先在用户名输入 William , 此举可使[确定]按钮 Enable
2.然后用户名只要大于 hanyu (例如: z ' hb ' hao), SN 为 9527888
即会显示注册成功[/QUOTE]
严重学习了
|
能力值:
( LV4,RANK:45 )
|
-
-
14 楼
两处地方修改就能爆破
或者使这两个地方都不能实现跳转就可以了
004016E7 . /75 50 jnz short CrackMe.00401739
用户名和hanyu比较---------------(1)第一跳的内容
要求比hanyu大呵呵小的话直接失败------------------就比较第一字母即可
用户名2位以上且第一位是‘h’(但排除hanyu)---------------------这个我用haha 测试过不可以
判断条件好象是判断第一个字母是否大于h -------------并没有要求位数是多少---------一个字母的z测试可以注册
另外当第一字母为h时判断的要求为第二个字母是否大于a ----he测试通过
当第二个字母为a 的时候判断第三个字母是否大于n-----------hao测试通过
可以测试的是只有一个字母z作为用户名 不信的话可以测试
这个判断可以推测结构的
00401727 . /75 14 jnz short CrackMe.0040173D
这个比较是不断的循环判断是否为 9527888---------------(2)第二跳的内容
只要不一致就跳,呵呵跟踪起来对理解汇编很有好处
所以用户名为第一个字母大于h
注册码固定 9527888
先在用户名输入 William , 此举可使[确定]按钮 Enable 完全正确
直接nop掉这两个关键遍可以爆破 综合上面的情况
这个CM应该是用户名是逐层判断的
第一个字母是否大于h
另外当第一字母为h时判断的要求为第二个字母是否大于a
当第二个字母为a 的时候判断第三个字母是否大于n----------对照测试的结果 欢迎大家把这个CM直接写出来基本上结构很明晰了
依次类推
注册码为固定
|
能力值:
( LV13,RANK:760 )
|
-
-
15 楼
看来还是得有点耐心才行啊,我也没注意到William这个东西,晕!
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
玩了下,贴答案了。
首先,玩的时候没有看其他老师的答案
贴个图看看
这个是我做完的作业。
CrackMe_QFLY.zip
顺便AD哈,偶博客 http://www.qfly.cn,没事来踩脚
看了下,按钮是灰的。于是bp EnableWindow,跟到了一处
00401511 . FFD7 call edi ; \SendMessageA 00401513 . 6A 00 push 0 00401515 . 68 EA030000 push 3EA 0040151A . 8BCE mov ecx, esi 0040151C . E8 FB040000 call <jmp.&MFC42.#3092_CWnd::GetDlgIt>;这里取按钮句柄 00401521 . 8BC8 mov ecx, eax 00401523 . E8 EE040000 call <jmp.&MFC42.#2642_CWnd::EnableWi> ;就是这里灰了按钮 00401528 . 8B4C24 0C mov ecx, dword ptr [esp+C]
仔细从上面看看,00401513 push 0估计是EnableWindow的参数,0是FALSE,当然灰了,改成1即改成push 1,试了下,按钮果然亮了。
不过想了想,似乎不怎么完美,为什么呢?可以看出,这段代码首先用GetDlgItem取了按钮的Handle,然后给EnableWindow让他吧按钮灰掉,哼哼,明显多此一举呀,于是,最节省的办法jmp他,于是有了以下修改。
00401511 . FFD7 call edi ; \SendMessageA 00401513 EB 13 jmp short 00401528 ; (initial cpu selection) 00401515 68 EA030000 push 3EA 0040151A 8BCE mov ecx, esi 0040151C E8 FB040000 call <jmp.&MFC42.#3092_CWnd::GetDlgIt> 00401521 8BC8 mov ecx, eax 00401523 E8 EE040000 call <jmp.&MFC42.#2642_CWnd::EnableWi> 00401528 . 8B4C24 0C mov ecx, dword ptr [esp+C]
这样的话,蓝色部分的代码(就是上面分析的功能就永远不可能被执行了,嘿嘿~~~,还能节省写CPU时间........高手别砸)
按钮亮了就好办了,习惯性点了哈,弹出MessageBox,虽然说楼主不让用字符串搜索,还是偷偷用了下,就看到了关键代码,下面只吧后面用到的贴出来。
004016E4 > \83F8 01 cmp eax, 1 004016E7 . 75 50 jnz short 00401739 ;这里跳走就Game Over了 004016E9 . 8B87 E8000000 mov eax, dword ptr [edi+E8] 004016EF . BE 44304000 mov esi, 00403044 ; ASCII "9527888" 004016F4 > 8A10 mov dl, byte ptr [eax] ;看到了吧,上面就是注册码了 004016F6 . 8A1E mov bl, byte ptr [esi] 004016F8 . 8ACA mov cl, dl 004016FA . 3AD3 cmp dl, bl 004016FC . 75 1E jnz short 0040171C 004016FE . 84C9 test cl, cl 00401700 . 74 16 je short 00401718 00401702 . 8A50 01 mov dl, byte ptr [eax+1] 00401705 . 8A5E 01 mov bl, byte ptr [esi+1] 00401708 . 8ACA mov cl, dl 0040170A . 3AD3 cmp dl, bl 0040170C . 75 0E jnz short 0040171C 0040170E . 83C0 02 add eax, 2 00401711 . 83C6 02 add esi, 2 00401714 . 84C9 test cl, cl 00401716 .^ 75 DC jnz short 004016F4 00401718 > 33C0 xor eax, eax 0040171A . EB 05 jmp short 00401721 0040171C > 1BC0 sbb eax, eax 0040171E . 83D8 FF sbb eax, -1 00401721 > 85C0 test eax, eax 00401723 . 6A 00 push 0 00401725 . 6A 00 push 0 00401727 . 75 14 jnz short 0040173D 00401729 . 68 34304000 push 00403034 0040172E . 8BCF mov ecx, edi 00401730 . E8 11030000 call <jmp.&MFC42.#4224_CWnd::MessageB> ;这里弹出正确提示 00401735 . 5F pop edi 00401736 . 5E pop esi 00401737 . 5B pop ebx 00401738 . C3 retn
知道正确注册码,原来是固定的,“9527888”,不过楼猪说要自曝
从上到下,先NOP掉跳走就Over的地方。
然后在能看到真注册码的语句以后的地方,选些地方让他自曝注册码,这里要用到注册码在内存中的地址,00403044,OD中直接能看到,上面的程序中也有,看004016EF。
偶选了004016F8,没撒原因,其实你可以直接从004016EF开始。这样的话程序不会执行多余的语句。偶选的地方前面还有几条对俺们目标无用的语句。
至于加什么代码才能弹出一个MessageBox,偶偷懒了
下面不是有提示注册码正确的地方吗,抄上来,OK?
就是下面的红色的地方。
最后别忘了用jmp跳过无用的代码。
不说了,动手了。
004016E4 > \83F8 01 cmp eax, 1 004016E7 90 nop ;对比上面的代码,这里跳走就Over了 004016E8 90 nop ;干脆NOP掉,在让你跳,嘿嘿~~ 004016E9 . 8B87 E8000000 mov eax, dword ptr [edi+E8] 004016EF . BE 44304000 mov esi, 00403044 ; 9527888hanyu 004016F4 > 8A10 mov dl, byte ptr [eax] 004016F6 . 8A1E mov bl, byte ptr [esi] 004016F8 6A 00 push 0 004016FA 6A 00 push 0 004016FC 68 44304000 push 00403044 ; ASCII "9527888" 00401701 8BCF mov ecx, edi 00401703 E8 3E030000 call <jmp.&MFC42.#4224_CWnd::MessageB> 00401708 EB 19 jmp short 00401723 0040170A . 3AD3 cmp dl, bl 0040170C . 75 0E jnz short 0040171C 0040170E . 83C0 02 add eax, 2 00401711 . 83C6 02 add esi, 2 00401714 . 84C9 test cl, cl 00401716 .^ 75 DC jnz short 004016F4 00401718 > 33C0 xor eax, eax 0040171A . EB 05 jmp short 00401721 0040171C > 1BC0 sbb eax, eax 0040171E . 83D8 FF sbb eax, -1 00401721 > 85C0 test eax, eax 00401723 . 6A 00 push 0 00401725 . 6A 00 push 0 00401727 90 nop 00401728 90 nop 00401729 68 34304000 push 00403034 ; 恭喜你成功了! 0040172E . 8BCF mov ecx, edi 00401730 . E8 11030000 call <jmp.&MFC42.#4224_CWnd::MessageB> 00401735 . 5F pop edi 00401736 . 5E pop esi 00401737 . 5B pop ebx 00401738 . C3 retn
就这样,OK了。
最后声明,小菜一个,各位NBer多指正。
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
[QUOTE=;]...[/QUOTE]
你们不知道hanyu 是通过什么判断出这个的 还有11楼的William是什么意思
|
能力值:
( LV9,RANK:180 )
|
-
-
18 楼
username.OnChange()
if username = 'william' then Button.Enable:= True;
Button.OnClick();
if username <= 'hanyu' then ShowMessage('别灰心');
|
能力值:
( LV4,RANK:45 )
|
-
-
19 楼
大家干脆把代码全部逆出来吧
算法什么都明了了.
原来的爆破注册机什么的都没难度了
注册原理不难的
用户名 z 注册码 9527888 可以注册
用户名 he 注册码 9527888 可以注册
用户名 hao 注册码 9527888 可以注册
具体的在上面我一一测试过了 汇编代码 似懂非懂
算法 注册机制作起来应该很简单的
整个算法 框架也完全可以看的明白的
呵呵大家一起逆向整个CM吧
|
能力值:
( LV9,RANK:180 )
|
-
-
20 楼
支持偶像, 就你来吧
|
能力值:
( LV6,RANK:90 )
|
-
-
21 楼
膜拜看汇编逆出C++的MFC!
|
能力值:
( LV2,RANK:10 )
|
-
-
22 楼
学习了,楼主
|
能力值:
( LV2,RANK:10 )
|
-
-
23 楼
username.OnChange() if username = 'william' then Button.Enable:= True;
我在postquitmessage下无意中翻到这几个字符 后来我发现第一个输入框里的字符改变后,会去跟william比较
|
能力值:
( LV4,RANK:50 )
|
-
-
24 楼
工具:OD
1.载入主体后,CTRL+G 断点 EnableWindow.
2.F9 run .
3.跳入断点后,ALT+F9返回用户代码。
4.调EnableWindow 函数之前,调用了GetDlgItem取的了"确定“按钮的句柄。再往上看压入2个参数, 参数1 HWND hWnd,
参数2 BOOL bEnable,根据参数入栈规则,很好就找到PUSH 0,因此改为PUSH 1使“确定”按钮有效。
5.断点MessageBoxA,随便输入用户名和密码,然后点确认。进入断点后按ALT+F9返回用户代码。
6.向上分析,修改004016E7 为JE SHORT 00401739 ,往下继续,修改004016FC 为 JE SHORT 0040171C
继续,修改00401727 为 JE SHORT 00401730.
7.OK 爆破
第6步骤修改太麻烦,也可以修改直接一步跳转到位。菜鸟分析,见笑。
|
能力值:
(RANK:350 )
|
-
-
25 楼
|
|
|