一直以来对计算机都很感兴趣,虽然学的专业不是计算机~~,也一直关注这方面的东西,看雪论坛上的大牛们以及论坛的学术气氛让小弟我有了坚持下去的信心,感谢看雪论坛!好了,闲话少说,进入正题。
在《加密与解密》的光盘里随便找了一个CRACKME的小软件,叫做chap204.exe。打开以后,需要输入用户名和注册码,随便输入两个,结果弹出错误对话框,”Incorrect!! try again”。我们利用这个查找字符串参考,先到反汇编窗口去观察一下。
004016AE |. B9 06000000 mov ecx,0x6
004016B3 |. BE 98404000 mov esi,chap204.00404098 //字符串参考ASCII "Incorrect!!, Try Again."
004016B8 |. 8DBD 78FFFFFF lea edi,[local.34]
004016BE |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
004016C0 |. B9 13000000 mov ecx,0x13
004016C5 |. 33C0 xor eax,eax
004016C7 |. 8D7D 90 lea edi,[local.28]
004016CA |. F3:AB rep stos dword ptr es:[edi]
004016CC |. B9 07000000 mov ecx,0x7
004016D1 |. BE B0404000 mov esi,chap204.004040B0 //字符串参考ASCII "Correct way to go, You Got It."
004016D6 |. 8DBD B0FEFFFF lea edi,[local.84]
004016DC |. F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
004016DE |. 66:A5 movs word ptr es:[edi],word ptr ds:[esi]
004016E0 |. A4 movs byte ptr es:[edi],byte ptr ds:[esi]
004016E1 |. B9 11000000 mov ecx,0x11
004016E6 |. 33C0 xor eax,eax
004016E8 |. 8DBD CFFEFFFF lea edi,dword ptr ss:[ebp-0x131]
004016EE |. F3:AB rep stos dword ptr es:[edi]
004016F0 |. AA stos byte ptr es:[edi]
004016F1 |. 6A 40 push 0x40
004016F3 |. 68 D0404000 push chap204.004040D0 // ASCII "CrackMe"
004016F8 |. 8D8D ACFEFFFF lea ecx,[local.85]
004016FE |. E8 AD010000 call chap204.004018B0
00401703 |. 50 push eax
00401704 |. 8B8D 40FEFFFF mov ecx,[local.112]
0040170A |. E8 75060000 call <jmp.&MFC42.#CWnd::MessageBoxA_4224> //第一个消息框
0040170F |. C645 FC 02 mov byte ptr ss:[ebp-0x4],0x2
00401713 |. 8D8D ACFEFFFF lea ecx,[local.85]
00401719 |. E8 42060000 call <jmp.&MFC42.#CString::~CString_800>
0040171E |. C645 FC 01 mov byte ptr ss:[ebp-0x4],0x1
00401722 |. 8D4D DC lea ecx,[local.9]
00401725 |. E8 36060000 call <jmp.&MFC42.#CString::~CString_800>
0040172A |. C645 FC 00 mov byte ptr ss:[ebp-0x4],0x0
0040172E |. 8D4D E8 lea ecx,[local.6]
00401731 |. E8 2A060000 call <jmp.&MFC42.#CString::~CString_800>
00401736 |. C745 FC FFFFF>mov [local.1],-0x1
0040173D |. 8D4D EC lea ecx,[local.5]
00401740 |. E8 1B060000 call <jmp.&MFC42.#CString::~CString_800>
00401745 |. EB 70 jmp Xchap204.004017B7
00401747 |> 8D8D 44FEFFFF lea ecx,[local.111]
0040174D |. E8 1A060000 call <jmp.&MFC42.#CString::CString_540>
00401752 |. C645 FC 04 mov byte ptr ss:[ebp-0x4],0x4
00401756 |. 6A 67 push 0x67
00401758 |. 8D8D 44FEFFFF lea ecx,[local.111]
0040175E |. E8 03060000 call <jmp.&MFC42.#CString::LoadStringA_4160>
00401763 |. 6A 40 push 0x40
00401765 |. 68 D8404000 push chap204.004040D8 ; ASCII "CrackMe"
0040176A |. 8D8D 44FEFFFF lea ecx,[local.111]
00401770 |. E8 3B010000 call chap204.004018B0
00401775 |. 50 push eax
00401776 |. 8B8D 40FEFFFF mov ecx,[local.112]
0040177C |. E8 03060000 call <jmp.&MFC42.#CWnd::MessageBoxA_4224> //第二个消息框
00401781 |. C645 FC 02 mov byte ptr ss:[ebp-0x4],0x2
00401785 |. 8D8D 44FEFFFF lea ecx,[local.111]
0040178B |. E8 D0050000 call <jmp.&MFC42.#CString::~CString_800>
00401790 |. C645 FC 01 mov byte ptr ss:[ebp-0x4],0x1
00401794 |. 8D4D DC lea ecx,[local.9]
00401797 |. E8 C4050000 call <jmp.&MFC42.#CString::~CString_800>
0040179C |. C645 FC 00 mov byte ptr ss:[ebp-0x4],0x0
004017A0 |. 8D4D E8 lea ecx,[local.6]
004017A3 |. E8 B8050000 call <jmp.&MFC42.#CString::~CString_800>
004017A8 |. C745 FC FFFFF>mov [local.1],-0x1
004017AF |. 8D4D EC lea ecx,[local.5]
004017B2 |. E8 A9050000 call <jmp.&MFC42.#CString::~CString_800>
004017B7 |> 8B4D F4 mov ecx,[local.3]
004017BA |. 64:890D 00000>mov dword ptr fs:[0],ecx
004017C1 |. 5F pop edi 在反汇编窗口找到我们查找的字符串参考(输入错误的信息),在下面又找到输入正确的提示信息(Correct way to go, You Got It.),往下翻一翻,发现有两个MessageBox(),肯定一个是输入错误弹出来的,一个是输入正确弹出来的,但到底哪个是输入错误弹出来的呢?我们通过在MessageBoxA函数上下断点来判断一下。在反汇编窗口,CTRL+N唤出函数名称对话框,找到MessageBoxA函数,右键在每个参考上设置断点,左下角显示激活了4个断点。然后F9运行程序,输入用户名:jaycococ,密码:aaaaaaaa。点击check,程序被OD断下。
我们可以发现程序断在了第二个MessageBoxA()的前面,就说明这里是错误信息的MessageBox()。沿着这个断点往上翻,还没到达另一个MessageBox()之前,可以看到:
00401747 |> 8D8D 44FEFFFF lea ecx,[local.111]
地址右边的箭头,表示此处可从别处跳转过来,而且在两个MessageBox()之前,只有这唯一的跳转,从程序的逻辑来看,两个MessageBox不可能同时都执行,那么这个就是我们要找的关键跳转!利用OD的箭头,找到跳转的源头:
00401638 |. 8D4D E8 lea ecx,[local.6]
0040163B |. E8 80020000 call chap204.004018C0 //关键判断函数
00401640 |. 85C0 test eax,eax //判断函数返回值,决定是否跳转
00401642 |. 0F85 FF000000 jnz chap204.00401747
在00401642处找到了非零跳转JNZ,上面的call chap204.004018C0应该就是关键的判断!在0040163B |. E8 80020000 call chap204.004018C0处,F7跟进。
004018C0 /$ 55 push ebp
004018C1 |. 8BEC mov ebp,esp
004018C3 |. 51 push ecx
004018C4 |. 894D FC mov [local.1],ecx
004018C7 |. 8B45 08 mov eax,[arg.1]
004018CA |. 50 push eax
004018CB |. 8B4D FC mov ecx,[local.1]
004018CE |. 8B11 mov edx,dword ptr ds:[ecx]
004018D0 |. 52 push edx
004018D1 |. E8 0A000000 call chap204.004018E0
004018D6 |. 83C4 08 add esp,0x8
004018D9 |. 8BE5 mov esp,ebp
004018DB |. 5D pop ebp
004018DC \. C2 0400 retn 0x4
004018DF CC int3
004018E0 /$ 55 push ebp
004018E1 |. 8BEC mov ebp,esp
004018E3 |. 8B45 0C mov eax,[arg.2]
004018E6 |. 50 push eax ; /s2
004018E7 |. 8B4D 08 mov ecx,[arg.1] ; |
004018EA |. 51 push ecx ; |s1
004018EB |. FF15 B4314000 call dword ptr ds:[<&MSVCRT._mbscmp>] //字符串比较函数 _mbscmp
004018F1 |. 83C4 08 add esp,0x8
004018F4 |. 5D pop ebp
004018F5 \. C3 retn
在函数内部004018EB处,找到了MSVCRT._mbscmp函数,该函数进行字符串比较,实际上在这里设置断点的话,会发现EAX跟ECX中保存的分别输入的注册码和真实的注册码!这样就找到了这个注册码。但由于该注册码随着用户名改变而改变,因此如果能找到注册机的话,那自然是最好了!下面着手寻找注册办法。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: