一个通过异常处理进行验证的crackme分析
同样是看雪上的一个小crackme,同样是MFC做的,分析的思路:1.查看OnInit函数中是否有用户自定义的初始化代码。2.查看OnInitDialog函数中是否用用户自定义的初始化代码。3.查看确定按钮的响应函数都做了什么。OK,let's go!
1.加载程序,查看OnInit函数中是否有用户自定义代码。OnInit函数的位置可以用上篇文章中提到的找DoModal函数的方法,这个exe中竟然会调用两次DoModal,不管他,在相应的位置下断,F9运行,断下来的那一个就是咱们要找的那个,这段函数断下来是这个样子滴

004010F9 |. 8BEC mov ebp, esp
004010FB |. 6A FF push -1
004010FD |. 68 59234000 push 00402359 ; SE 处理程序安装
00401102 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
00401108 |. 50 push eax
00401109 |. 64:8925 00000>mov dword ptr fs:[0], esp
00401110 |. 83EC 78 sub esp, 78
00401113 |. 898D 7CFFFFFF mov dword ptr [ebp-84], ecx
00401119 |. 6A 00 push 0
0040111B |. E8 4A0E0000 call <jmp.&MFC42.#1134_AfxEnableControlContainer>
00401120 |. 83C4 04 add esp, 4
00401123 |. 8B8D 7CFFFFFF mov ecx, dword ptr [ebp-84]
00401129 |. E8 360E0000 call <jmp.&MFC42.#2621_CWinApp::Enable3dControls>
0040112E |. 6A 00 push 0
00401130 |. 8D4D 84 lea ecx, dword ptr [ebp-7C]
00401133 |. E8 1C020000 call 00401354
00401138 |. C745 FC 00000>mov dword ptr [ebp-4], 0
0040113F |. 8B85 7CFFFFFF mov eax, dword ptr [ebp-84]
00401145 |. 8D4D 84 lea ecx, dword ptr [ebp-7C]
00401148 |. 8948 20 mov dword ptr [eax+20], ecx
0040114B |. 8D4D 84 lea ecx, dword ptr [ebp-7C]
0040114E |. E8 0B0E0000 call <jmp.&MFC42.#2514_CDialog::DoModal>
00401153 |. 8945 F0 mov dword ptr [ebp-10], eax
00401156 |. C745 80 00000>mov dword ptr [ebp-80], 0
0040115D |. C745 FC FFFFF>mov dword ptr [ebp-4], -1
00401164 |. 8D4D 84 lea ecx, dword ptr [ebp-7C]
00401167 |. E8 64000000 call 004011D0
0040116C |. 8B45 80 mov eax, dword ptr [ebp-80]
0040116F |. 8B4D F4 mov ecx, dword ptr [ebp-C]
00401172 |. 64:890D 00000>mov dword ptr fs:[0], ecx
00401179 |. 8BE5 mov esp, ebp
0040117B |. 5D pop ebp
0040117C \. C3 retn
跟一下看看,没发现有特殊的用户自定义函数
2.检查OnInitDialog函数
用上篇文章中的方法找用户自定义的初始化函数,这段代码如下

