能力值:
( LV13,RANK:760 )
|
-
-
5 楼
if (len(user)>=6 && len(code)>=6){
if (user[0]=='h' && user[5]=='b' && user[2]==code[3] && user[3]==code[5]){
MessageBox("OK!");
}
}
所以随便拼:
hrrrrb
rrrrrr
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
大概跟了一下,用户名和密码没什么算法。只是代码中使用了一些障眼法,影响了正常的分析。
程序初始化时会注册一个顶层异常处理函数:
.text:00401863 push eax ; lpProcName
.text:00401864 push offset ModuleName ; "kernel32.dll"
.text:00401869 call ds:GetModuleHandleA
.text:0040186F push eax ; hModule
.text:00401870 call ds:GetProcAddress
.text:00401876 mov dword_404168, eax
.text:0040187B push offset ExceptHandler
.text:00401880 call dword_404168 ; 这里设置了一个顶层异常处理函数!
.text:00401886 push offset LibFileName ; "user32.dll"
.text:0040188B call ds:LoadLibraryA
.text:00401891 mov [ebp+hLibModule], eax
.text:00401894 cmp [ebp+hLibModule], 0
这个按钮处理事件只是保存了输入的用户名和密码,然后用特权指令引发一个异常,从而调用刚才注册的异常处理函数来进行用户名和密码的验证!
00401A63 55 push ebp
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 ss:[ebp-C],ecx
00401A6F 6A 01 push 1
00401A71 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
00401A74 E8 F3050000 call <jmp.&MFC42.#6334_CWnd::UpdateData>
00401A79 8B45 F4 mov eax,dword ptr ss:[ebp-C]
00401A7C 83C0 60 add eax,60
00401A7F 50 push eax
00401A80 B9 78414000 mov ecx,CrackMe.00404178 ;取用户名
00401A85 E8 DC050000 call <jmp.&MFC42.#858_CString::operator=>
00401A8A 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
00401A8D 83C1 64 add ecx,64
00401A90 51 push ecx
00401A91 B9 74414000 mov ecx,CrackMe.00404174 ;取密码
00401A96 E8 CB050000 call <jmp.&MFC42.#858_CString::operator=>
00401A9B C745 F8 64000>mov dword ptr ss:[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
异常处理函数中:
.text:00401564 push ebp
.text:00401565 mov ebp, esp
.text:00401567 sub esp, 2Ch
.text:0040156A push esi
.text:0040156B push ecx
.text:0040156C mov ecx, esp
.text:0040156E mov [ebp+var_24], esp
.text:00401571 push offset unk_404178 ;用户名
.text:00401576 call CString::CString(CString const &)
.text:0040157B mov [ebp+var_28], eax
.text:0040157E call sub_401466 ;用户名检验函数
.text:00401583 add esp, 4
.text:00401586 mov [ebp+var_2C], eax ;返回值是0就完蛋!
.text:00401589 cmp [ebp+var_2C], 0
.text:0040158D jnz short loc_4015B7
.text:0040158F lea eax, [ebp+Text]
.text:00401592 push eax
.text:00401593 push offset unk_404030
.text:00401598 call sub_4014FB
.text:0040159D add esp, 8
.text:004015A0 push 0 ; unsigned int
.text:004015A2 push 0 ; unsigned int
.text:004015A4 lea ecx, [ebp+Text]
.text:004015A7 push ecx ; char *
.text:004015A8 call AfxMessageBox(char const *,uint,uint) ;用户名校验不通过的完蛋方式
.text:004015AD mov eax, 1
.text:004015B2 jmp loc_401659
.text:004015B7 ; ---------------------------------------------------------------------------
.text:004015B7
.text:004015B7 loc_4015B7: ; CODE XREF: ExceptHandler+29j
.text:004015B7 push 2
.text:004015B9 mov ecx, offset unk_404178
.text:004015BE call sub_401BD0
.text:004015C3 movsx esi, al
.text:004015C6 push 3
.text:004015C8 mov ecx, offset unk_404174
.text:004015CD call sub_401BD0
.text:004015D2 movsx edx, al
.text:004015D5 cmp esi, edx ;用户名的第三位和密码的第四位必须相同
.text:004015D7 jnz short loc_401625
.text:004015D9 push 3
.text:004015DB mov ecx, offset unk_404178
.text:004015E0 call sub_401BD0
.text:004015E5 movsx esi, al
.text:004015E8 push 5
.text:004015EA mov ecx, offset unk_404174
.text:004015EF call sub_401BD0
.text:004015F4 movsx eax, al
.text:004015F7 cmp esi, eax ;用户名的第四位和密码的第六位必须相同
.text:004015F9 jnz short loc_401625
.text:004015FB lea ecx, [ebp+Text]
.text:004015FE push ecx
.text:004015FF push offset unk_40403C
.text:00401604 call sub_4014FB ;Ok!!
.text:00401609 add esp, 8
.text:0040160C push 0 ; uType
.text:0040160E push offset Caption ; "CrackMe"
.text:00401613 lea edx, [ebp+Text]
.text:00401616 push edx ; lpText
.text:00401617 mov eax, hWnd
.text:0040161C push eax ; hWnd
.text:0040161D call ds:MessageBoxA
.text:00401623 jmp short loc_401654
.text:00401625 ; ---------------------------------------------------------------------------
.text:00401625
.text:00401625 loc_401625: ; CODE XREF: ExceptHandler+73j
.text:00401625 ; ExceptHandler+95j
.text:00401625 lea ecx, [ebp+Text]
.text:00401628 push ecx
.text:00401629 push offset unk_404030
.text:0040162E call sub_4014FB
.text:00401633 add esp, 8
.text:00401636 push 0 ; uType
.text:00401638 push offset aCrackme_0 ; "CrackMe"
.text:0040163D lea edx, [ebp+Text]
.text:00401640 push edx ; lpText
.text:00401641 mov eax, hWnd
.text:00401646 push eax ; hWnd
.text:00401647 call ds:MessageBoxA ;用户名和密码校验不通过的完蛋方式
.text:0040164D mov eax, 1
.text:00401652 jmp short loc_401659
.text:00401654 ; ---------------------------------------------------------------------------
.text:00401654
.text:00401654 loc_401654: ; CODE XREF: ExceptHandler+BFj
.text:00401654 mov eax, 1
.text:00401659
.text:00401659 loc_401659: ; CODE XREF: ExceptHandler+4Ej
.text:00401659 ; ExceptHandler+EEj
.text:00401659 pop esi
.text:0040165A mov esp, ebp
.text:0040165C pop ebp
.text:0040165D retn 4
用户名的校验:
.text:00401466 push ebp
.text:00401467 mov ebp, esp
.text:00401469 push 0FFFFFFFFh
.text:0040146B push offset SEH_401466
.text:00401470 mov eax, large fs:0
.text:00401476 push eax
.text:00401477 mov large fs:0, esp
.text:0040147E sub esp, 8
.text:00401481 mov [ebp+var_4], 0
.text:00401488 lea ecx, [ebp+arg_0]
.text:0040148B call sub_401B60
.text:00401490 cmp eax, 6 ;用户名必须大于等于6字节
.text:00401493 jl short loc_4014D4
.text:00401495 push 0
.text:00401497 lea ecx, [ebp+arg_0]
.text:0040149A call sub_401BD0
.text:0040149F movsx eax, al
.text:004014A2 cmp eax, 68h ;首字母必须是h
.text:004014A5 jnz short loc_4014D4
.text:004014A7 push 5
.text:004014A9 lea ecx, [ebp+arg_0]
.text:004014AC call sub_401BD0
.text:004014B1 movsx ecx, al
.text:004014B4 cmp ecx, 62h ;第六位必须是b
.text:004014B7 jnz short loc_4014D4
.text:004014B9 mov [ebp+var_10], 1
.text:004014C0 mov [ebp+var_4], 0FFFFFFFFh
.text:004014C7 lea ecx, [ebp+arg_0]
.text:004014CA call CString::~CString(void)
.text:004014CF mov eax, [ebp+var_10]
.text:004014D2 jmp short loc_4014ED
.text:004014D4 ; ---------------------------------------------------------------------------
.text:004014D4
.text:004014D4 loc_4014D4: ; CODE XREF: sub_401466+2Dj
.text:004014D4 ; sub_401466+3Fj
.text:004014D4 ; sub_401466+51j
.text:004014D4 mov [ebp+var_14], 0
.text:004014DB mov [ebp+var_4], 0FFFFFFFFh
.text:004014E2 lea ecx, [ebp+arg_0]
.text:004014E5 call CString::~CString(void)
.text:004014EA mov eax, [ebp+var_14]
.text:004014ED
.text:004014ED loc_4014ED: ; CODE XREF: sub_401466+6Cj
.text:004014ED mov ecx, [ebp+var_C]
.text:004014F0 mov large fs:0, ecx
.text:004014F7 mov esp, ebp
.text:004014F9 pop ebp
.text:004014FA retn
综上所述:
1、用户名必须大于等于6个字节。
2、用户名首字节必须是h。
3、用户名第六个字节必须是b。
4、用户名的第三位和密码的第四位必须相同。
5、用户名的第四位和密码的第六位必须相同。
给出一组KEY:
h****b
******
|
能力值:
( LV9,RANK:180 )
|
-
-
17 楼
此 CM 用 SetUnhandledExceptionFilter(401564h)
401564h 到底有的人执行到了, 有的人却怎么弄都不会执行到.
上面有人提到了 2 个插件 (其实现在只用StrongOD的人很多耶)
不管插件有没有效, (我没用过我也不知)
401564 要不要执行是跟 NtQueryInformationProcess(DebugPort) 有关系的.
此用于检测是否处于 ring3 调试器之下.
现在我们 Ctrl-G 到 UnhandledExceptionFilter 吧, 往下没几行马上可以看到这一段 :
(kernel32领空)
77E7AA62 53 push ebx
77E7AA63 6A 04 push 4
77E7AA65 8D45 C8 lea eax, [ebp-38]
77E7AA68 50 push eax
77E7AA69 6A 07 push 7
77E7AA6B E8 3B90FEFF call GetCurrentProcess
77E7AA70 50 push eax
77E7AA71 FF15 B810E677 call [<&NTDLL.NtQueryInformationProcess>]
77E7AA77 3BC3 cmp eax, ebx
77E7AA79 7C 09 jl short 77E7AA84
77E7AA7B 395D C8 cmp [ebp-38], ebx
77E7AA7E 0F85 16020000 jnz 77E7AC9A
77E7AA84 A1 4C04EC77 mov eax, [77EC044C]
77E7AA89 3BC3 cmp eax, ebx
77E7AA8B 74 15 je short 77E7AAA2
77E7AA8D 56 push esi
77E7AA8E FFD0 call eax
77E7AA90 83F8 01 cmp eax, 1
上面的 push 7 , 7 就是 DebugPort 的意思
cmp [ebp-38], ebx (ebx=0), 就是在看是否处于被调试状态
若不是的话才会 77E7AA8E call eax (eax=401564)
所以..知道该怎么做了吧: 下个断点在 77E7AA7E , 不要让他跳即可.
若前面提到的插件有效的话, 也是因为插件hook了NtQueryInformationProcess
影响到上面 UnhandledExceptionFilter 的这一处.
这是一个自毁式时MsgBox的 CM.
|
能力值:
( LV2,RANK:10 )
|
-
-
20 楼
我分析了下加密原理:首先调用SetUnhandledExceptionFilter注册一个异常处理回调(我们假设叫ExceptionHandler), 当点确认时用hlt指令(这个应该是内嵌的一条汇编指令)产生一个异常,系统会调用我们刚才注册的回调函数,在回调函数里面获取用户名和密码并校验。具体校验算法见楼上的。用OD调试时不能把hlt指令干掉,只有产生异常才能调用我们注册的异常回调来校验
|
能力值:
( LV2,RANK:10 )
|
-
-
23 楼
分析的思路:1.看OnInit函数中是否有anti程序。2.看OnInitDialog函数中是否有anti。3.看看是否有timer做anti。4.看看确定按钮的响应函数
对于确定按钮的响应函数中的hlt,作用是引发一个异常,从而让程序进入异常处理,直接把hlt改成jmp 00401564,就能够继续调试程序了。
这个crackme貌似没有任何的anti,不知道我说的对不对,望各位大大指正,谢谢:)
|
能力值:
( LV9,RANK:180 )
|
-
-
24 楼
所言当真?
anti的插件只留 StrongOD , 试试. [另一方法]
将CrackMe.exe文件, 位址 1564h 的 55 8B 改为 EB FE
直接执行 CrackMe.exe , 按[确定]之后执行 OllyDbg 并 Attach 此 CrackMe.exe
Attach 进来之后按 Alt-M 在 .text 按 F2 , 按 F9
断下来后, 将 EB FE 改回 55 8B , 就可开始动态追算法了.
|
能力值:
( LV9,RANK:160 )
|
-
-
25 楼
换了个地方,去掉所有的插件,s大说的实现了。谢谢热心的s大!
唯一有点不同的是,我这里从[<&NTDLL.NtQueryInformationProcess>]到call eax (eax=401564)
中间不像s大的那样只有几行代码,中间还是有挺多跳转的,水平有限,也看不大明白。。
7C8630D1 FF15 AC10807C [COLOR="Red"]call dword ptr ds:[<&ntdll.NtQueryInform>; [/COLOR]ntdll.ZwQueryInformationProcess
7C8630D7 85C0 test eax,eax
7C8630D9 0F8C A4000000 jl kernel32.7C863183
7C8630DF 33DB xor ebx,ebx
7C8630E1 399D B4FAFFFF cmp dword ptr ss:[ebp-54C],ebx
7C8630E7 0F84 96000000 je kernel32.7C863183
7C8630ED 64:A1 18000000 mov eax,dword ptr fs:[18]
7C8630F3 8B40 30 mov eax,dword ptr ds:[eax+30]
7C8630F6 F640 69 01 test byte ptr ds:[eax+69],1
7C8630FA 0F84 A6080000 je kernel32.7C8639A6
7C863100 8B06 mov eax,dword ptr ds:[esi]
7C863102 3938 cmp dword ptr ds:[eax],edi
7C863104 75 3F jnz short kernel32.7C863145
7C863106 6A 01 push 1
7C863108 68 5464887C push kernel32.7C886454
7C86310D E8 8C66FAFF call kernel32.InterlockedExchange
7C863112 85C0 test eax,eax
7C863114 75 2F jnz short kernel32.7C863145
7C863116 8B06 mov eax,dword ptr ds:[esi]
7C863118 68 3C3B867C push kernel32.7C863B3C ; ASCII ".cxr (context record)"
7C86311D FF76 04 push dword ptr ds:[esi+4]
7C863120 68 243B867C push kernel32.7C863B24 ; ASCII ".exr (exception record)"
7C863125 50 push eax
7C863126 68 043B867C push kernel32.7C863B04 ; ASCII "Code performing invalid access"
7C86312B FF70 0C push dword ptr ds:[eax+C]
7C86312E 68 E43A867C push kernel32.7C863AE4 ; ASCII "Invalid address being accessed"
7C863133 FF70 18 push dword ptr ds:[eax+18]
7C863136 68 B03A867C push kernel32.7C863AB0 ; ASCII "access violation exception for current stack trace"
7C86313B 68 02000020 push 20000002
7C863140 E8 FBC90100 call <jmp.&ntdll.RtlApplicationVerifierS>
7C863145 8B06 mov eax,dword ptr ds:[esi]
7C863147 8138 080000C0 cmp dword ptr ds:[eax],C0000008
7C86314D 0F85 53080000 jnz kernel32.7C8639A6
7C863153 6A 01 push 1
7C863155 68 5464887C push kernel32.7C886454
7C86315A E8 3F66FAFF call kernel32.InterlockedExchange
7C86315F 85C0 test eax,eax
7C863161 0F85 3F080000 jnz kernel32.7C8639A6
7C863167 53 push ebx
7C863168 53 push ebx
7C863169 53 push ebx
7C86316A 53 push ebx
7C86316B 53 push ebx
7C86316C 53 push ebx
7C86316D 53 push ebx
7C86316E 53 push ebx
7C86316F 68 7C3A867C push kernel32.7C863A7C ; ASCII "invalid handle exception for current stack trace"
7C863174 68 00030020 push 20000300
7C863179 E8 C2C90100 call <jmp.&ntdll.RtlApplicationVerifierS>
7C86317E E9 23080000 jmp kernel32.7C8639A6
7C863183 BB 8047887C mov ebx,kernel32.7C884780
7C863188 53 push ebx
7C863189 FF15 8011807C call dword ptr ds:[<&ntdll.RtlEnterCriti>; ntdll.RtlEnterCriticalSection
7C86318F A1 AC43887C mov eax,dword ptr ds:[7C8843AC]
7C863194 8985 3CFAFFFF mov dword ptr ss:[ebp-5C4],eax
7C86319A B9 85000000 mov ecx,85
7C86319F BE E068887C mov esi,kernel32.7C8868E0
7C8631A4 8DBD D0FCFFFF lea edi,dword ptr ss:[ebp-330]
7C8631AA F3:A5 rep movs dword ptr es:[edi],dword ptr ds>
7C8631AC 53 push ebx
7C8631AD FF15 7C11807C call dword ptr ds:[<&ntdll.RtlLeaveCriti>; ntdll.RtlLeaveCriticalSection
7C8631B3 FFB5 3CFAFFFF push dword ptr ss:[ebp-5C4]
7C8631B9 E8 D8CFFAFF call <jmp.&ntdll.RtlDecodePointer>
7C8631BE 8BF0 mov esi,eax
7C8631C0 85F6 test esi,esi
7C8631C2 0F84 80000000 je kernel32.7C863248
7C8631C8 8D85 BCFAFFFF lea eax,dword ptr ss:[ebp-544]
7C8631CE 50 push eax
7C8631CF 56 push esi
7C8631D0 E8 DFFAFFFF call kernel32.7C862CB4
7C8631D5 85C0 test eax,eax
7C8631D7 74 6F je short kernel32.7C863248
7C8631D9 8B85 BCFAFFFF mov eax,dword ptr ss:[ebp-544]
7C8631DF 3B85 D0FCFFFF cmp eax,dword ptr ss:[ebp-330]
7C8631E5 75 61 jnz short kernel32.7C863248
7C8631E7 8B85 C4FAFFFF mov eax,dword ptr ss:[ebp-53C]
7C8631ED 3B85 D8FCFFFF cmp eax,dword ptr ss:[ebp-328]
7C8631F3 75 53 jnz short kernel32.7C863248
7C8631F5 8B85 C0FAFFFF mov eax,dword ptr ss:[ebp-540]
7C8631FB 3B85 D4FCFFFF cmp eax,dword ptr ss:[ebp-32C]
7C863201 75 45 jnz short kernel32.7C863248
7C863203 A9 00000001 test eax,1000000
7C863208 74 1D je short kernel32.7C863227
7C86320A 8D85 DCFCFFFF lea eax,dword ptr ss:[ebp-324]
7C863210 50 push eax
7C863211 8D85 C8FAFFFF lea eax,dword ptr ss:[ebp-538]
7C863217 50 push eax
7C863218 FF15 F411807C call dword ptr ds:[<&ntdll.wcscmp>] ; ntdll.wcscmp
7C86321E 59 pop ecx
7C86321F 59 pop ecx
7C863220 F7D8 neg eax
7C863222 1BC0 sbb eax,eax
7C863224 40 inc eax
7C863225 EB 03 jmp short kernel32.7C86322A
7C863227 33C0 xor eax,eax
7C863229 40 inc eax
7C86322A 85C0 test eax,eax
7C86322C 74 1A je short kernel32.7C863248
7C86322E FFB5 88FAFFFF push dword ptr ss:[ebp-578]
7C863234 FFD6 [COLOR="red"]call esi // 这里才是那个关键的Call[/COLOR]
|