【文章标题】: 金度美案找出注册码,希望哪位大侠能帮我简单分析下算法
【文章作者】: macsnk
【作者邮箱】: macsnooker@qq.com
【软件名称】: 金度美案2004
【软件大小】: 2.69MB
【下载地址】: 自己搜索下载
【加壳方式】: 无壳,庆幸:>
【保护方式】: 注册码+似乎有功能限制
【编写语言】: Microsoft Visual C++ 6.0
【使用工具】: peid v0.92;Ollydbg v1.10;W32asm无极版
【操作平台】: xp
【软件介绍】: 一款简单方便的图形化设计表达软件
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
说明:我是一个小菜鸟,这也是我第一次写破文,不到之处还请原谅。
美案,英文名叫PrettyCase。是一款简单方便的图形化设计表达软件。使用美案辅助您完成精彩的图形设计工作,
包括"工作流程"、"组织结构"、"网络架构"、"建筑设计"、"电子电路"、"计划表格"甚至"城市规划", 美案都得心应手。
首先用PEiD查壳,无壳,Microsoft Visual C++ 6.0 [Debug] 编译。省了一个步骤了。好,继续。。
接下来进行试注册,打开软件,弹出提示注册框。输入注册信息:
注册名称:macsnk
注册号码:97979797
弹出注册失败信息:“无效注册码,请再检查一下输入内容”。ok!既然弹出提示信息那就好办。
现在拿出静态分析利器,我们无敌的W32asm,我用的是无极版,我们点击PE信息-->字符串参考,查找“无效注册码,
请再检查一下输入内容”字符串。看到光标停在00430509处,拿笔记住这个数值。
* Possible StringData Ref from Data Obj ->"无效注册码,请再检查一下输入内容。"
|
:00430509 68DC6B4500 push 00456BDC
:0043050E 8BCE mov ecx, esi
继续向上看,我们能看见这个:
* Possible StringData Ref from Data Obj ->"注册成功,谢谢您对本产品的支持。"
|
:004304AD 68306C4500 push 00456C30
:004304B2 8BCE mov ecx, esi
:004304B4 C6057C75450001 mov byte ptr [0045757C], 01
竟然出现了注册成功的提示信息,现在很令人兴奋啊。。。
继续向上找我们就能找到这个:
* Reference To: MSVCRT._mbscmp, Ord:0159h
|
:00430412 FF15F8894400 Call dword ptr [004489F8]
:00430418 83C408 add esp, 00000008
:0043041B 85C0 test eax, eax
:0043041D 0F85E2000000 jne 00430505 ///我们可以看出,是从这里跳到430505位置然后弹出错误窗口的
:00430423 8B3F mov edi, dword ptr [edi]
:00430425 8D4C2428 lea ecx, dword ptr [esp+28]
:00430429 57 push edi
那么现在打开Ollydbg v1.10准备进行分析。我们都知道从错误信息往上找就能找到是因为什么错误跳到这里来的。
现在ctrl+G调处查找,输入430509,则光标停在430509处。我把00430509以上我们要的那部分代码复制下来以便分析。
:00430412 FF15F8894400 Call dword ptr [004489F8] ///这个就是关键Call了,应该是读取输入的密码
:00430418 83C408 add esp, 00000008
:0043041B 85C0 test eax, eax ///测试eax
:0043041D 0F85E2000000 jne 00430505 ///===>爆破点 PS:jne在汇编中是不相等就转移的意思。
:00430423 8B3F mov edi, dword ptr [edi]
:00430425 8D4C2428 lea ecx, dword ptr [esp+28]
:00430429 57 push edi
==========================================================================================================
我们在0043412处点F2下断点,然后点F9运行程序,然后输入我们的假码
注册名称:macsnk
注册号码:97979797
确定后程序停在了断点位置,这时,看右上的寄存器窗口或者右下的窗口,都显示出了正确的注册码
|s1 = "99E87D374F3FA6E95DE3AA339D781899"
99E87D374F3FA6E95DE3AA339D781899这个字符串就是真正的注册码了
============================================================================================================
如果只想得到注册码,到这里就结束了。。。。。。。
但是我们是为了研究程序,所以我们继续来分析程序:
* Reference To: MSVCRT.sprintf, Ord:02B2h
|
:0043042A 8B3DF4894400 mov edi, dword ptr [004489F4]
:00430430 51 push ecx
:00430431 FFD7 call edi
:00430433 8B4664 mov eax, dword ptr [esi+64]
:00430436 8D542458 lea edx, dword ptr [esp+58]
:0043043A 50 push eax
:0043043B 52 push edx
:0043043C FFD7 call edi
:0043043E 83C410 add esp, 00000010
:00430441 8D4C2418 lea ecx, dword ptr [esp+18]
* Reference To: MFC42.Ordinal:0162, Ord:0162h
|
:00430445 E8E4230100 Call 0044282E
:0043044A 8D4C2408 lea ecx, dword ptr [esp+08]
:0043044E C684248000000003 mov byte ptr [esp+00000080], 03
* Reference To: MFC42.Ordinal:021C, Ord:021Ch
|
:00430456 E8D11F0100 Call 0044242C
:0043045B A1948A4500 mov eax, dword ptr [00458A94]
:00430460 8D4C2408 lea ecx, dword ptr [esp+08]
:00430464 50 push eax
* Possible StringData Ref from Data Obj ->"%s\reginfo.dat" ///程序走到这里,在程序文件夹生成了一个dat文件,用来保存注
册信息
|
:00430465 68F0684500 push 004568F0
:0043046A 51 push ecx
:0043046B C684248C00000004 mov byte ptr [esp+0000008C], 04
* Reference To: MFC42.Ordinal:0B02, Ord:0B02h
|
:00430473 E8AE1F0100 Call 00442426
:00430478 8B542414 mov edx, dword ptr [esp+14]
:0043047C 83C40C add esp, 0000000C
:0043047F 8D4C2418 lea ecx, dword ptr [esp+18]
:00430483 6A00 push 00000000
:00430485 6801100000 push 00001001
:0043048A 52 push edx
* Reference To: MFC42.Ordinal:1442, Ord:1442h
|
:0043048B E898230100 Call 00442828
:00430490 8D442428 lea eax, dword ptr [esp+28]
:00430494 6A50 push 00000050
:00430496 50 push eax
:00430497 8D4C2420 lea ecx, dword ptr [esp+20]
* Reference To: MFC42.Ordinal:18F1, Ord:18F1h
|
:0043049B E852260100 Call 00442AF2
:004304A0 8D4C2418 lea ecx, dword ptr [esp+18]
* Reference To: MFC42.Ordinal:07BB, Ord:07BBh
|
:004304A4 E86D230100 Call 00442816
:004304A9 6A00 push 00000000
:004304AB 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"注册成功,谢谢您对本产品的支持。" ///提示注册成功了。
|
:004304AD 68306C4500 push 00456C30
:004304B2 8BCE mov ecx, esi
:004304B4 C6057C75450001 mov byte ptr [0045757C], 01
* Reference To: MFC42.Ordinal:1080, Ord:1080h
|
:004304BB E878220100 Call 00442738
:004304C0 6A01 push 00000001
:004304C2 8BCE mov ecx, esi
* Reference To: MFC42.Ordinal:0A55, Ord:0A55h
|
:004304C4 E8691F0100 Call 00442432
:004304C9 6A00 push 00000000
:004304CB 6A00 push 00000000
:004304CD 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"http://prettycase.goldlimit.com/regcomplete.ht" ///到这里程序弹出浏览器
访问软件的注册成功网站
->"m"
|
:004304CF 68006C4500 push 00456C00
* Possible StringData Ref from Data Obj ->"Open"
|
:004304D4 68A0634500 push 004563A0
:004304D9 6A00 push 00000000
* Reference To: SHELL32.ShellExecuteA, Ord:0072h
|
:004304DB FF15708A4400 Call dword ptr [00448A70]
:004304E1 8D4C2408 lea ecx, dword ptr [esp+08]
:004304E5 C684248000000003 mov byte ptr [esp+00000080], 03
* Reference To: MFC42.Ordinal:0320, Ord:0320h
|
:004304ED E8281F0100 Call 0044241A
:004304F2 8D4C2418 lea ecx, dword ptr [esp+18]
:004304F6 C684248000000002 mov byte ptr [esp+00000080], 02
* Reference To: MFC42.Ordinal:0299, Ord:0299h
|
:004304FE E80D230100 Call 00442810
:00430503 EB10 jmp 00430515
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0043041D(C)
|
:00430505 6A00 push 00000000
:00430507 6A00 push 00000000
* Possible StringData Ref from Data Obj ->"无效注册码,请再检查一下输入内容。" ///这里是坟墓
|
:00430509 68DC6B4500 push 00456BDC
:0043050E 8BCE mov ecx, esi
=============================================================================================================
=============================================================================================================
程序断点以后的部分就看完了,程序是先干什么后干什么我们也知道了。
下面就是我遇到的问题,一直想研究一下程序的算法,但是现在也没看明白。不知道程序是怎么算的。
在断点之前,我们能看到这段程序:
00430380 . 6A FF PUSH -1
00430382 . 68 A8784400 PUSH PrettyCa.004478A8 ; SE handler installation
///把4478a8的值放入栈中
==================================================================================================
我们来看看4478a8是什么:
004478A8 $ B8 D02A4500 MOV EAX,PrettyCa.00452AD0 ; Structured exception handler
原来是读取输入的用户名,放入eax中
==================================================================================================
00430387 . 64:A1 00000000 MOV EAX,DWORD PTR FS:[0] ///FS传送到eax mov指令就是把逗号后的值传送到逗号前中
0043038D . 50 PUSH EAX ///eax进栈 push指令就是进栈的意思
0043038E . 64:8925 000000>MOV DWORD PTR FS:[0],ESP
00430395 . 83EC 70 SUB ESP,70 ///esp减去就是输入的用户名减去70??
sub指令就是逗号前减逗号后的值赋予到逗号
前的寄存器中
00430398 . 56 PUSH ESI
00430399 . 8BF1 MOV ESI,ECX
0043039B . 57 PUSH EDI
0043039C . 8D4C24 10 LEA ECX,DWORD PTR SS:[ESP+10] ///取esp的前十位有效地址放到ecx中???虽然知道lea的意思
但是不确定是不是这这么解释,请大虾告知
lea指令就是把逗号后的有效地址送到逗号前的指定寄存器中
004303A0 . E8 87200100 CALL <JMP.&MFC42.#540> ///跟进后是jmp无条件转移到00448848
call指令是调用子程序命令
jmp指令时无条件转移命令
004303A5 . 68 546C4500 PUSH PrettyCa.00456C54 ; ASCII "PCPER"
004303AA . 8D4C24 14 LEA ECX,DWORD PTR SS:[ESP+14]
004303AE . C78424 8400000>MOV DWORD PTR SS:[ESP+84],0
004303B9 . E8 86230100 CALL <JMP.&MFC42.#860> ///转移到00448324
004303BE . 6A 01 PUSH 1
004303C0 . 8BCE MOV ECX,ESI
004303C2 . E8 71200100 CALL <JMP.&MFC42.#6334> ///转移到0044892c
004303C7 . 8D7E 60 LEA EDI,DWORD PTR DS:[ESI+60]
004303CA . 8D4424 10 LEA EAX,DWORD PTR SS:[ESP+10]
004303CE . 57 PUSH EDI
004303CF . 8D4C24 18 LEA ECX,DWORD PTR SS:[ESP+18]
004303D3 . 50 PUSH EAX
004303D4 . 51 PUSH ECX
004303D5 . E8 40230100 CALL <JMP.&MFC42.#922> ///转移到00448308
004303DA . 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14]
004303DE . 8D5424 0C LEA EDX,DWORD PTR SS:[ESP+C]
004303E2 . C68424 8000000>MOV BYTE PTR SS:[ESP+80],1
004303EA . 8B48 F8 MOV ECX,DWORD PTR DS:[EAX-8]
004303ED . 51 PUSH ECX
004303EE . 50 PUSH EAX
004303EF . 52 PUSH EDX
004303F0 . E8 0B07FFFF CALL PrettyCa.00420B00 ///这个call跟过去以后不知道是做了什么运算,希望得到指点。
我在下面贴出来代码。。。
004303F5 . 83C4 0C ADD ESP,0C ///ESP加上0C的值放入esp add指令就是两个值相加放入逗号前的
寄存器中
004303F8 . 8D4C24 0C LEA ECX,DWORD PTR SS:[ESP+C]
004303FC . C68424 8000000>MOV BYTE PTR SS:[ESP+80],2
00430404 . E8 792A0100 CALL <JMP.&MFC42.#4204> ///转移到00448838
00430409 . 8B46 64 MOV EAX,DWORD PTR DS:[ESI+64]
0043040C . 50 PUSH EAX ; /s2
0043040D . 8B4424 10 MOV EAX,DWORD PTR SS:[ESP+10] ; |
00430411 . 50 PUSH EAX ; |s1
00430412 FF15 F8894400 CALL DWORD PTR DS:[<&MSVCRT._mbscmp>] ; msvcrt._mbscmp
==================================================================================================
420b00跟进以后的程序如下,看不懂是要干什么了。
Local Calls from 004084AB, 0042033A, 00428C53, 004291D0, 0042AFDD, 004303F0
这些地址都调用了这个
00420B00 /$ 6A FF PUSH -1
00420B02 |. 68 18634400 PUSH PrettyCa.00446318 ; SE handler installation
00420B07 |. 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
00420B0D |. 50 PUSH EAX
00420B0E |. 64:8925 000000>MOV DWORD PTR FS:[0],ESP
00420B15 |. 83EC 60 SUB ESP,60
00420B18 |. 56 PUSH ESI
00420B19 |. 8B7424 7C MOV ESI,DWORD PTR SS:[ESP+7C]
00420B1D |. 57 PUSH EDI
00420B1E |. 8B7C24 7C MOV EDI,DWORD PTR SS:[ESP+7C]
00420B22 |. 6A 00 PUSH 0
00420B24 |. 56 PUSH ESI
00420B25 |. 57 PUSH EDI
00420B26 |. C74424 14 0000>MOV DWORD PTR SS:[ESP+14],0
00420B2E |. E8 AF200200 CALL <JMP.&MFC42.#1187>
00420B33 |. 8D4C24 0C LEA ECX,DWORD PTR SS:[ESP+C]
00420B37 |. E8 A40A0000 CALL PrettyCa.004215E0
00420B3C |. 56 PUSH ESI
00420B3D |. 57 PUSH EDI
00420B3E |. 8D4C24 14 LEA ECX,DWORD PTR SS:[ESP+14]
00420B42 |. C74424 78 0000>MOV DWORD PTR SS:[ESP+78],0
00420B4A |. E8 810C0000 CALL PrettyCa.004217D0
00420B4F |. 8B7424 78 MOV ESI,DWORD PTR SS:[ESP+78]
00420B53 |. 8D4C24 0C LEA ECX,DWORD PTR SS:[ESP+C]
00420B57 |. 56 PUSH ESI ; /Arg1
00420B58 |. E8 130B0000 CALL PrettyCa.00421670 ; \PrettyCa.00421670
00420B5D |. 8B4C24 68 MOV ECX,DWORD PTR SS:[ESP+68]
00420B61 |. 8BC6 MOV EAX,ESI
00420B63 |. 5F POP EDI
00420B64 |. 5E POP ESI
00420B65 |. 64:890D 000000>MOV DWORD PTR FS:[0],ECX
00420B6C |. 83C4 6C ADD ESP,6C
00420B6F \. C3 RETN
后面的分析十分没水平,对算法也不很了解,我到现在也没看出这个程序是怎么从用户名算出注册码的,如果哪位大虾知道,请跟帖告知,
谢谢!由于我上网不是很方便,所以可能回复的比较晚,不过肯定会回复谢谢大家的,再次十分感谢!
可以用keymake制作注册机
=======================
内存注册机:
中断地址:00430412
中断次数:1
第一字节:FF
指令长度:1
内存方式--->EAX
=======================
--------------------------------------------------------------------------------
【经验总结】
找码和爆破都比较容易,但是到算法这块还不太明白,有点糊涂,不知道到底怎么计算,望知道的大虾不吝告知,谢谢!
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2009年1月2日 2:29:14
[课程]Linux pwn 探索篇!