-
-
[原创]对wunv队的爆破
-
发表于: 2009-9-21 23:49 18851
-
对本CM的理解:
程序运行启动两个线程,一个用于反调试(至少检测了调试器,检测了关键代码处的断点),另一个用于调用计算注册码的关键函数。获得输入的函数只是判断长度是否合法,不进行进一步的判断。进一步判断的由开始启动的一个线程负责。计算用了浮点运算。
调试过程:
1、在OD中直接运行,退出,有anti;
2、添加Strong OD插件,用书呆彭的“不可说不可数”法,找到关键代码处(00401A70),下断,发现下断之后,程序直接退出了,肯定有反调试的东东;
3、猜测是有其他线程在检测,用bp CreateThread下断,然后选择执行到用户代码,有两处调用MFC的AfxBeginThread,直接给nop掉,保存改后的程序,这下可以下断了。
4、在关键代码处
00401A70 /. 55 push ebp ; 关键代码
00401A71 |. 8BEC mov ebp, esp
00401A73 |. 6A FF push -1
00401A75 |. 68 D0274000 push 004027D0 ; SE 处理程序安装
00401A7A |. 64:A1 0000000>mov eax, dword ptr fs:[0]
00401A80 |. 50 push eax
00401A81 |. 64:8925 00000>mov dword ptr fs:[0], esp
00401A88 |. 83EC 10 sub esp, 10
00401A8B |. 53 push ebx
00401A8C |. 56 push esi
00401A8D |. 8BF1 mov esi, ecx
00401A8F |. 8D4D E8 lea ecx, dword ptr [ebp-18]
00401A92 |. E8 F9090000 call <jmp.&MFC42.#CString::CString_54>
00401A97 |. 33DB xor ebx, ebx
00401A99 |. 8D4D EC lea ecx, dword ptr [ebp-14]
00401A9C |. 895D FC mov dword ptr [ebp-4], ebx
00401A9F |. E8 EC090000 call <jmp.&MFC42.#CString::CString_54>
00401AA4 |. 8D45 E8 lea eax, dword ptr [ebp-18]
00401AA7 |. 8D8E A0000000 lea ecx, dword ptr [esi+A0]
00401AAD |. 50 push eax
00401AAE |. C645 FC 01 mov byte ptr [ebp-4], 1
00401AB2 |. E8 F7090000 call <jmp.&MFC42.#CWnd::GetWindowText>
; 获得用户名
00401AB7 |. 8B4D E8 mov ecx, dword ptr [ebp-18]
00401ABA |. 8B41 F8 mov eax, dword ptr [ecx-8]
00401ABD |. 3BC3 cmp eax, ebx
00401ABF |. 0F84 BE000000 je 00401B83 ; 判断用户名的长度是否合法
00401AC5 |. 83F8 05 cmp eax, 5
00401AC8 |. 0F8C B5000000 jl 00401B83
00401ACE |. 83F8 14 cmp eax, 14
00401AD1 |. 0F8F AC000000 jg 00401B83
00401AD7 |. 8D55 EC lea edx, dword ptr [ebp-14]
00401ADA |. 8D4E 60 lea ecx, dword ptr [esi+60]
00401ADD |. 52 push edx
00401ADE |. E8 CB090000 call <jmp.&MFC42.#CWnd::GetWindowText>
00401AE3 |. 8B45 EC mov eax, dword ptr [ebp-14] ; 获得密码
00401AE6 |. 8B40 F8 mov eax, dword ptr [eax-8]
00401AE9 |. 3BC3 cmp eax, ebx
00401AEB |. 0F84 92000000 je 00401B83
00401AF1 |. 0F8E 8C000000 jle 00401B83
00401AF7 |. 68 34120000 push 1234 ; /hObject = 00001234
00401AFC |. FF15 04304000 call dword ptr [<&KERNEL32.CloseHandl>; \CloseHandle
00401B02 |. 68 20414000 push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401B07 |. C745 FC 01000>mov dword ptr [ebp-4], 1
; |这个值得注意,申请进入临界对象
00401B0E |. FF15 20304000 call dword ptr [<&KERNEL32.EnterCriti>; \EnterCriticalSection
00401B14 |. 0F31 rdtsc
; 下面倒腾数据呢,没细看呢还; 但是是在进入临界区域之后; 猜测,会不会是在另一线程了进行注册码计算; 那么搜索下看看其他进入临界区域的地方; 搜这个00401B0E的 call dword ptr [403020] ; OK,只有一处,在00401C38,00401BB0是他的开始
00401B16 |. 8955 E4 mov dword ptr [ebp-1C], edx
00401B19 |. 8B4D E4 mov ecx, dword ptr [ebp-1C]
00401B1C |. 890D 04414000 mov dword ptr [404104], ecx
00401B22 |. 8945 E4 mov dword ptr [ebp-1C], eax
00401B25 |. 8B55 E4 mov edx, dword ptr [ebp-1C]
00401B28 |. 8B0D 04414000 mov ecx, dword ptr [404104]
00401B2E |. 8915 00414000 mov dword ptr [404100], edx
00401B34 |. 8B15 1C414000 mov edx, dword ptr [40411C]
00401B3A |. 8BC1 mov eax, ecx
00401B3C |. 2BC2 sub eax, edx
00401B3E |. 99 cdq
00401B3F |. 33C2 xor eax, edx
00401B41 |. 2BC2 sub eax, edx
00401B43 |. 83F8 10 cmp eax, 10
00401B46 |. 7F 30 jg short 00401B78
00401B48 |. 8B15 14414000 mov edx, dword ptr [404114]
00401B4E |. 8BC1 mov eax, ecx
00401B50 |. 2BC2 sub eax, edx
00401B52 |. 99 cdq
00401B53 |. 33C2 xor eax, edx
00401B55 |. 2BC2 sub eax, edx
00401B57 |. 83F8 10 cmp eax, 10
00401B5A |. 7F 1C jg short 00401B78
00401B5C |. 68 20414000 push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401B61 |. FF15 1C304000 call dword ptr [<&KERNEL32.LeaveCriti>; \LeaveCriticalSection
00401B67 |. 53 push ebx ; 上面没发现什么异常就退出临街区域了
00401B68 |. 53 push ebx
00401B69 |. 53 push ebx
00401B6A |. 53 push ebx
00401B6B |. 56 push esi
00401B6C |. 68 B01B4000 push 00401BB0
00401B71 |. E8 08090000 call <jmp.&MFC42.#AfxBeginThread_1105>
00401B76 |. EB 0B jmp short 00401B83
00401B78 |> 68 20414000 push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401B7D |. FF15 1C304000 call dword ptr [<&KERNEL32.LeaveCriti>; \LeaveCriticalSection
00401B83 |> 8D4D EC lea ecx, dword ptr [ebp-14] ; 退出临街区域
00401B86 |. 885D FC mov byte ptr [ebp-4], bl
00401B89 |. E8 F6080000 call <jmp.&MFC42.#CString::~CString_8>
00401B8E |. 8D4D E8 lea ecx, dword ptr [ebp-18]
00401B91 |. C745 FC FFFFF>mov dword ptr [ebp-4], -1
00401B98 |. E8 E7080000 call <jmp.&MFC42.#CString::~CString_8>
00401B9D |. 8B4D F4 mov ecx, dword ptr [ebp-C]
00401BA0 |. 5E pop esi
00401BA1 |. 5B pop ebx
00401BA2 |. 64:890D 00000>mov dword ptr fs:[0], ecx
00401BA9 |. 8BE5 mov esp, ebp
00401BAB |. 5D pop ebp
00401BAC \. C3 retn
照上面的分析,看看00401C38处的代码,00401BB0是这段程序的开始。有获得输入的对话框,也有浮点运算,看来应该是这里了。
可是下断点,无效!对了,我把所有启动线程的地方都给咔嚓了。尝试在原来的程序上更改指令达到爆破的目的,结果改后就无法运行了,看来程序应该是进行了校验。
5、打开原始程序,AfxBeginThread的地方,稍微分析下。其实我觉得不看也罢,看了也不太明白,只是有一种特别的感觉,第一个00401690跟下去,更像是在反调试。第二个好像和计算注册码有关。这个程序,直接6步就好了。
0040143B 68 90164000 push 00401690
00401440 E8 39100000 call <jmp.&MFC42.#AfxBeginThread_1105>
……
0040144A 68 50174000 push 00401750
0040144F E8 2A100000 call <jmp.&MFC42.#AfxBeginThread_1105>
对第一个00401690,跟
00401690 /. 55 push ebp
00401691 |. 8BEC mov ebp, esp
00401693 |. 51 push ecx
00401694 |. 56 push esi
00401695 |. 57 push edi
00401696 |. 6A 00 push 0
00401698 |. 6A 00 push 0
0040169A |. 6A 00 push 0
0040169C |. 6A 00 push 0
0040169E |. 6A 00 push 0
004016A0 |. 68
D0184000 push 004018D0 ; ASCII "SVWj"
004016A5 |. E8 D40D0000 call <jmp.&MFC42.#AfxBeginThread_1105>
继续跟
004018D0 . 53 56 57 6A 0>ascii "SVWj",0
004018D5 . FF15 24304000 call dword ptr [<&KERNEL32.GetModuleHandleA>] ; \GetModuleHandleA
004018DB . 8BF0 mov esi, eax
004018DD . 8B46 3C mov eax, dword ptr [esi+3C]
004018E0 . 03C6 add eax, esi
004018E2 . 33C9 xor ecx, ecx
004018E4 . 66:8B48 14 mov cx, word ptr [eax+14]
004018E8 . 8B58 FC mov ebx, dword ptr [eax-4]
004018EB . 8D7C01 18 lea edi, dword ptr [ecx+eax+18]
004018EF > 8B57 08 mov edx, dword ptr [edi+8]
004018F2 . 8BC6 mov eax, esi
004018F4 . 52 push edx
004018F5 . 8B57 0C mov edx, dword ptr [edi+C]
004018F8 . 03C2 add eax, edx
004018FA . 50 push eax
004018FB . E8 50FFFFFF call 00401850
00401900 . 83C4 08 add esp, 8
00401903 . 3BD8 cmp ebx, eax
00401905 .^ 74 E8 je short 004018EF
00401907 . 6A 00 push 0 ; /ExitCode = 0
00401909 . FF15 18304000 call dword ptr [<&KERNEL32.ExitProcess>] ; \ExitProcess
0040190F . 5F pop edi
00401910 . 5E pop esi
00401911 . 33C0 xor eax, eax
00401913 . 5B pop ebx
00401914 . C3 retn
对第二个00401750跟:
00401750 /. 55 push ebp
00401751 |. 8BEC mov ebp, esp
00401753 |. 83EC 48 sub esp, 48
00401756 |. 53 push ebx
00401757 |. 8B1D 20304000 mov ebx, dword ptr [<&KERNEL32.EnterCritical>; ntdll.RtlEnterCriticalSection
0040175D |. 56 push esi
0040175E |. 8B35 28304000 mov esi, dword ptr [<&KERNEL32.GetStartupInf>; kernel32.GetStartupInfoA
00401764 |. 57 push edi
00401765 |> B9 11000000 /mov ecx, 11
0040176A |. 33C0 |xor eax, eax
0040176C |. 8D7D B8 |lea edi, dword ptr [ebp-48]
0040176F |. F3:AB |rep stos dword ptr es:[edi]
00401771 |. 8D45 B8 |lea eax, dword ptr [ebp-48]
00401774 |. C745 B8 44000>|mov dword ptr [ebp-48], 44
0040177B |. 50 |push eax
0040177C |. FFD6 |call esi
0040177E |. 8B45 C8 |mov eax, dword ptr [ebp-38]
00401781 |. 85C0 |test eax, eax
00401783 |. 0F85 A5000000 |jnz 0040182E
00401789 |. 8B45 CC |mov eax, dword ptr [ebp-34]
0040178C |. 85C0 |test eax, eax
0040178E |. 0F85 9A000000 |jnz 0040182E
00401794 |. 8B45 D8 |mov eax, dword ptr [ebp-28]
00401797 |. 85C0 |test eax, eax
00401799 |. 0F85 8F000000 |jnz 0040182E
0040179F |. 8B45 DC |mov eax, dword ptr [ebp-24]
004017A2 |. 85C0 |test eax, eax
004017A4 |. 0F85 84000000 |jnz 0040182E
004017AA |. 8B45 E0 |mov eax, dword ptr [ebp-20]
004017AD |. 85C0 |test eax, eax
004017AF |. 75 7D |jnz short 0040182E
004017B1 |. 8B45 D0 |mov eax, dword ptr [ebp-30]
004017B4 |. 85C0 |test eax, eax
004017B6 |. 75 76 |jnz short 0040182E
004017B8 |. 8B45 D4 |mov eax, dword ptr [ebp-2C]
004017BB |. 85C0 |test eax, eax
004017BD |. 75 6F |jnz short 0040182E
004017BF |. 68 20414000 |push 00404120
004017C4 |. FFD3 |call ebx
004017C6 |. 0F31 |rdtsc
004017C8 |. 8955 FC |mov dword ptr [ebp-4], edx
004017CB |. 8B4D FC |mov ecx, dword ptr [ebp-4]
004017CE |. 890D 14414000 |mov dword ptr [404114], ecx
004017D4 |. 8945 FC |mov dword ptr [ebp-4], eax
004017D7 |. 8B0D 1C414000 |mov ecx, dword ptr [40411C]
004017DD |. 8B55 FC |mov edx, dword ptr [ebp-4]
004017E0 |. A1 14414000 |mov eax, dword ptr [404114]
004017E5 |. 8915 10414000 |mov dword ptr [404110], edx
004017EB |. 85C9 |test ecx, ecx
004017ED |. 75 08 |jnz short 004017F7
004017EF |. 8BC8 |mov ecx, eax
004017F1 |. 890D 1C414000 |mov dword ptr [40411C], ecx
004017F7 |> 2BC1 |sub eax, ecx
004017F9 |. 99 |cdq
004017FA |. 33C2 |xor eax, edx
004017FC |. 2BC2 |sub eax, edx
004017FE |. 83F8 10 |cmp eax, 10
00401801 |. 7F 19 |jg short 0040181C
00401803 |. 68 20414000 |push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401808 |. FF15 1C304000 |call dword ptr [<&KERNEL32.LeaveCriticalSect>; \LeaveCriticalSection
0040180E |. E8 4DFDFFFF |call 00401560
00401813 |. 85C0 |test eax, eax
00401815 |. 75 17 |jnz short 0040182E
00401817 |.^ E9 49FFFFFF \jmp 00401765
0040181C |> 68 20414000 push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401821 |. C605 F44D4000>mov byte ptr [404DF4], 1 ; |
00401828 |. FF15 1C304000 call dword ptr [<&KERNEL32.LeaveCriticalSecti>; \LeaveCriticalSection
0040182E |> 6A 00 push 0 ; /ExitCode = 0
00401830 |. C605 F44D4000>mov byte ptr [404DF4], 1 ; |
00401837 \. FF15 18304000 call dword ptr [<&KERNEL32.ExitProcess>] ; \ExitProcess
0040183D . 5F pop edi
0040183E . 5E pop esi
0040183F . 33C0 xor eax, eax
00401841 . 5B pop ebx
00401842 . 8BE5 mov esp, ebp
00401844 . 5D pop ebp
00401845 . C3 retn
6、 分别nop第一处和第二处AfxBeginThread,保存文件。nop掉第二处后程序无法启动了。那应该第一处里有检验了。(幸好没有即计算又校验,不然。。。),就用能启动的那个爆破吧。
7、来到4分析出来的关键代码处(00401BB0),里面有这句,猜测应该是提示注册成功的地方。
00401E88 |. E8 E9040000 call <jmp.&MFC42.#CDialog::DoModal_2514>
因为还没有仔细看代码,JNE改JMP保证毕跳,或者NOP掉跳转,保证程序可以执行到DoModal。还挺多地方的,函数开始的地方有两处,接近00401E88的地方还有几处。保存,本来以为大功告成了。结果,依然没有成功提示。
00401BB0下断,跟进去(猜测这里是关键代码,没错!),就在开始,有下面代码,开始没看出什么问题,执行到这里了才发现程序直接就飞了,没想明白原因,直接NOP掉(netwind版主前些天发了“2008-04-25, 00:24 [原创]趣味crackme try it!”, 其中有这样的技巧:“ key必须正确才能弹消息,key不正确时messagebox 参数就被修改了”,是不是和这个原因也相近?)。保存, 爆破成功。
00401BEC |. C645 FC 01 mov byte ptr [ebp-4], 1
00401BF0 |. 8D8E A0000000 lea ecx, dword ptr [esi+A0]
00401BF6 |. E8 B3080000 call <jmp.&MFC42.#CWnd::GetWindowTextA_3874>
00401BFB |. 8D4D F0 lea ecx, dword ptr [ebp-10]
00401BFE |. 51 push ecx
00401BFF |. 8D4E 60 lea ecx, dword ptr [esi+60]
00401C02 |. E8 A7080000 call <jmp.&MFC42.#CWnd::GetWindowTextA_3874>
程序运行启动两个线程,一个用于反调试(至少检测了调试器,检测了关键代码处的断点),另一个用于调用计算注册码的关键函数。获得输入的函数只是判断长度是否合法,不进行进一步的判断。进一步判断的由开始启动的一个线程负责。计算用了浮点运算。
调试过程:
1、在OD中直接运行,退出,有anti;
2、添加Strong OD插件,用书呆彭的“不可说不可数”法,找到关键代码处(00401A70),下断,发现下断之后,程序直接退出了,肯定有反调试的东东;
3、猜测是有其他线程在检测,用bp CreateThread下断,然后选择执行到用户代码,有两处调用MFC的AfxBeginThread,直接给nop掉,保存改后的程序,这下可以下断了。
4、在关键代码处
00401A70 /. 55 push ebp ; 关键代码
00401A71 |. 8BEC mov ebp, esp
00401A73 |. 6A FF push -1
00401A75 |. 68 D0274000 push 004027D0 ; SE 处理程序安装
00401A7A |. 64:A1 0000000>mov eax, dword ptr fs:[0]
00401A80 |. 50 push eax
00401A81 |. 64:8925 00000>mov dword ptr fs:[0], esp
00401A88 |. 83EC 10 sub esp, 10
00401A8B |. 53 push ebx
00401A8C |. 56 push esi
00401A8D |. 8BF1 mov esi, ecx
00401A8F |. 8D4D E8 lea ecx, dword ptr [ebp-18]
00401A92 |. E8 F9090000 call <jmp.&MFC42.#CString::CString_54>
00401A97 |. 33DB xor ebx, ebx
00401A99 |. 8D4D EC lea ecx, dword ptr [ebp-14]
00401A9C |. 895D FC mov dword ptr [ebp-4], ebx
00401A9F |. E8 EC090000 call <jmp.&MFC42.#CString::CString_54>
00401AA4 |. 8D45 E8 lea eax, dword ptr [ebp-18]
00401AA7 |. 8D8E A0000000 lea ecx, dword ptr [esi+A0]
00401AAD |. 50 push eax
00401AAE |. C645 FC 01 mov byte ptr [ebp-4], 1
00401AB2 |. E8 F7090000 call <jmp.&MFC42.#CWnd::GetWindowText>
; 获得用户名
00401AB7 |. 8B4D E8 mov ecx, dword ptr [ebp-18]
00401ABA |. 8B41 F8 mov eax, dword ptr [ecx-8]
00401ABD |. 3BC3 cmp eax, ebx
00401ABF |. 0F84 BE000000 je 00401B83 ; 判断用户名的长度是否合法
00401AC5 |. 83F8 05 cmp eax, 5
00401AC8 |. 0F8C B5000000 jl 00401B83
00401ACE |. 83F8 14 cmp eax, 14
00401AD1 |. 0F8F AC000000 jg 00401B83
00401AD7 |. 8D55 EC lea edx, dword ptr [ebp-14]
00401ADA |. 8D4E 60 lea ecx, dword ptr [esi+60]
00401ADD |. 52 push edx
00401ADE |. E8 CB090000 call <jmp.&MFC42.#CWnd::GetWindowText>
00401AE3 |. 8B45 EC mov eax, dword ptr [ebp-14] ; 获得密码
00401AE6 |. 8B40 F8 mov eax, dword ptr [eax-8]
00401AE9 |. 3BC3 cmp eax, ebx
00401AEB |. 0F84 92000000 je 00401B83
00401AF1 |. 0F8E 8C000000 jle 00401B83
00401AF7 |. 68 34120000 push 1234 ; /hObject = 00001234
00401AFC |. FF15 04304000 call dword ptr [<&KERNEL32.CloseHandl>; \CloseHandle
00401B02 |. 68 20414000 push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401B07 |. C745 FC 01000>mov dword ptr [ebp-4], 1
; |这个值得注意,申请进入临界对象
00401B0E |. FF15 20304000 call dword ptr [<&KERNEL32.EnterCriti>; \EnterCriticalSection
00401B14 |. 0F31 rdtsc
; 下面倒腾数据呢,没细看呢还; 但是是在进入临界区域之后; 猜测,会不会是在另一线程了进行注册码计算; 那么搜索下看看其他进入临界区域的地方; 搜这个00401B0E的 call dword ptr [403020] ; OK,只有一处,在00401C38,00401BB0是他的开始
00401B16 |. 8955 E4 mov dword ptr [ebp-1C], edx
00401B19 |. 8B4D E4 mov ecx, dword ptr [ebp-1C]
00401B1C |. 890D 04414000 mov dword ptr [404104], ecx
00401B22 |. 8945 E4 mov dword ptr [ebp-1C], eax
00401B25 |. 8B55 E4 mov edx, dword ptr [ebp-1C]
00401B28 |. 8B0D 04414000 mov ecx, dword ptr [404104]
00401B2E |. 8915 00414000 mov dword ptr [404100], edx
00401B34 |. 8B15 1C414000 mov edx, dword ptr [40411C]
00401B3A |. 8BC1 mov eax, ecx
00401B3C |. 2BC2 sub eax, edx
00401B3E |. 99 cdq
00401B3F |. 33C2 xor eax, edx
00401B41 |. 2BC2 sub eax, edx
00401B43 |. 83F8 10 cmp eax, 10
00401B46 |. 7F 30 jg short 00401B78
00401B48 |. 8B15 14414000 mov edx, dword ptr [404114]
00401B4E |. 8BC1 mov eax, ecx
00401B50 |. 2BC2 sub eax, edx
00401B52 |. 99 cdq
00401B53 |. 33C2 xor eax, edx
00401B55 |. 2BC2 sub eax, edx
00401B57 |. 83F8 10 cmp eax, 10
00401B5A |. 7F 1C jg short 00401B78
00401B5C |. 68 20414000 push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401B61 |. FF15 1C304000 call dword ptr [<&KERNEL32.LeaveCriti>; \LeaveCriticalSection
00401B67 |. 53 push ebx ; 上面没发现什么异常就退出临街区域了
00401B68 |. 53 push ebx
00401B69 |. 53 push ebx
00401B6A |. 53 push ebx
00401B6B |. 56 push esi
00401B6C |. 68 B01B4000 push 00401BB0
00401B71 |. E8 08090000 call <jmp.&MFC42.#AfxBeginThread_1105>
00401B76 |. EB 0B jmp short 00401B83
00401B78 |> 68 20414000 push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401B7D |. FF15 1C304000 call dword ptr [<&KERNEL32.LeaveCriti>; \LeaveCriticalSection
00401B83 |> 8D4D EC lea ecx, dword ptr [ebp-14] ; 退出临街区域
00401B86 |. 885D FC mov byte ptr [ebp-4], bl
00401B89 |. E8 F6080000 call <jmp.&MFC42.#CString::~CString_8>
00401B8E |. 8D4D E8 lea ecx, dword ptr [ebp-18]
00401B91 |. C745 FC FFFFF>mov dword ptr [ebp-4], -1
00401B98 |. E8 E7080000 call <jmp.&MFC42.#CString::~CString_8>
00401B9D |. 8B4D F4 mov ecx, dword ptr [ebp-C]
00401BA0 |. 5E pop esi
00401BA1 |. 5B pop ebx
00401BA2 |. 64:890D 00000>mov dword ptr fs:[0], ecx
00401BA9 |. 8BE5 mov esp, ebp
00401BAB |. 5D pop ebp
00401BAC \. C3 retn
照上面的分析,看看00401C38处的代码,00401BB0是这段程序的开始。有获得输入的对话框,也有浮点运算,看来应该是这里了。
可是下断点,无效!对了,我把所有启动线程的地方都给咔嚓了。尝试在原来的程序上更改指令达到爆破的目的,结果改后就无法运行了,看来程序应该是进行了校验。
5、打开原始程序,AfxBeginThread的地方,稍微分析下。其实我觉得不看也罢,看了也不太明白,只是有一种特别的感觉,第一个00401690跟下去,更像是在反调试。第二个好像和计算注册码有关。这个程序,直接6步就好了。
0040143B 68 90164000 push 00401690
00401440 E8 39100000 call <jmp.&MFC42.#AfxBeginThread_1105>
……
0040144A 68 50174000 push 00401750
0040144F E8 2A100000 call <jmp.&MFC42.#AfxBeginThread_1105>
对第一个00401690,跟
00401690 /. 55 push ebp
00401691 |. 8BEC mov ebp, esp
00401693 |. 51 push ecx
00401694 |. 56 push esi
00401695 |. 57 push edi
00401696 |. 6A 00 push 0
00401698 |. 6A 00 push 0
0040169A |. 6A 00 push 0
0040169C |. 6A 00 push 0
0040169E |. 6A 00 push 0
004016A0 |. 68
D0184000 push 004018D0 ; ASCII "SVWj"
004016A5 |. E8 D40D0000 call <jmp.&MFC42.#AfxBeginThread_1105>
继续跟
004018D0 . 53 56 57 6A 0>ascii "SVWj",0
004018D5 . FF15 24304000 call dword ptr [<&KERNEL32.GetModuleHandleA>] ; \GetModuleHandleA
004018DB . 8BF0 mov esi, eax
004018DD . 8B46 3C mov eax, dword ptr [esi+3C]
004018E0 . 03C6 add eax, esi
004018E2 . 33C9 xor ecx, ecx
004018E4 . 66:8B48 14 mov cx, word ptr [eax+14]
004018E8 . 8B58 FC mov ebx, dword ptr [eax-4]
004018EB . 8D7C01 18 lea edi, dword ptr [ecx+eax+18]
004018EF > 8B57 08 mov edx, dword ptr [edi+8]
004018F2 . 8BC6 mov eax, esi
004018F4 . 52 push edx
004018F5 . 8B57 0C mov edx, dword ptr [edi+C]
004018F8 . 03C2 add eax, edx
004018FA . 50 push eax
004018FB . E8 50FFFFFF call 00401850
00401900 . 83C4 08 add esp, 8
00401903 . 3BD8 cmp ebx, eax
00401905 .^ 74 E8 je short 004018EF
00401907 . 6A 00 push 0 ; /ExitCode = 0
00401909 . FF15 18304000 call dword ptr [<&KERNEL32.ExitProcess>] ; \ExitProcess
0040190F . 5F pop edi
00401910 . 5E pop esi
00401911 . 33C0 xor eax, eax
00401913 . 5B pop ebx
00401914 . C3 retn
对第二个00401750跟:
00401750 /. 55 push ebp
00401751 |. 8BEC mov ebp, esp
00401753 |. 83EC 48 sub esp, 48
00401756 |. 53 push ebx
00401757 |. 8B1D 20304000 mov ebx, dword ptr [<&KERNEL32.EnterCritical>; ntdll.RtlEnterCriticalSection
0040175D |. 56 push esi
0040175E |. 8B35 28304000 mov esi, dword ptr [<&KERNEL32.GetStartupInf>; kernel32.GetStartupInfoA
00401764 |. 57 push edi
00401765 |> B9 11000000 /mov ecx, 11
0040176A |. 33C0 |xor eax, eax
0040176C |. 8D7D B8 |lea edi, dword ptr [ebp-48]
0040176F |. F3:AB |rep stos dword ptr es:[edi]
00401771 |. 8D45 B8 |lea eax, dword ptr [ebp-48]
00401774 |. C745 B8 44000>|mov dword ptr [ebp-48], 44
0040177B |. 50 |push eax
0040177C |. FFD6 |call esi
0040177E |. 8B45 C8 |mov eax, dword ptr [ebp-38]
00401781 |. 85C0 |test eax, eax
00401783 |. 0F85 A5000000 |jnz 0040182E
00401789 |. 8B45 CC |mov eax, dword ptr [ebp-34]
0040178C |. 85C0 |test eax, eax
0040178E |. 0F85 9A000000 |jnz 0040182E
00401794 |. 8B45 D8 |mov eax, dword ptr [ebp-28]
00401797 |. 85C0 |test eax, eax
00401799 |. 0F85 8F000000 |jnz 0040182E
0040179F |. 8B45 DC |mov eax, dword ptr [ebp-24]
004017A2 |. 85C0 |test eax, eax
004017A4 |. 0F85 84000000 |jnz 0040182E
004017AA |. 8B45 E0 |mov eax, dword ptr [ebp-20]
004017AD |. 85C0 |test eax, eax
004017AF |. 75 7D |jnz short 0040182E
004017B1 |. 8B45 D0 |mov eax, dword ptr [ebp-30]
004017B4 |. 85C0 |test eax, eax
004017B6 |. 75 76 |jnz short 0040182E
004017B8 |. 8B45 D4 |mov eax, dword ptr [ebp-2C]
004017BB |. 85C0 |test eax, eax
004017BD |. 75 6F |jnz short 0040182E
004017BF |. 68 20414000 |push 00404120
004017C4 |. FFD3 |call ebx
004017C6 |. 0F31 |rdtsc
004017C8 |. 8955 FC |mov dword ptr [ebp-4], edx
004017CB |. 8B4D FC |mov ecx, dword ptr [ebp-4]
004017CE |. 890D 14414000 |mov dword ptr [404114], ecx
004017D4 |. 8945 FC |mov dword ptr [ebp-4], eax
004017D7 |. 8B0D 1C414000 |mov ecx, dword ptr [40411C]
004017DD |. 8B55 FC |mov edx, dword ptr [ebp-4]
004017E0 |. A1 14414000 |mov eax, dword ptr [404114]
004017E5 |. 8915 10414000 |mov dword ptr [404110], edx
004017EB |. 85C9 |test ecx, ecx
004017ED |. 75 08 |jnz short 004017F7
004017EF |. 8BC8 |mov ecx, eax
004017F1 |. 890D 1C414000 |mov dword ptr [40411C], ecx
004017F7 |> 2BC1 |sub eax, ecx
004017F9 |. 99 |cdq
004017FA |. 33C2 |xor eax, edx
004017FC |. 2BC2 |sub eax, edx
004017FE |. 83F8 10 |cmp eax, 10
00401801 |. 7F 19 |jg short 0040181C
00401803 |. 68 20414000 |push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401808 |. FF15 1C304000 |call dword ptr [<&KERNEL32.LeaveCriticalSect>; \LeaveCriticalSection
0040180E |. E8 4DFDFFFF |call 00401560
00401813 |. 85C0 |test eax, eax
00401815 |. 75 17 |jnz short 0040182E
00401817 |.^ E9 49FFFFFF \jmp 00401765
0040181C |> 68 20414000 push 00404120 ; /pCriticalSection = wunv队-C.00404120
00401821 |. C605 F44D4000>mov byte ptr [404DF4], 1 ; |
00401828 |. FF15 1C304000 call dword ptr [<&KERNEL32.LeaveCriticalSecti>; \LeaveCriticalSection
0040182E |> 6A 00 push 0 ; /ExitCode = 0
00401830 |. C605 F44D4000>mov byte ptr [404DF4], 1 ; |
00401837 \. FF15 18304000 call dword ptr [<&KERNEL32.ExitProcess>] ; \ExitProcess
0040183D . 5F pop edi
0040183E . 5E pop esi
0040183F . 33C0 xor eax, eax
00401841 . 5B pop ebx
00401842 . 8BE5 mov esp, ebp
00401844 . 5D pop ebp
00401845 . C3 retn
6、 分别nop第一处和第二处AfxBeginThread,保存文件。nop掉第二处后程序无法启动了。那应该第一处里有检验了。(幸好没有即计算又校验,不然。。。),就用能启动的那个爆破吧。
7、来到4分析出来的关键代码处(00401BB0),里面有这句,猜测应该是提示注册成功的地方。
00401E88 |. E8 E9040000 call <jmp.&MFC42.#CDialog::DoModal_2514>
因为还没有仔细看代码,JNE改JMP保证毕跳,或者NOP掉跳转,保证程序可以执行到DoModal。还挺多地方的,函数开始的地方有两处,接近00401E88的地方还有几处。保存,本来以为大功告成了。结果,依然没有成功提示。
00401BB0下断,跟进去(猜测这里是关键代码,没错!),就在开始,有下面代码,开始没看出什么问题,执行到这里了才发现程序直接就飞了,没想明白原因,直接NOP掉(netwind版主前些天发了“2008-04-25, 00:24 [原创]趣味crackme try it!”, 其中有这样的技巧:“ key必须正确才能弹消息,key不正确时messagebox 参数就被修改了”,是不是和这个原因也相近?)。保存, 爆破成功。
00401BEC |. C645 FC 01 mov byte ptr [ebp-4], 1
00401BF0 |. 8D8E A0000000 lea ecx, dword ptr [esi+A0]
00401BF6 |. E8 B3080000 call <jmp.&MFC42.#CWnd::GetWindowTextA_3874>
00401BFB |. 8D4D F0 lea ecx, dword ptr [ebp-10]
00401BFE |. 51 push ecx
00401BFF |. 8D4E 60 lea ecx, dword ptr [esi+60]
00401C02 |. E8 A7080000 call <jmp.&MFC42.#CWnd::GetWindowTextA_3874>
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
看原图
赞赏
雪币:
留言: