标签:
系统 : Windows xp
程序 : CrackMe2016
程序下载地址 :http://pan.baidu.com/s/1dDOP2Xr
要求 : 找出正确密码
使用工具 : OD & IDA
可在看雪论坛中查找关于此程序的讨论,http://bbs.pediy.com/showthread.php?t=206850
打开IDA,翻找出提示匹配成功的字串“Good job”,并向上翻找出关键代码:
004010F0 /> \55 push ebp
004010F1 |. 8BEC mov ebp, esp
004010F3 |. 81EC 44040000 sub esp, 444
004010F9 |. 53 push ebx
004010FA |. 56 push esi
004010FB |. 57 push edi
004010FC |. 8DBD BCFBFFFF lea edi, dword ptr [ebp-444]
00401102 |. B9 11010000 mov ecx, 111
00401107 |. B8 CCCCCCCC mov eax, CCCCCCCC
0040110C |. F3:AB rep stos dword ptr es:[edi]
0040110E |. C745 FC 00000>mov dword ptr [ebp-4], 0
00401115 |> B8 01000000 /mov eax, 1
0040111A |. 85C0 |test eax, eax
0040111C |. 74 5A |je short 00401178
0040111E |. 68 CC504200 |push 004250CC ; ASCII "Please input password:"
00401123 |. E8 D8030000 |call 00401500 ; _printf
00401128 |. 83C4 04 |add esp, 4 ; 平衡堆栈
0040112B |. 8D8D FCFBFFFF |lea ecx, dword ptr [ebp-404]
00401131 |. 51 |push ecx
00401132 |. 68 C8504200 |push 004250C8 ; ASCII "%s"
00401137 |. E8 64030000 |call 004014A0 ; _scanf
0040113C |. 83C4 08 |add esp, 8
0040113F |. 8D95 FCFBFFFF |lea edx, dword ptr [ebp-404] ; 取password
00401145 |. 52 |push edx ; password入栈
00401146 |. E8 BAFEFFFF |call 00401005
0040114B |. 83C4 04 |add esp, 4 ; 平衡堆栈
0040114E |. 8945 FC |mov dword ptr [ebp-4], eax
00401151 |. 817D FC 53434>|cmp dword ptr [ebp-4], 474353
00401158 |. 75 0F |jnz short 00401169
0040115A |. 68 B8504200 |push 004250B8 ; ASCII 0A,"Good job!",LF
0040115F |. E8 9C030000 |call 00401500
00401164 |. 83C4 04 |add esp, 4
00401167 |. EB 0F |jmp short 00401178
00401169 |> 68 9C504200 |push 0042509C ; ASCII "Incorrect password!",LF,LF
0040116E |. E8 8D030000 |call 00401500
00401173 |. 83C4 04 |add esp, 4
00401176 |.^ EB 9D \jmp short 00401115
00401178 |> 68 94504200 push 00425094 ; ASCII "pause"
0040117D |. E8 0E020000 call 00401390
00401182 |. 83C4 04 add esp, 4
00401185 |. 5F pop edi
00401186 |. 5E pop esi
00401187 |. 5B pop ebx
00401188 |. 81C4 44040000 add esp, 444
0040118E |. 3BEC cmp ebp, esp
00401190 |. E8 BB010000 call 00401350
00401195 |. 8BE5 mov esp, ebp
00401197 |. 5D pop ebp
00401198 \. C3 retn
F7进入401500子程序:
00401005 $ /E9 16000000 jmp 00401020
继续跟进:
00401020 /> \55 push ebp
00401021 |. 8BEC mov ebp, esp
00401023 |. 81EC C0000000 sub esp, 0C0
00401029 |. 53 push ebx
0040102A |. 56 push esi
0040102B |. 57 push edi
0040102C |. 8DBD 40FFFFFF lea edi, dword ptr [ebp-C0] ; 取一段内存
00401032 |. B9 30000000 mov ecx, 30
00401037 |. B8 CCCCCCCC mov eax, CCCCCCCC
0040103C |. F3:AB rep stos dword ptr es:[edi] ; 重复拷贝将eax拷贝到【edi】中0x30次,
0040103E |. 8B45 08 mov eax, dword ptr [ebp+8] ; 取password
00401041 |. 50 push eax ; 入栈
00401042 |. 8D4D 80 lea ecx, dword ptr [ebp-80] ; 取一段内存
00401045 |. 51 push ecx ; 入栈
00401046 |. E8 15020000 call 00401260 ; 拷贝字串
0040104B |. 83C4 08 add esp, 8 ; 平衡堆栈
0040104E |. 68 6C504200 push 0042506C ; ‘看雪论坛的兄弟姐妹们,元旦快乐!’
00401053 |. 8D55 80 lea edx, dword ptr [ebp-80] ; 取password
00401056 |. 52 push edx
00401057 |. E8 74010000 call 004011D0 ; _strcmp
0040105C |. 83C4 08 add esp, 8 ; 平衡堆栈
0040105F |. 8945 F8 mov dword ptr [ebp-8], eax ; 保存比较结果
00401062 |. 8B45 08 mov eax, dword ptr [ebp+8] ; 取password
00401065 |. 50 push eax ; password入栈
00401066 |. 8D4D A8 lea ecx, dword ptr [ebp-58] ; 取一段内存
00401069 |. 51 push ecx ; 入栈
0040106A |. E8 F1010000 call 00401260 ; 拷贝字串
0040106F |. 83C4 08 add esp, 8 ; 平衡堆栈
00401072 |. 68 44504200 push 00425044 ; ‘有可能被你发现密码了,加油加油’
00401077 |. 8D55 A8 lea edx, dword ptr [ebp-58] ; 取password
0040107A |. 52 push edx ; password入栈
0040107B |. E8 50010000 call 004011D0 ; _strcmp
00401080 |. 83C4 08 add esp, 8 ; 平衡堆栈
00401083 |. 8945 F8 mov dword ptr [ebp-8], eax ; 保存比较结果
00401086 |. 8B45 08 mov eax, dword ptr [ebp+8] ; 取password
00401089 |. 50 push eax ; password入栈
0040108A |. 8D4D D0 lea ecx, dword ptr [ebp-30] ; 取一段内存
0040108D |. 51 push ecx ; 入栈
0040108E |. E8 CD010000 call 00401260 ; 拷贝字串
00401093 |. 83C4 08 add esp, 8 ; 平衡堆栈
00401096 |. 68 1C504200 push 0042501C ; ‘关键是如何输入,中文我也没办法!’
0040109B |. 8D55 D0 lea edx, dword ptr [ebp-30] ; 取password
0040109E |. 52 push edx ; password入栈
0040109F |. E8 2C010000 call 004011D0 ; _strcmp
004010A4 |. 83C4 08 add esp, 8 ; 平衡堆栈
004010A7 |. 8945 FC mov dword ptr [ebp-4], eax ; 保存比较结果
004010AA |. 8B45 F8 mov eax, dword ptr [ebp-8]
004010AD |. 5F pop edi
004010AE |. 5E pop esi
004010AF |. 5B pop ebx
004010B0 |. 81C4 C0000000 add esp, 0C0
004010B6 |. 3BEC cmp ebp, esp
004010B8 |. E8 93020000 call 00401350 ; __chkesp 只检测ebp的当前值(函数入口点的栈顶地址)和函数释放栈上空间以后的esp是否一致
004010BD |. 8BE5 mov esp, ebp
004010BF |. 5D pop ebp
004010C0 \. C3 retn
程序最终根据eax的值进行判断,eax的值来源于[ebp-8]。对[ebp-8]下内存写入断点,发现最后在给eax赋值之前最后一次写入[ebp-8]的值是在
00401083 |. 8945 F8 mov dword ptr [ebp-8], eax ; 保存比较结果
比较结果是什么呢?我们跟入_strcmp:
004011D0 /$ 8B5424 04 mov edx, dword ptr [esp+4] ; 取password
004011D4 |. 8B4C24 08 mov ecx, dword ptr [esp+8]
004011D8 |. F7C2 03000000 test edx, 3
004011DE |. 75 3C jnz short 0040121C
004011E0 |> 8B02 /mov eax, dword ptr [edx] ; 将字串当做dword数值赋给eax
004011E2 |. 3A01 |cmp al, byte ptr [ecx] ; 与‘关键是如何输入,中文我也没办法!’逐个比较
004011E4 |. 75 2E |jnz short 00401214
004011E6 |. 0AC0 |or al, al ; 字符为空?
004011E8 |. 74 26 |je short 00401210
004011EA |. 3A61 01 |cmp ah, byte ptr [ecx+1] ; 取高位继续比较
004011ED |. 75 25 |jnz short 00401214
004011EF |. 0AE4 |or ah, ah ; 字符为空?
004011F1 |. 74 1D |je short 00401210
004011F3 |. C1E8 10 |shr eax, 10 ; 逻辑右移16位
004011F6 |. 3A41 02 |cmp al, byte ptr [ecx+2] ; 取低位继续比较
004011F9 |. 75 19 |jnz short 00401214
004011FB |. 0AC0 |or al, al ; 字符为空?
004011FD |. 74 11 |je short 00401210
004011FF |. 3A61 03 |cmp ah, byte ptr [ecx+3] ; 取高位继续比较
00401202 |. 75 10 |jnz short 00401214
00401204 |. 83C1 04 |add ecx, 4
00401207 |. 83C2 04 |add edx, 4
0040120A |. 0AE4 |or ah, ah ; 字符为空?
0040120C |.^ 75 D2 \jnz short 004011E0
0040120E |. 8BFF mov edi, edi
00401210 |> 33C0 xor eax, eax
00401212 |. C3 retn
00401213 | 90 nop
00401214 |> 1BC0 sbb eax, eax
00401216 |. D1E0 shl eax, 1
00401218 |. 40 inc eax
00401219 |. C3 retn
结果只可能是两个:0和FFFFFFFF。这意味着我们不能通过普通的手段来进行破解,只能修改程序结构(爆破)或是修改内存(越界攻击)。这里,我们查看[ebp-8]前后的内存区域:
执行到40108A时,[ebp-30]的内存地址是:12FAF4,相对于存放结果的位置[ebp-4]如上图所示。接下来的流程要将输入的password拷贝至[ebp-30],而程序对于password并没有做任何格式限制,这意味着理论上我们可以输入无限大的字串,直到将[ebp-4]的值覆盖掉。这里,我们随便输入40个字符就可以到达[ebp-4]的区域,对比流程,发现[ebp-4]的值应该为:53|43|47|00
最后一个字节作为字串结尾,前三个字节转化为ASCII码。最终可以通过验证的字串格式应为:任意40个占一字节的字符+"SCG"。
验证我们的猜想:
标签:
原文地址:http://www.cnblogs.com/ZRBYYXDM/p/5135080.html