【目标来源】 crakedes.de
【下载地址】 点击下载
Creator: nivel
Objective: Unpack and stop the time trial. Make the program display always
that it has 5 trials left.
e-mail: nivel_999@yahoo.com
Hint: The program has anti-sice,anti-monitoring and other protections.
When you unpack it this protections will be removed.
【破解目标】:作者说得,脱掉它,在qj她!
【破解作者】:mejy【人称IPB脱盲】
【作者声明】:练手的咚咚,不对之处敬请谅解!
【简要介绍】:该壳虽然不是很难,在当今壳世界中只能算是小儿科,但是用了很多变形call和异常,
还有SMC技术,监测CC,检测调试器等技术。输入表的处理又比较弱,菜鸟研究起来也别有一番风味呀!
【脱壳过程】:
(1)查壳:拿出peid-监测结果ARM Protector 0.1 -> SMoKE 没见过的说不知是啥咚咚,fly曰:exethield的初级版
(2)掏出脱衣利器:Ollydbg1.1
(3)载入:程序停在
代码:
00419000 > E8 04000000 CALL crackme4.00419009 //程序停在这里 入口点地址在壳段里 00419005 8360 EB 0C AND DWORD PTR DS:[EAX-15],0C 00419009 5D POP EBP
怎么样,一件一件的脱啦:)
切记切记不能心急,小心的用F8,多用F7慢慢抚摸是没错的,程序有很多假的call,一不小心你就跟飞了!
俺飞了n次
小心的F7来到下面
代码:
004190A7 47 INC EDI 004190A8 4A DEC EDX 004190A9 ^75 B4 JNZ SHORT crackme4.0041905F 这段代码是解码 004190AB EB 01 JMP SHORT crackme4.004190AE 光标停在这里F7
004190C1 E8 7E0D0000 CALL crackme4.00419E44 这个一定要用F7走
进入后发现下面的作用是检测armp区段,也就是壳区段是否有int3断点 ,后面多次用到
代码:
00419E61 EB 01 JMP SHORT crackme4.00419E64 00419E64 8A06 MOV AL,BYTE PTR DS:[ESI] 取要检测的地址 00419E66 EB 02 JMP SHORT crackme4.00419E6A 00419E6A FEC8 DEC AL 程序是为了避免自身出现CC所以先减1 00419E6C EB 01 JMP SHORT crackme4.00419E6F 00419E6F 3C CB CMP AL,0CB 这样比较 00419E71 EB 01 JMP SHORT crackme4.00419E74 00419E74 75 0B JNZ SHORT crackme4.00419E81 跳到这里 如果相等你就玩玩了 00419E76 83C4 10 ADD ESP,10 00419E79 EB 01 JMP SHORT crackme4.00419E7C 00419E7B EB 61 JMP SHORT crackme4.00419EDE 00419E7D EB 01 JMP SHORT crackme4.00419E80 00419E7F C3 RETN 00419E80 C3 RETN 00419E81 EB 01 JMP SHORT crackme4.00419E84 00419E84 46 INC ESI ; crackme4.00419002 00419E85 EB 01 JMP SHORT crackme4.00419E88 指令会变化 00419E88 ^E2 D7 LOOPD SHORT crackme4.00419E61 循环 00419E8A 58 POP EAX 00419E8B 59 POP ECX 00419E8C EB 01 JMP SHORT crackme4.00419E8F 如果比较完毕 00419E8E 60 PUSHAD 00419E8F 5E POP ESI 00419E90 C3 RETN 返回,注意不能在这里直接用F2设断,因为同样这里也有CC监测 所以在此处设内存断点,会中断两次,一次监测cc一次真正的执行指令 004190C6 EB 01 JMP SHORT crackme4.004190C9 上面返回到这里 004190C6 EB 01 JMP SHORT crackme4.004190C9 004190D6 74 5D JE SHORT crackme4.00419135 必须跳走 004190D8 EB 01 JMP SHORT crackme4.004190DB 否则跳到下面 7C816D4F 50 PUSH EAX 来到这里你也玩了 7C816D50 E8 545FFFFF CALL kernel32.ExitThread 7C816D55 90 NOP 7C816D56 90 NOP 7C816D57 90 NOP 00419D03 ^75 DD JNZ SHORT crackme4.00419CE2 00419D05 EB 01 JMP SHORT crackme4.00419D08 光标放在这里F4 00419D22 813C02 50450000 CMP DWORD PTR DS:[EDX+EAX],4550 PE文件 00419D29 ^75 E4 JNZ SHORT crackme4.00419D0F 00419D2E 8985 13304000 MOV DWORD PTR SS:[EBP+403013],EAX EAX=7C800000 00419D34 C3 RETN 走到这里会再次检测CC 在00419E90处设内存断点,两次F9之后F8 后面类似处理相同 00419EE7 E8 A6F4FFFF CALL crackme4.00419392 这个里面对系统函数有一个处理 00419EEC 66:8B13 MOV DX,WORD PTR DS:[EBX] 00419EEF 0FB7D2 MOVZX EDX,DX 00419EF2 EB 01 JMP SHORT crackme4.00419EF5 00419F0E 83C3 02 ADD EBX,2 00419F11 833C24 00 CMP DWORD PTR SS:[ESP],0 00419F15 ^77 C1 JA SHORT crackme4.00419ED8 00419FD5 EB 01 JMP SHORT crackme4.00419FD8 下面代码 计算壳所用的api 00419FD8 8B85 13304000 MOV EAX,DWORD PTR SS:[EBP+403013] ; kernel32.7C800000 很明显kernel32的地址 00419FDE FF36 PUSH DWORD PTR DS:[ESI] 00419FE0 50 PUSH EAX 00419FE1 EB 01 JMP SHORT crackme4.00419FE4 00419FE4 EB 01 JMP SHORT crackme4.00419FE7 00419FE7 F785 17304000 40000000 TEST DWORD PTR SS:[EBP+403017],40 00419FF1 EB 01 JMP SHORT crackme4.00419FF4 00419FF4 74 09 JE SHORT crackme4.00419FFF 00419FF6 EB 02 JMP SHORT crackme4.00419FFA 00419FF8 E8 00E845FE CALL FE8787FD 00419FFD FFFF ??? ; 未知命令 00419FFA E8 45FEFFFF CALL crackme4.00419E44 F7走 中间会监测该API是否有断点 00419FFF EB 01 JMP SHORT crackme4.0041A002 0041A002 E8 8AFEFFFF CALL crackme4.00419E91 取API API地址保存在[41A103] 0041A007 EB 01 JMP SHORT crackme4.0041A00A 中间会监测该API是否有断点 0041A007 EB 01 JMP SHORT crackme4.0041A00A 0041A024 8946 04 MOV DWORD PTR DS:[ESI+4],EAX ; kernel32.GetModuleHandleA 提取壳要用的API, 0041A027 83C6 08 ADD ESI,8 0041A02A EB 01 JMP SHORT crackme4.0041A02D 0041A02D FF8D D2304000 DEC DWORD PTR SS:[EBP+4030D2] 内存中的值为0xB,即要提取的API数量 0041A033 83BD D2304000 00 CMP DWORD PTR SS:[EBP+4030D2],0 比较11个壳所用的API是否处理完毕 0041A03A ^77 99 JA SHORT crackme4.00419FD5 00419145 8D85 24314000 LEA EAX,DWORD PTR SS:[EBP+403124] API地址 这时内存中可以看见 0041914B E8 04000000 CALL crackme4.00419154 中间会监测CC 004191AF EB 01 JMP SHORT crackme4.004191B2 004191B2 8DB5 DA304000 LEA ESI,DWORD PTR SS:[EBP+4030DA] 地址=0041A196, (ASCII "\\.\TRW") 004191B8 EB 02 JMP SHORT crackme4.004191BC 内存中 【 0041A18F 00 00 00 00 00 00 00 5C 5C 2E 5C 54 52 57 00 5C .......\\.\TRW.\ 0041A19F 5C 2E 5C 53 49 43 45 00 5C 5C 2E 5C 4E 54 49 43 \.\SICE.\\.\NTIC 0041A1AF 45 00 5C 5C 2E 5C 46 49 4C 45 56 58 44 00 5C 5C E.\\.\FILEVXD.\\ 0041A1BF 2E 5C 46 49 4C 45 4D 4F 4E 00 5C 5C 2E 5C 52 45 .\FILEMON.\\.\RE 0041A1CF 47 56 58 44 00 5C 5C 2E 5C 52 45 47 4D 4F 4E 00 GVXD.\\.\REGMON. 】 004191C7 803E 00 CMP BYTE PTR DS:[ESI],0 004191CA ^75 F7 JNZ SHORT crackme4.004191C3 004191D0 803E 00 CMP BYTE PTR DS:[ESI],0 004191D3 EB 03 JMP SHORT crackme4.004191D8 004191D8 75 05 JNZ SHORT crackme4.004191DF 这里可以跳过检测调试器 004191DA EB 01 JMP SHORT crackme4.004191DD 004191E8 FF95 87304000 CALL DWORD PTR SS:[EBP+403087] ; kernel32._lopen 004191EE 40 INC EAX 检测调试器了 004191EF EB 02 JMP SHORT crackme4.004191F3 004191F3 ^74 C9 JE SHORT crackme4.004191BE 一定要跳 004191F5 61 POPAD 004191F6 C3 RETN 004193FC 0F84 D8000000 JE crackme4.004194DA 小心这里,一定要跳 00419402 EB 01 JMP SHORT crackme4.00419405 00419516 8BBD 1B304000 MOV EDI,DWORD PTR SS:[EBP+40301B] ; crackme4.00400000 0041951C 037F 3C ADD EDI,DWORD PTR DS:[EDI+3C] 3C处是PE格式标志 00419522 8BF7 MOV ESI,EDI 区段信息 00419524 81C6 F8000000 ADD ESI,0F8 0041952A EB 01 JMP SHORT crackme4.0041952D 004196EB 837E 14 00 CMP DWORD PTR DS:[ESI+14],0 004196EF 74 06 JE SHORT crackme4.004196F7 004196F1 837E 10 00 CMP DWORD PTR DS:[ESI+10],0 004196F5 75 05 JNZ SHORT crackme4.004196FC 004196F7 E9 A3000000 JMP crackme4.0041979F 004196FC 8B46 0C MOV EAX,DWORD PTR DS:[ESI+C] 004196FF EB 01 JMP SHORT crackme4.00419702 0041978F E8 B0060000 CALL crackme4.00419E44 00419794 EB 02 JMP SHORT crackme4.00419798 00419798 E8 C0070000 CALL crackme4.00419F5D 中间是区段解密 004197A6 3BD3 CMP EDX,EBX 比较已经处理的区段数目和程序区段总数目 004197A8 ^0F82 3DFFFFFF JB crackme4.004196EB 004197AE EB 01 JMP SHORT crackme4.004197B1 004197B1 66:C747 06 0000 MOV WORD PTR DS:[EDI+6],0 004197B7 EB 01 JMP SHORT crackme4.004197BA 下面开始处理输入表了 004198B9 57 PUSH EDI userdll等的地址 004198BA EB 02 JMP SHORT crackme4.004198BE 004198C8 8B85 7F304000 MOV EAX,DWORD PTR SS:[EBP+40307F] ; kernel32.LoadLibraryA 004198CE EB 01 JMP SHORT crackme4.004198D1 004198EF FFD0 CALL EAX 获取API的地址 004198F1 0BC0 OR EAX,EAX ; user32.77D10000 00419984 8B56 10 MOV EDX,DWORD PTR DS:[ESI+10] 00419987 EB 01 JMP SHORT crackme4.0041998A 004199B0 0395 1B304000 ADD EDX,DWORD PTR SS:[EBP+40301B] ; crackme4.00400000 004199B6 EB 01 JMP SHORT crackme4.004199B9 00419A8E 8902 MOV DWORD PTR DS:[EDX],EAX 写入IAT 00419A90 EB 01 JMP SHORT crackme4.00419A93 其中EDX中保存着IAT的地址,因为从12000开始写起的, 00419B20 3BCA CMP ECX,EDX 是否处理完毕 第二次ecx的值就是IAT起始 00419B22 74 18 JE SHORT crackme4.00419B3C 凌晨4点了,IAT表的计算略处 到这里自己跟一下就看见了 继续走 00419B31 6A 01 PUSH 1 00419B33 51 PUSH ECX 00419B34 EB 01 JMP SHORT crackme4.00419B37 00419B42 83C2 04 ADD EDX,4 00419B45 8339 00 CMP DWORD PTR DS:[ECX],0 00419B48 ^0F85 7AFEFFFF JNZ crackme4.004199C8 00419B4E EB 01 JMP SHORT crackme4.00419B51 00419B6C 83C6 14 ADD ESI,14 00419B6F 33C0 XOR EAX,EAX 00419B71 837E 10 00 CMP DWORD PTR DS:[ESI+10],0 00419B75 ^0F85 C5FCFFFF JNZ crackme4.00419840 00419B7B EB 01 JMP SHORT crackme4.00419B7E 00419F50 ^E2 F7 LOOPD SHORT crackme4.00419F49 00419F52 8D85 30314000 LEA EAX,DWORD PTR SS:[EBP+403130] F4 0041A226 ^E2 F7 LOOPD SHORT crackme4.0041A21F 0041A228 61 POPAD F4到这 0041A22C 50 PUSH EAX ; crackme4.00419B86 下面有一个0地址异常,EAx是异常的结束点,在EAX处F2设断,然后SHIFT+F9 0041A22D EB 01 JMP SHORT crackme4.0041A230 0041A22F EB 64 JMP SHORT crackme4.0041A295 来到 00419B86 EB 01 JMP SHORT crackme4.00419B89 取消这里的断点 来到 00419BC1 8986 B8000000 MOV DWORD PTR DS:[ESI+B8],EAX ; crackme4.00407C2E EAX中就是OEP,呵呵用异常这样处理,我们在OEP处F2,然后SHIFT+F9就道OEP了 00419BC7 B8 00000000 MOV EAX,0 00419BCC EB 01 JMP SHORT crackme4.00419BCF
到这里完毕,打开LordPe修复一下,OEP=7C2E就可以用了,到达OEP的方法有点好玩。
【脱壳方法总结】
1 载入程序
2 0041912A 74 09 JE SHORT crackme4.00419135 设置硬件访问断点,改变这里的跳转使它跳
3 004193FC 0F84 D8000000 JE crackme4.004194DA 设置硬件访问断点 使她跳
00419A8E 8902 MOV DWORD PTR DS:[EDX],EAX 这里也可以设硬件断点,可以看得IAT
DS:[004120F8]=17CE3053
4 00419B86 EB 01 JMP SHORT crackme4.00419B89 设置硬件断点 SHIFT+F9
5 00407C2E 55 PUSH EBP 设置内存访问断点 SHIFT+F9
停在这里后,就可以dump程序了。
【破解】
可以反汇编看看,这里直接跟了,猜它注册信息保存在注册表中,不信你可以用OD的搜索当前模块函数看看,然后设断
小讨厌:你不防先运行一次程序,关掉在运行一次,呵呵,出错了吧!是脱壳没脱干净吗?非也,作者在这里放了个苍蝇
代码:
00401300 |. 8D5424 00 LEA EDX,DWORD PTR SS:[ESP] 00401304 |. 51 PUSH ECX ; /pDisposition 00401305 |. 52 PUSH EDX ; |pHandle 00401306 |. 6A 00 PUSH 0 ; |pSecurity = NULL 00401308 |. 68 3F000F00 PUSH 0F003F ; |Access = KEY_ALL_ACCESS 0040130D |. 6A 00 PUSH 0 ; |Options = REG_OPTION_NON_VOLATILE 0040130F |. 6A 00 PUSH 0 ; |Class = NULL 00401311 |. 6A 00 PUSH 0 ; |Reserved = 0 00401313 |. 68 34524100 PUSH dumped_.00415234 ; |Subkey = "nv" 00401318 |. 50 PUSH EAX ; |hKey 00401319 |. FF15 0C204100 CALL DWORD PTR DS:[<&advapi32.RegCreateKeyExA>] ; \RegCreateKeyExA 0040131F |. 8B4424 08 MOV EAX,DWORD PTR SS:[ESP+8] 00401323 |. 83F8 01 CMP EAX,1 00401326 75 1D JNZ SHORT dumped_.00401345 呵呵,这里如果注册表中有值的话 这里跳走 00401328 |. 8B4C24 00 MOV ECX,DWORD PTR SS:[ESP] 上面会返回到这里,当然异常退出了 00400000 4D DEC EBP 00400001 5A POP EDX 00400002 90 NOP 00400003 0003 ADD BYTE PTR DS:[EBX],AL 00400005 0000 ADD BYTE PTR DS:[EAX],AL 我们把那个苍蝇NOP掉,就可以了 用OD保存,继续载入新的程序 0040172D |. 51 PUSH ECX ; /pDisposition 0040172E |. 52 PUSH EDX ; |pHandle 0040172F |. 6A 00 PUSH 0 ; |pSecurity = NULL 00401731 |. 68 3F000F00 PUSH 0F003F ; |Access = KEY_ALL_ACCESS 00401736 |. 6A 00 PUSH 0 ; |Options = REG_OPTION_NON_VOLATILE 00401738 |. 68 9C524100 PUSH dumped1_.0041529C ; |Class = "REG_SZ" 0040173D |. 6A 00 PUSH 0 ; |Reserved = 0 0040173F |. 68 98524100 PUSH dumped1_.00415298 ; |Subkey = "niv" 00401744 |. 50 PUSH EAX ; |hKey 00401745 |. FF15 0C204100 CALL DWORD PTR DS:[<&advapi32.RegCreateKeyExA>] ; \RegCreateKeyExA 0040174B |. 8B4424 0C MOV EAX,DWORD PTR SS:[ESP+C] 0040174F |. 5F POP EDI 00401750 |. 83F8 01 CMP EAX,1 00401753 75 23 JNZ SHORT dumped1_.00401778 这里比较是否已经存在该建值,有的话会进行操作 没有会给他赋个值,呵呵,既然这样我们就每次都给他赋新值就可以了吗 我们把它也NOP掉 00401755 |. 8B4C24 00 MOV ECX,DWORD PTR SS:[ESP] 00401759 |. 6A 03 PUSH 3 ; /Length = 3 0040175B |. 68 94524100 PUSH dumped1_.00415294 ; |Value = "535" 00401760 |. 50 PUSH EAX ; |ValueType 00401761 |. 6A 00 PUSH 0 ; |Subkey = NULL 00401763 |. 51 PUSH ECX ; |hKey 004014C7 |. 75 1B JNZ SHORT dumped1_.004014E4 比较是否过期 004014C9 |. 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL 004014CB |. 68 64524100 PUSH dumped1_.00415264 ; |Title = "Warning" 004014D0 |. 68 4C524100 PUSH dumped1_.0041524C ; |Text = "Your trial has expired" 004014D5 |. 6A 00 PUSH 0 ; |hOwner = NULL 004014D7 |. FF15 00214100 CALL DWORD PTR DS:[<&user32.MessageBoxA>] ; \MessageBoxA 004014DD |. 6A 01 PUSH 1 004014DF |. E8 AB5B0000 CALL dumped1_.0040708F 004014E4 \> C3 RETN 还有很多地方可以爆破这个程序
【后记】好累呀!脱壳好累!
本unpack我等菜鸟练手实在不错
感谢ipb群一起灌水的大大们,陪我度过的美好时光,呵呵!