00401661 |. 8BEC mov ebp, esp
00401663 |. 6A FF push -1
00401665 |. 68 E0234000 push 004023E0 ; SE 处理程序安装
0040166A |. 64:A1 0000000>mov eax, dword ptr fs:[0]
00401670 |. 50 push eax
00401671 |. 64:8925 00000>mov dword ptr fs:[0], esp
00401678 |. 83EC 70 sub esp, 70
0040167B |. 57 push edi
0040167C |. 894D 84 mov dword ptr [ebp-7C], ecx
0040167F |. 8B4D 84 mov ecx, dword ptr [ebp-7C]
00401682 |. E8 0D090000 call <jmp.&MFC42.#4710_CDialog::OnInitDialog>
00401687 |. 6A 00 push 0
00401689 |. 8B4D 84 mov ecx, dword ptr [ebp-7C]
0040168C |. E8 7F060000 call 00401D10
00401691 |. 8945 CC mov dword ptr [ebp-34], eax
00401694 |. 837D CC 00 cmp dword ptr [ebp-34], 0
00401698 |. 74 5A je short 004016F4
0040169A |. 8D4D 8C lea ecx, dword ptr [ebp-74]
0040169D |. E8 D2070000 call <jmp.&MFC42.#540_CString::CString>
004016A2 |. C745 FC 00000>mov dword ptr [ebp-4], 0
004016A9 |. 6A 65 push 65
004016AB |. 8D4D 8C lea ecx, dword ptr [ebp-74]
004016AE |. E8 A1090000 call <jmp.&MFC42.#4160_CString::LoadStringA>
004016B3 |. 8D4D 8C lea ecx, dword ptr [ebp-74]
004016B6 |. E8 E5040000 call 00401BA0
004016BB |. 85C0 test eax, eax
004016BD |. 75 26 jnz short 004016E5
004016BF |. 6A 00 push 0
004016C1 |. 6A 00 push 0
004016C3 |. 68 00080000 push 800
004016C8 |. 8B4D CC mov ecx, dword ptr [ebp-34]
004016CB |. E8 E0050000 call 00401CB0
004016D0 |. 8D4D 8C lea ecx, dword ptr [ebp-74]
004016D3 |. E8 E8040000 call 00401BC0
004016D8 |. 50 push eax
004016D9 |. 6A 10 push 10
004016DB |. 6A 00 push 0
004016DD |. 8B4D CC mov ecx, dword ptr [ebp-34]
004016E0 |. E8 CB050000 call 00401CB0
004016E5 |> C745 FC FFFFF>mov dword ptr [ebp-4], -1
004016EC |. 8D4D 8C lea ecx, dword ptr [ebp-74]
004016EF |. E8 86070000 call <jmp.&MFC42.#800_CString::~CString>
004016F4 |> 6A 01 push 1
004016F6 |. 8B45 84 mov eax, dword ptr [ebp-7C]
004016F9 |. 8B48 68 mov ecx, dword ptr [eax+68]
004016FC |. 51 push ecx
004016FD |. 8B4D 84 mov ecx, dword ptr [ebp-7C]
00401700 |. E8 7B060000 call 00401D80
00401705 |. 6A 00 push 0
00401707 |. 8B55 84 mov edx, dword ptr [ebp-7C]
0040170A |. 8B42 68 mov eax, dword ptr [edx+68]
0040170D |. 50 push eax
0040170E |. 8B4D 84 mov ecx, dword ptr [ebp-7C]
00401711 |. E8 6A060000 call 00401D80
00401716 |. C645 D8 00 mov byte ptr [ebp-28], 0
0040171A |. B9 06000000 mov ecx, 6
0040171F |. 33C0 xor eax, eax
00401721 |. 8D7D D9 lea edi, dword ptr [ebp-27]
00401724 |. F3:AB rep stos dword ptr es:[edi]
00401726 |. 66:AB stos word ptr es:[edi]
00401728 |. AA stos byte ptr es:[edi]
00401729 |. C645 AC 01 mov byte ptr [ebp-54], 1
0040172D |. C645 AD 02 mov byte ptr [ebp-53], 2
00401731 |. C645 AE 03 mov byte ptr [ebp-52], 3
00401735 |. C645 AF 0A mov byte ptr [ebp-51], 0A
00401739 |. C645 B0 0B mov byte ptr [ebp-50], 0B
0040173D |. C645 B1 0C mov byte ptr [ebp-4F], 0C
00401741 |. C645 B2 0D mov byte ptr [ebp-4E], 0D
00401745 |. C645 B3 0E mov byte ptr [ebp-4D], 0E
00401749 |. C645 B4 0F mov byte ptr [ebp-4C], 0F
0040174D |. C645 B5 77 mov byte ptr [ebp-4B], 77
00401751 |. C645 B6 22 mov byte ptr [ebp-4A], 22
00401755 |. C645 B7 55 mov byte ptr [ebp-49], 55
00401759 |. C645 B8 AA mov byte ptr [ebp-48], 0AA
0040175D |. C645 B9 21 mov byte ptr [ebp-47], 21
00401761 |. C645 BA 22 mov byte ptr [ebp-46], 22
00401765 |. C645 BB 23 mov byte ptr [ebp-45], 23
00401769 |. C645 BC 45 mov byte ptr [ebp-44], 45
0040176D |. C645 BD 12 mov byte ptr [ebp-43], 12
00401771 |. C645 BE 45 mov byte ptr [ebp-42], 45
00401775 |. C645 BF 12 mov byte ptr [ebp-41], 12
00401779 |. C645 C0 21 mov byte ptr [ebp-40], 21
0040177D |. C645 C1 22 mov byte ptr [ebp-3F], 22
00401781 |. C645 C2 23 mov byte ptr [ebp-3E], 23
00401785 |. C645 C3 45 mov byte ptr [ebp-3D], 45
00401789 |. C645 C4 12 mov byte ptr [ebp-3C], 12
0040178D |. C645 C5 45 mov byte ptr [ebp-3B], 45
00401791 |. C645 C6 12 mov byte ptr [ebp-3A], 12
00401795 |. 33C9 xor ecx, ecx
00401797 |. 884D C7 mov byte ptr [ebp-39], cl
0040179A |. C645 90 52 mov byte ptr [ebp-70], 52
0040179E |. C645 91 67 mov byte ptr [ebp-6F], 67
004017A2 |. C645 92 77 mov byte ptr [ebp-6E], 77
004017A6 |. C645 93 5F mov byte ptr [ebp-6D], 5F
004017AA |. C645 94 65 mov byte ptr [ebp-6C], 65
004017AE |. C645 95 64 mov byte ptr [ebp-6B], 64
004017B2 |. C645 96 6C mov byte ptr [ebp-6A], 6C
004017B6 |. C645 97 60 mov byte ptr [ebp-69], 60
004017BA |. C645 98 6B mov byte ptr [ebp-68], 6B
004017BE |. C645 99 1B mov byte ptr [ebp-67], 1B
004017C2 |. C645 9A 47 mov byte ptr [ebp-66], 47
004017C6 |. C645 9B 31 mov byte ptr [ebp-65], 31
004017CA |. C645 9C EF mov byte ptr [ebp-64], 0EF
004017CE |. C645 9D 59 mov byte ptr [ebp-63], 59
004017D2 |. C645 9E 41 mov byte ptr [ebp-62], 41
004017D6 |. C645 9F 46 mov byte ptr [ebp-61], 46
004017DA |. C645 A0 35 mov byte ptr [ebp-60], 35
004017DE |. C645 A1 66 mov byte ptr [ebp-5F], 66
004017E2 |. C645 A2 2C mov byte ptr [ebp-5E], 2C
004017E6 |. C645 A3 7D mov byte ptr [ebp-5D], 7D
004017EA |. C645 A4 4F mov byte ptr [ebp-5C], 4F
004017EE |. C645 A5 64 mov byte ptr [ebp-5B], 64
004017F2 |. C645 A6 4A mov byte ptr [ebp-5A], 4A
004017F6 |. C645 A7 29 mov byte ptr [ebp-59], 29
004017FA |. C645 A8 66 mov byte ptr [ebp-58], 66
004017FE |. C645 A9 20 mov byte ptr [ebp-57], 20
00401802 |. C645 AA 60 mov byte ptr [ebp-56], 60
00401806 |. 33D2 xor edx, edx
00401808 |. 8855 AB mov byte ptr [ebp-55], dl
0040180B |. C745 C8 00000>mov dword ptr [ebp-38], 0
00401812 |. EB 09 jmp short 0040181D
00401814 |> 8B45 C8 /mov eax, dword ptr [ebp-38]
00401817 |. 83C0 01 |add eax, 1
0040181A |. 8945 C8 |mov dword ptr [ebp-38], eax
0040181D |> 837D C8 1C cmp dword ptr [ebp-38], 1C
00401821 |. 7D 1D |jge short 00401840
00401823 |. 8B4D C8 |mov ecx, dword ptr [ebp-38]
00401826 |. 33D2 |xor edx, edx
00401828 |. 8A540D AC |mov dl, byte ptr [ebp+ecx-54]
0040182C |. 8B45 C8 |mov eax, dword ptr [ebp-38]
0040182F |. 33C9 |xor ecx, ecx
00401831 |. 8A4C05 90 |mov cl, byte ptr [ebp+eax-70]
00401835 |. 33D1 |xor edx, ecx
00401837 |. 8B45 C8 |mov eax, dword ptr [ebp-38]
0040183A |. 885405 D8 |mov byte ptr [ebp+eax-28], dl
0040183E |.^ EB D4 \jmp short 00401814
00401840 |> 8D4D D0 lea ecx, dword ptr [ebp-30]
00401843 |. E8 2C060000 call <jmp.&MFC42.#540_CString::CString>
00401848 |. C745 FC 01000>mov dword ptr [ebp-4], 1
0040184F |. 8D4D D8 lea ecx, dword ptr [ebp-28]
00401852 |. 51 push ecx
00401853 |. 8D4D D0 lea ecx, dword ptr [ebp-30]
00401856 |. E8 E5020000 call 00401B40
0040185B |. 8D4D D0 lea ecx, dword ptr [ebp-30]
0040185E |. E8 5D030000 call 00401BC0
00401863 |. 50 push eax ; /ProcNameOrOrdinal
00401864 |. 68 58404000 push 00404058 ; |/pModule = "kernel32.dll"
00401869 |. FF15 08304000 call dword ptr [<&KERNEL32.GetModuleHandleA>] ; |\GetModuleHandleA
0040186F |. 50 push eax ; |hModule
00401870 |. FF15 04304000 call dword ptr [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
00401876 |. A3 68414000 mov dword ptr [404168], eax
0040187B |. 68 64154000 push 00401564
00401880 |. FF15 68414000 call dword ptr [404168] ; call SetUnhandleExceptionFilter
00401886 |. 68 68404000 push 00404068 ; /FileName = "user32.dll"
0040188B |. FF15 10304000 call dword ptr [<&KERNEL32.LoadLibraryA>] ; \LoadLibraryA
00401891 |. 8945 D4 mov dword ptr [ebp-2C], eax
00401894 |. 837D D4 00 cmp dword ptr [ebp-2C], 0
00401898 |. 74 14 je short 004018AE
0040189A |. 68 74404000 push 00404074 ; /ProcNameOrOrdinal = "MessageBoxA"
0040189F |. 8B55 D4 mov edx, dword ptr [ebp-2C] ; |
004018A2 |. 52 push edx ; |hModule
004018A3 |. FF15 04304000 call dword ptr [<&KERNEL32.GetProcAddress>] ; \GetProcAddress
004018A9 |. A3 6C414000 mov dword ptr [40416C], eax
004018AE |> 8B45 D4 mov eax, dword ptr [ebp-2C]
004018B1 |. 50 push eax ; /hLibModule
004018B2 |. FF15 00304000 call dword ptr [<&KERNEL32.FreeLibrary>] ; \FreeLibrary
004018B8 |. C745 88 01000>mov dword ptr [ebp-78], 1
004018BF |. C745 FC FFFFF>mov dword ptr [ebp-4], -1
004018C6 |. 8D4D D0 lea ecx, dword ptr [ebp-30]
004018C9 |. E8 AC050000 call <jmp.&MFC42.#800_CString::~CString>
004018CE |. 8B45 88 mov eax, dword ptr [ebp-78]
004018D1 |. 8B4D F4 mov ecx, dword ptr [ebp-C]
004018D4 |. 64:890D 00000>mov dword ptr fs:[0], ecx
004018DB |. 5F pop edi
004018DC |. 8BE5 mov esp, ebp
004018DE |. 5D pop ebp
004018DF \. C3 retn
我们可以看到,从401729开始,大段的数字数字数字,这不是此地无银三百两么,囧,这边要是没问题我可以把天安门吃了,跟下去看看,发现在401880处,调用了SetUnhandleExceptionFilter函数,这个函数貌似是定义了一个异常处理的过程,详细的说明MSDN上面有的。在40187B处,push了一个401564,这就是异常处理函数的位置,这个函数是这个样子滴

00401565 |. 8BEC mov ebp, esp
00401567 |. 83EC 2C sub esp, 2C
0040156A |. 56 push esi
0040156B |. 51 push ecx
0040156C |. 8BCC mov ecx, esp
0040156E |. 8965 DC mov dword ptr [ebp-24], esp
00401571 |. 68 78414000 push 00404178
00401576 |. E8 D30A0000 call <jmp.&MFC42.#535_CString::CString>
0040157B |. 8945 D8 mov dword ptr [ebp-28], eax
0040157E |. E8 E3FEFFFF call 00401466
00401583 |. 83C4 04 add esp, 4
00401586 |. 8945 D4 mov dword ptr [ebp-2C], eax
00401589 |. 837D D4 00 cmp dword ptr [ebp-2C], 0
0040158D |. 75 28 jnz short 004015B7
0040158F |. 8D45 E0 lea eax, dword ptr [ebp-20]
00401592 |. 50 push eax
00401593 |. 68 30404000 push 00404030
00401598 |. E8 5EFFFFFF call 004014FB
0040159D |. 83C4 08 add esp, 8
004015A0 |. 6A 00 push 0
004015A2 |. 6A 00 push 0
004015A4 |. 8D4D E0 lea ecx, dword ptr [ebp-20]
004015A7 |. 51 push ecx
004015A8 |. E8 9B0A0000 call <jmp.&MFC42.#1200_AfxMessageBox>
004015AD |. B8 01000000 mov eax, 1
004015B2 |. E9 A2000000 jmp 00401659
004015B7 |> 6A 02 push 2
004015B9 |. B9 78414000 mov ecx, 00404178
004015BE |. E8 0D060000 call 00401BD0
004015C3 |. 0FBEF0 movsx esi, al
004015C6 |. 6A 03 push 3
004015C8 |. B9 74414000 mov ecx, 00404174
004015CD |. E8 FE050000 call 00401BD0
004015D2 |. 0FBED0 movsx edx, al
004015D5 |. 3BF2 cmp esi, edx
004015D7 |. 75 4C jnz short 00401625
004015D9 |. 6A 03 push 3
004015DB |. B9 78414000 mov ecx, 00404178
004015E0 |. E8 EB050000 call 00401BD0
004015E5 |. 0FBEF0 movsx esi, al
004015E8 |. 6A 05 push 5
004015EA |. B9 74414000 mov ecx, 00404174
004015EF |. E8 DC050000 call 00401BD0
004015F4 |. 0FBEC0 movsx eax, al
004015F7 |. 3BF0 cmp esi, eax
004015F9 |. 75 2A jnz short 00401625
004015FB |. 8D4D E0 lea ecx, dword ptr [ebp-20]
004015FE |. 51 push ecx
004015FF |. 68 3C404000 push 0040403C
00401604 |. E8 F2FEFFFF call 004014FB
00401609 |. 83C4 08 add esp, 8
0040160C |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
0040160E |. 68 48404000 push 00404048 ; |Title = "CrackMe"
00401613 |. 8D55 E0 lea edx, dword ptr [ebp-20] ; |
00401616 |. 52 push edx ; |Text
00401617 |. A1 70414000 mov eax, dword ptr [404170] ; |
0040161C |. 50 push eax ; |hOwner => NULL
0040161D |. FF15 F8314000 call dword ptr [<&USER32.MessageBoxA>] ; \MessageBoxA
00401623 |. EB 2F jmp short 00401654
00401625 |> 8D4D E0 lea ecx, dword ptr [ebp-20]
00401628 |. 51 push ecx
00401629 |. 68 30404000 push 00404030
0040162E |. E8 C8FEFFFF call 004014FB
00401633 |. 83C4 08 add esp, 8
00401636 |. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
00401638 |. 68 50404000 push 00404050 ; |Title = "CrackMe"
0040163D |. 8D55 E0 lea edx, dword ptr [ebp-20] ; |
00401640 |. 52 push edx ; |Text
00401641 |. A1 70414000 mov eax, dword ptr [404170] ; |
00401646 |. 50 push eax ; |hOwner => NULL
00401647 |. FF15 F8314000 call dword ptr [<&USER32.MessageBoxA>] ; \MessageBoxA
0040164D |. B8 01000000 mov eax, 1
00401652 |. EB 05 jmp short 00401659
00401654 |> B8 01000000 mov eax, 1
00401659 |> 5E pop esi
0040165A |. 8BE5 mov esp, ebp
0040165C |. 5D pop ebp
0040165D \. C2 0400 retn 4
具体做了什么俺没分析,下面做第三步
3.分析一下确定按钮做了什么
在translatemessage函数处下条件断点,断鼠标的单击消息,条件是[[esp+4]+4]==WM_LBUTTONDOWN,至于为什么这样,看看断下来的时候堆栈里面的信息就好了,断下来以后,同样的,按照上篇文章里的囧方法,在程序领空的每一个函数入口处下断,经过一番F9之后,找到了单击确定按钮对应的响应函数,如下

00401A64 |. 8BEC mov ebp, esp
00401A66 |. 83EC 0C sub esp, 0C
00401A69 |. 53 push ebx
00401A6A |. 56 push esi
00401A6B |. 57 push edi
00401A6C |. 894D F4 mov dword ptr [ebp-C], ecx
00401A6F |. 6A 01 push 1
00401A71 |. 8B4D F4 mov ecx, dword ptr [ebp-C]
00401A74 |. E8 F3050000 call <jmp.&MFC42.#6334_CWnd::UpdateData>
00401A79 |. 8B45 F4 mov eax, dword ptr [ebp-C]
00401A7C |. 83C0 60 add eax, 60
00401A7F |. 50 push eax
00401A80 |. B9 78414000 mov ecx, 00404178
00401A85 |. E8 DC050000 call <jmp.&MFC42.#858_CString::operator=>
00401A8A |. 8B4D F4 mov ecx, dword ptr [ebp-C]
00401A8D |. 83C1 64 add ecx, 64
00401A90 |. 51 push ecx
00401A91 |. B9 74414000 mov ecx, 00404174
00401A96 |. E8 CB050000 call <jmp.&MFC42.#858_CString::operator=>
00401A9B |. C745 F8 64000>mov dword ptr [ebp-8], 64
00401AA2 |. F4 hlt ; 这里产生一个异常
00401AA3 |. 5F pop edi
00401AA4 |. 5E pop esi
00401AA5 |. 5B pop ebx
00401AA6 |. 8BE5 mov esp, ebp
00401AA8 |. 5D pop ebp
00401AA9 \. C3 retn
在401AA2处,一个很奇怪的命令,hlt,百度一下,表示的是处理器暂停指令,普通程序应该是不能调用这个指令的,因此这里肯定会产生一个异常,异常的响应函数上面已经给出了。
到此为止,整个crackme的流程基本分析完毕,分析的过程还是有缺憾的,没法跟踪异常处理响应函数中的程序,还要再继续研究一下
补:(怎么样才能让异常处理部分程序执行起来?很简单,在hlt处把程序改成jmp 00401564就好了,囧,因为hlt以后的代码本来就不会被执行到)