-
-
[原创]另觅途径寻找OEP
-
发表于: 2005-7-17 00:46 4733
-
【破解作者】 Anwil
【作者邮箱】 略
【作者主页】 略
【使用工具】 Ollydbg、PEiD、LordPE
【破解平台】 WinXP
【软件名称】 Fraps 2.6.0.4791
【下载地址】 http://down.91.com/newhtm/318/page_305318.htm
【软件简介】 这是一款显卡辅助软件,用它可以轻松了解机器在运行游戏时的帧数,从而了解机器的性能!另外它还
具备在游戏中的截图和视频捕捉功能,可以方便的进行截图和动画捕捉!
【软件大小】 634KB
【加壳方式】 Armadillo
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【脱壳过程】
这个软件用常规的方法来脱是行不通的,但却能顺利达到OEP处,行,不说废话,我们去尝试一回,回顾以前常规脱壳思路
以及如果来解决这一问题。
设置Ollydbg忽略所有的异常选项,用IsDebug 1.4插件去掉Ollydbg的调试器标志。
009E0B93 f>/$ 55 push ebp ; 进入OD后停在这里
009E0B94 |. 8BEC mov ebp,esp
009E0B96 |. 6A FF push -1
009E0B98 |. 68 F8AEA000 push fraps.00A0AEF8
009E0B9D |. 68 D0089E00 push fraps.009E08D0 ; SE handler installation
一、变换双进程,使程序把自己当成子进程运行
下断:BP OpenMutexA,F9运行
7C80EC1B k> 8BFF mov edi,edi ; 断在这里,留意堆栈变化
7C80EC1D 55 push ebp
7C80EC1E 8BEC mov ebp,esp
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
0012D7AC 009CC7B8 /CALL 到 OpenMutexA 来自 fraps.009CC7B2
0012D7B0 001F0001 |Access = 1F0001
0012D7B4 00000000 |Inheritable = FALSE
0012D7B8 0012DDEC \MutexName = "A58::DA62EE7DD1" ; 注意0012DDEC
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
Ctrl+G输入401000,来到以下空代码地址
00401000 0000 add byte ptr ds:[eax],al
00401002 0000 add byte ptr ds:[eax],al
00401004 0000 add byte ptr ds:[eax],al
00401006 0000 add byte ptr ds:[eax],al
00401008 0000 add byte ptr ds:[eax],al
0040100A 0000 add byte ptr ds:[eax],al
0040100C 0000 add byte ptr ds:[eax],al
0040100E 0000 add byte ptr ds:[eax],al
00401010 0000 add byte ptr ds:[eax],al
00401012 0000 add byte ptr ds:[eax],al
键入欺骗代码
00401000 60 pushad
00401001 9C pushfd
00401002 68 ECDD1200 push 12DDEC ; 堆栈里看到的值
00401007 33C0 xor eax,eax
00401009 50 push eax
0040100A 50 push eax
0040100B E8 2FDB407C call kernel32.CreateMutexA
00401010 9D popfd
00401011 61 popad
00401012 - E9 04DC407C jmp kernel32.OpenMutexA
在401000处,右键--->此处新建EIP,即新建起源,F9运行,再次中断在OpenMutexA处,取消该断点,然后返回401000处,撤消
刚才键入的所有代码,序曲结束。
二、避开IAT加密
还原输入表函数,这个是铁定的规律了,GO!
下断:He GetModuleHandleA,F9运行
7C80B529 k> 8BFF mov edi,edi ; 断在这里,留意堆栈
7C80B52B 55 push ebp
7C80B52C 8BEC mov ebp,esp
7C80B52E 837D 08 00 cmp dword ptr ss:[ebp+8],0
7C80B532 74 18 je short kernel32.7C80B54C
在这里中断六次,然后Alt+F9返回程序,并取消硬件断点
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
0012CE78 5D175394 /CALL 到 GetModuleHandleA 来自 5D17538E
0012CE7C 5D1753E0 \pModule = "kernel32.dll"
0012CE80 5D1E2B38
0012CF38 77F45BB0 /CALL 到 GetModuleHandleA 来自 SHLWAPI.77F45BAA
0012CF3C 77F44FF4 \pModule = "KERNEL32.DLL"
0012CF40 00000001
0012D750 009CB8F3 /CALL 到 GetModuleHandleA 来自 fraps.009CB8ED
0012D754 00000000 \pModule = NULL
0012D758 0000FFFF
00127D24 011F20BF /CALL 到 GetModuleHandleA 来自 011F20B9
00127D28 01200BAC \pModule = "kernel32.dll"
00127D2C 01201E1C ASCII "VirtualAlloc"
00127D24 011F20DC /CALL 到 GetModuleHandleA 来自 011F20D6
00127D28 01200BAC \pModule = "kernel32.dll"
00127D2C 01201E10 ASCII "VirtualFree"
00127AC4 011E4BF0 /CALL 到 GetModuleHandleA 来自 011E4BEA ; 返回的时机,GO!
00127AC8 00127C00 \pModule = "kernel32.dll"
00127ACC 0012CC74
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
011E4BEA FF15 C8B01F01 call dword ptr ds:[11FB0C8] ; kernel32.GetModuleHandleA
011E4BF0 8B0D 948D2001 mov ecx,dword ptr ds:[1208D94] ; 返回到这里
011E4BF6 89040E mov dword ptr ds:[esi+ecx],eax
011E4BF9 A1 948D2001 mov eax,dword ptr ds:[1208D94]
011E4BFE 393C06 cmp dword ptr ds:[esi+eax],edi
011E4C01 75 16 jnz short 011E4C19
011E4C03 8D85 DCFEFFFF lea eax,dword ptr ss:[ebp-124]
011E4C09 50 push eax
011E4C0A FF15 90B01F01 call dword ptr ds:[11FB090] ; kernel32.LoadLibraryA
011E4C10 8B0D 948D2001 mov ecx,dword ptr ds:[1208D94]
011E4C16 89040E mov dword ptr ds:[esi+ecx],eax
011E4C19 A1 948D2001 mov eax,dword ptr ds:[1208D94]
011E4C1E 393C06 cmp dword ptr ds:[esi+eax],edi
011E4C21 0F84 2F010000 je 011E4D56 ; Magic Jump
011E4C27 33C9 xor ecx,ecx
直接改011E4C21 jmp 011E4D56,此时修改代码也非常的容易、方便,更不需要在IAT处理结束后再还原代码了。
三、用内存断点大法直抵OEP
Alt+M 查看内存,在401000开始的段上 下内存访问断点,F9运行
0040B7E4 55 push ebp ; 红色代码区域
0040B7E5 8BEC mov ebp,esp
0040B7E7 6A FF push -1
0040B7E9 68 E0324100 push fraps.004132E0
0040B7EE 68 E0DC4000 push fraps.0040DCE0
0040B7F3 64:A1 00000000 mov eax,dword ptr fs:[0]
0040B7F9 50 push eax
0040B7FA 64:8925 00000000 mov dword ptr fs:[0],esp
0040B801 83EC 58 sub esp,58
0040B804 53 push ebx
0040B805 56 push esi
0040B806 57 push edi
0040B807 8965 E8 mov dword ptr ss:[ebp-18],esp
0040B80A FF15 8C1D3801 call dword ptr ds:[1381D8C] ; kernel32.GetVersion
0040B810 33D2 xor edx,edx
0040B812 8AD4 mov dl,ah
0040B814 8915 9C309A00 mov dword ptr ds:[9A309C],edx
0040B81A 8BC8 mov ecx,eax
0040B81C 81E1 FF000000 and ecx,0FF
0040B822 890D 98309A00 mov dword ptr ds:[9A3098],ecx
在0040B7E4处用在这儿用LordPE纠正ImageSize,发现居然无法完全DUMP这个进程,取而代之的是:“Couldn't grab
process memory.”居然无法读取被调试内存,看来程序在脱壳的过程中发生异常或者是因为其它操作导致程序无法
被dumper出来,本来以为到达OEP就算大功告成,没想到却引发其它非实质性问题,看来这次的脱壳算是完成失败。
又想到破解有时不止有一种方法,可爆破,也可用注册码完成注册,脱壳何尝不可,一怒之下重组思路,用另一种方
法来脱吧。
四、另觅途径寻找OEP
既然A计划失败,但预计中还剩一个B计划,只有不得已而为之,GO!
009E0B93 f>/$ 55 push ebp ; 再次载入OD后停在这里
009E0B94 |. 8BEC mov ebp,esp
009E0B96 |. 6A FF push -1
009E0B98 |. 68 F8AEA000 push fraps.00A0AEF8
009E0B9D |. 68 D0089E00 push fraps.009E08D0 ; SE handler installation
脱壳思路:
下BP VirtualProtect断点,F9运行,这时要留意堆?变化开始记下按F9的次数,直到程序运行,如果你在按下N次时
程序运行了,那重新载入程序下断时,要在N-1下时停止,然后选择适当的时机返回程序,这样就达到另辟途径来寻
找OEP了,OK,实例分析来得更实际,GO!
下断:BP VirtualProtect, F9 运行
7C801AD0 k> 8BFF mov edi,edi ; 断在这里,留意堆栈
7C801AD2 55 push ebp
7C801AD3 8BEC mov ebp,esp
在这里中断23次,然后Alt+F9返回程序,并取消断点
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC
0012D6C8 011D1000 |Address = 011D1000
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC
0012D6C8 011FB000 |Address = 011FB000
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC
0012D6C8 011FE000 |Address = 011FE000
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC
0012D6C8 01211000 |Address = 01211000
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC ; 在这里按F9时,进入缓冲区较大地带
0012D6C8 01214000 |Address = 01214000
00127D1C 011F4417 /CALL 到 VirtualProtect 来自 011F4411
00127D20 00401000 |Address = fraps.00401000
00127D1C 011F445E /CALL 到 VirtualProtect 来自 011F4458
00127D20 00401000 |Address = fraps.00401000
00127D1C 011F4417 /CALL 到 VirtualProtect 来自 011F4411
00127D20 00413000 |Address = fraps.00413000
00127D1C 011F445E /CALL 到 VirtualProtect 来自 011F4458
00127D20 00413000 |Address = fraps.00413000
00127D1C 011F4417 /CALL 到 VirtualProtect 来自 011F4411
00127D20 00415000 |Address = fraps.00415000
00127D1C 011F445E /CALL 到 VirtualProtect 来自 011F4458
00127D20 00415000 |Address = fraps.00415000
00127D1C 011F4417 /CALL 到 VirtualProtect 来自 011F4411
00127D20 00A8D1F0 |Address = fraps.00A8D1F0
00127D1C 011F445E /CALL 到 VirtualProtect 来自 011F4458 ; 在这里按F9时,再次进入缓冲区较大地带
00127D20 00A8D1F0 |Address = fraps.00A8D1F0
00127D1C 011F5539 /CALL 到 VirtualProtect 来自 011F5533
00127D20 00401000 |Address = fraps.00401000
00127D1C 011F56A6 /CALL 到 VirtualProtect 来自 011F56A0
00127D20 00401000 |Address = fraps.00401000
00127CF8 011F63CD /CALL 到 VirtualProtect 来自 011F63CB
00127CFC 00400000 |Address = fraps.00400000
00127CF8 011F63F9 /CALL 到 VirtualProtect 来自 011F63F7
00127CFC 00400000 |Address = fraps.00400000
00127CF8 011F6410 /CALL 到 VirtualProtect 来自 011F640E
00127CFC 00A43FE0 |Address = fraps.00A43FE0
00127CF8 011F6431 /CALL 到 VirtualProtect 来自 011F642F
00127CFC 00A43FE0 |Address = fraps.00A43FE0
00127CF8 011F643C /CALL 到 VirtualProtect 来自 011F643A
00127CFC 00400000 |Address = fraps.00400000
00127CF8 011F6450 /CALL 到 VirtualProtect 来自 011F644E
00127CFC 00400000 |Address = fraps.00400000
00127CF8 011F6469 /CALL 到 VirtualProtect 来自 011F6467
00127CFC 004000E8 |Address = fraps.004000E8
00127CF8 011F64A7 /CALL 到 VirtualProtect 来自 011F64A5 ; 返回的时机,GO!
00127CFC 004000E8 |Address = fraps.004000E8
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
因为此时再按一次F9程序就运行了,所以我们在它要运行的前一步先做点工夫,也可为寻觅OEP作铺垫!
011F64A7 5E pop esi ; kernel32.VirtualProtect
011F64A8 5F pop edi ; 返回到这里
011F64A9 5B pop ebx
011F64AA C9 leave
011F64AB C3 retn
为了方便,避免多余代码的出现,可用Ctrl+F9略过,大约几次之后,可到以下地方。
009CB912 |. 83C4 04 add esp,4 ; 返回到这里
009CB915 |. 8945 FC mov dword ptr ss:[ebp-4],eax
009CB918 |. 837D EC FF cmp dword ptr ss:[ebp-14],-1
009CB91C |. 74 0B je short fraps.009CB929 ; 跳
009CB91E |. 8B55 EC mov edx,dword ptr ss:[ebp-14]
009CB921 |. 8915 FCC2A000 mov dword ptr ds:[A0C2FC],edx
009CB927 |. EB 10 jmp short fraps.009CB939
009CB929 |> 837D FC 01 cmp dword ptr ss:[ebp-4],1
009CB92D |. 74 0A je short fraps.009CB939 ; 跳
009CB92F |. C705 FCC2A000 01000>mov dword ptr ds:[A0C2FC],1
009CB939 |> 837D B0 00 cmp dword ptr ss:[ebp-50],0
009CB93D |. 74 0A je short fraps.009CB949 ; 跳
009CB93F |. 8B45 B0 mov eax,dword ptr ss:[ebp-50]
009CB942 |. 50 push eax ; /hWnd
009CB943 |. FF15 2452A000 call dword ptr ds:[<&USER32.DestroyWindow> ; \DestroyWindow
009CB949 |> 8B45 FC mov eax,dword ptr ss:[ebp-4]
009CB94C |> 8BE5 mov esp,ebp
009CB94E |. 5D pop ebp
009CB94F \. C3 retn
009CCE61 . 8945 E4 mov dword ptr ss:[ebp-1C],eax
009CCE64 . 6A 00 push 0 ; /Arg1 = 00000000
009CCE66 . E8 6D000000 call fraps.009CCED8 ; \fraps.009CCED8
009CCE6B . 83C4 04 add esp,4
009CCE6E . 6A 00 push 0
009CCE70 . E8 37390100 call fraps.009E07AC
009CCE75 . 83C4 04 add esp,4
009CCE78 . 837D E4 01 cmp dword ptr ss:[ebp-1C],1
009CCE7C . 75 11 jnz short fraps.009CCE8F
009CCE7E . 68 08BEA000 push fraps.00A0BE08
009CCE83 . FF15 30BEA000 call dword ptr ds:[A0BE30] ; 这个CALL用F7跟进
009CCE89 . 83C4 04 add esp,4
009CCE8C . 8945 E4 mov dword ptr ss:[ebp-1C],eax
进入上面009CCE83的call之后会来到以下代码:
011F746E 53 push ebx ; 停在这里
011F746F 56 push esi
011F7470 8B7424 0C mov esi,dword ptr ss:[esp+C]
011F7474 57 push edi
011F7475 6A FE push -2
011F7477 C605 CEEC2001 01 mov byte ptr ds:[120ECCE],1
011F747E C705 70102001 401F200>mov dword ptr ds:[1201070],1201F40
011F7488 833E 02 cmp dword ptr ds:[esi],2
011F748B 5B pop ebx
011F748C 75 63 jnz short 011F74F1 ; 跳
011F748E 6A 00 push 0
011F7490 E8 4BF3FFFF call 011F67E0
011F7495 A1 084F2001 mov eax,dword ptr ds:[1204F08]
011F749A 59 pop ecx
011F749B 8B48 74 mov ecx,dword ptr ds:[eax+74]
011F749E 8B50 58 mov edx,dword ptr ds:[eax+58]
011F74A1 3348 38 xor ecx,dword ptr ds:[eax+38]
011F74A4 33CA xor ecx,edx
011F74A6 74 14 je short 011F74BC
011F74A8 8B78 48 mov edi,dword ptr ds:[eax+48]
011F74AB 3378 30 xor edi,dword ptr ds:[eax+30]
011F74AE 8B46 1C mov eax,dword ptr ds:[esi+1C]
011F74B1 33FA xor edi,edx
011F74B3 2BC7 sub eax,edi
011F74B5 03C1 add eax,ecx
011F74B7 8946 20 mov dword ptr ds:[esi+20],eax
011F74BA EB 04 jmp short 011F74C0
011F74BC 8366 20 00 and dword ptr ds:[esi+20],0
011F74C0 FF76 1C push dword ptr ds:[esi+1C]
011F74C3 E8 5C16FFFF call 011E8B24
011F74C8 59 pop ecx
011F74C9 BF C0482001 mov edi,12048C0
011F74CE 8BCF mov ecx,edi
011F74D0 E8 8D0CFEFF call 011D8162
011F74D5 84C0 test al,al
011F74D7 75 09 jnz short 011F74E2
011F74D9 6A 01 push 1
011F74DB 8BCF mov ecx,edi
011F74DD E8 B758FEFF call 011DCD99
011F74E2 B9 D8062101 mov ecx,12106D8
011F74E7 E8 F4F2FFFF call 011F67E0
011F74EC E9 A2000000 jmp 011F7593
011F74F1 E8 A3AFFEFF call 011E2499
011F74F6 C705 70102001 381F200>mov dword ptr ds:[1201070],1201F38
011F7500 E8 0ADAFEFF call 011E4F0F
011F7505 6A 00 push 0
011F7507 E8 1816FFFF call 011E8B24
011F750C 59 pop ecx
011F750D BF C0482001 mov edi,12048C0
011F7512 8BCF mov ecx,edi
011F7514 E8 490CFEFF call 011D8162
011F7519 84C0 test al,al
011F751B 75 09 jnz short 011F7526 ; 跳
011F751D 6A 01 push 1
011F751F 8BCF mov ecx,edi
011F7521 E8 7358FEFF call 011DCD99
011F7526 B9 D8062101 mov ecx,12106D8
011F752B C705 70102001 301F200>mov dword ptr ds:[1201070],1201F30
011F7535 E8 A6F2FFFF call 011F67E0
011F753A 6A 00 push 0
011F753C E8 9FF2FFFF call 011F67E0
011F7541 A1 084F2001 mov eax,dword ptr ds:[1204F08]
011F7546 59 pop ecx
011F7547 8B16 mov edx,dword ptr ds:[esi]
011F7549 8B48 74 mov ecx,dword ptr ds:[eax+74]
011F754C 3348 58 xor ecx,dword ptr ds:[eax+58]
011F754F 3348 38 xor ecx,dword ptr ds:[eax+38]
011F7552 030D 204F2001 add ecx,dword ptr ds:[1204F20] ; fraps.00400000
011F7558 85D2 test edx,edx
011F755A 75 18 jnz short 011F7574 ; 跳
011F755C 8B50 58 mov edx,dword ptr ds:[eax+58]
011F755F FF76 18 push dword ptr ds:[esi+18]
011F7562 3350 48 xor edx,dword ptr ds:[eax+48]
011F7565 FF76 14 push dword ptr ds:[esi+14]
011F7568 3350 30 xor edx,dword ptr ds:[eax+30]
011F756B FF76 10 push dword ptr ds:[esi+10]
011F756E 2BCA sub ecx,edx
011F7570 FFD1 call ecx
011F7572 EB 1D jmp short 011F7591
011F7574 83FA 01 cmp edx,1
011F7577 75 1A jnz short 011F7593
011F7579 FF76 04 push dword ptr ds:[esi+4]
011F757C 8B50 58 mov edx,dword ptr ds:[eax+58]
011F757F 3350 48 xor edx,dword ptr ds:[eax+48]
011F7582 FF76 08 push dword ptr ds:[esi+8]
011F7585 3350 30 xor edx,dword ptr ds:[eax+30]
011F7588 6A 00 push 0
011F758A FF76 0C push dword ptr ds:[esi+C]
011F758D 2BCA sub ecx,edx
011F758F FFD1 call ecx ; OEP,F7进入,代码有点变化
011F7591 8BD8 mov ebx,eax
011F7593 5F pop edi
011F7594 8BC3 mov eax,ebx
011F7596 5E pop esi
011F7597 5B pop ebx
011F7598 C3 retn
以下代码也发生了少许变化,不过程序已经完全由内存中分离出来,还愣着干什么?赶快dump啊!
0040B7E4 55 push ebp
0040B7E5 8BEC mov ebp,esp
0040B7E7 6A FF push -1
0040B7E9 68 E0324100 push fraps.004132E0
0040B7EE 68 E0DC4000 push fraps.0040DCE0
0040B7F3 64:A1 00000000 mov eax,dword ptr fs:[0]
0040B7F9 50 push eax
0040B7FA 64:8925 00000000 mov dword ptr fs:[0],esp
0040B801 83EC 58 sub esp,58
0040B804 53 push ebx
0040B805 56 push esi
0040B806 57 push edi
0040B807 8965 E8 mov dword ptr ss:[ebp-18],esp
0040B80A FF15 5C833700 call dword ptr ds:[37835C]
0040B810 33D2 xor edx,edx
0040B812 8AD4 mov dl,ah
0040B814 8915 9C309A00 mov dword ptr ds:[9A309C],edx
在0040B7E4处用LordPE纠正ImageSize,然后完全DUMP这个进程,顺利完工。
五、修复
时间关系,略过!大家可参考以前那两篇。
【后记】希望用不同状况的Armadillo来详细分析其解决之道,由于明天要出差,所以文章连夜赶工,可能比较潦草,希望
大家不要嫌弃 :)
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
【作者邮箱】 略
【作者主页】 略
【使用工具】 Ollydbg、PEiD、LordPE
【破解平台】 WinXP
【软件名称】 Fraps 2.6.0.4791
【下载地址】 http://down.91.com/newhtm/318/page_305318.htm
【软件简介】 这是一款显卡辅助软件,用它可以轻松了解机器在运行游戏时的帧数,从而了解机器的性能!另外它还
具备在游戏中的截图和视频捕捉功能,可以方便的进行截图和动画捕捉!
【软件大小】 634KB
【加壳方式】 Armadillo
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
【脱壳过程】
这个软件用常规的方法来脱是行不通的,但却能顺利达到OEP处,行,不说废话,我们去尝试一回,回顾以前常规脱壳思路
以及如果来解决这一问题。
设置Ollydbg忽略所有的异常选项,用IsDebug 1.4插件去掉Ollydbg的调试器标志。
009E0B93 f>/$ 55 push ebp ; 进入OD后停在这里
009E0B94 |. 8BEC mov ebp,esp
009E0B96 |. 6A FF push -1
009E0B98 |. 68 F8AEA000 push fraps.00A0AEF8
009E0B9D |. 68 D0089E00 push fraps.009E08D0 ; SE handler installation
一、变换双进程,使程序把自己当成子进程运行
下断:BP OpenMutexA,F9运行
7C80EC1B k> 8BFF mov edi,edi ; 断在这里,留意堆栈变化
7C80EC1D 55 push ebp
7C80EC1E 8BEC mov ebp,esp
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
0012D7AC 009CC7B8 /CALL 到 OpenMutexA 来自 fraps.009CC7B2
0012D7B0 001F0001 |Access = 1F0001
0012D7B4 00000000 |Inheritable = FALSE
0012D7B8 0012DDEC \MutexName = "A58::DA62EE7DD1" ; 注意0012DDEC
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
Ctrl+G输入401000,来到以下空代码地址
00401000 0000 add byte ptr ds:[eax],al
00401002 0000 add byte ptr ds:[eax],al
00401004 0000 add byte ptr ds:[eax],al
00401006 0000 add byte ptr ds:[eax],al
00401008 0000 add byte ptr ds:[eax],al
0040100A 0000 add byte ptr ds:[eax],al
0040100C 0000 add byte ptr ds:[eax],al
0040100E 0000 add byte ptr ds:[eax],al
00401010 0000 add byte ptr ds:[eax],al
00401012 0000 add byte ptr ds:[eax],al
键入欺骗代码
00401000 60 pushad
00401001 9C pushfd
00401002 68 ECDD1200 push 12DDEC ; 堆栈里看到的值
00401007 33C0 xor eax,eax
00401009 50 push eax
0040100A 50 push eax
0040100B E8 2FDB407C call kernel32.CreateMutexA
00401010 9D popfd
00401011 61 popad
00401012 - E9 04DC407C jmp kernel32.OpenMutexA
在401000处,右键--->此处新建EIP,即新建起源,F9运行,再次中断在OpenMutexA处,取消该断点,然后返回401000处,撤消
刚才键入的所有代码,序曲结束。
二、避开IAT加密
还原输入表函数,这个是铁定的规律了,GO!
下断:He GetModuleHandleA,F9运行
7C80B529 k> 8BFF mov edi,edi ; 断在这里,留意堆栈
7C80B52B 55 push ebp
7C80B52C 8BEC mov ebp,esp
7C80B52E 837D 08 00 cmp dword ptr ss:[ebp+8],0
7C80B532 74 18 je short kernel32.7C80B54C
在这里中断六次,然后Alt+F9返回程序,并取消硬件断点
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
0012CE78 5D175394 /CALL 到 GetModuleHandleA 来自 5D17538E
0012CE7C 5D1753E0 \pModule = "kernel32.dll"
0012CE80 5D1E2B38
0012CF38 77F45BB0 /CALL 到 GetModuleHandleA 来自 SHLWAPI.77F45BAA
0012CF3C 77F44FF4 \pModule = "KERNEL32.DLL"
0012CF40 00000001
0012D750 009CB8F3 /CALL 到 GetModuleHandleA 来自 fraps.009CB8ED
0012D754 00000000 \pModule = NULL
0012D758 0000FFFF
00127D24 011F20BF /CALL 到 GetModuleHandleA 来自 011F20B9
00127D28 01200BAC \pModule = "kernel32.dll"
00127D2C 01201E1C ASCII "VirtualAlloc"
00127D24 011F20DC /CALL 到 GetModuleHandleA 来自 011F20D6
00127D28 01200BAC \pModule = "kernel32.dll"
00127D2C 01201E10 ASCII "VirtualFree"
00127AC4 011E4BF0 /CALL 到 GetModuleHandleA 来自 011E4BEA ; 返回的时机,GO!
00127AC8 00127C00 \pModule = "kernel32.dll"
00127ACC 0012CC74
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
011E4BEA FF15 C8B01F01 call dword ptr ds:[11FB0C8] ; kernel32.GetModuleHandleA
011E4BF0 8B0D 948D2001 mov ecx,dword ptr ds:[1208D94] ; 返回到这里
011E4BF6 89040E mov dword ptr ds:[esi+ecx],eax
011E4BF9 A1 948D2001 mov eax,dword ptr ds:[1208D94]
011E4BFE 393C06 cmp dword ptr ds:[esi+eax],edi
011E4C01 75 16 jnz short 011E4C19
011E4C03 8D85 DCFEFFFF lea eax,dword ptr ss:[ebp-124]
011E4C09 50 push eax
011E4C0A FF15 90B01F01 call dword ptr ds:[11FB090] ; kernel32.LoadLibraryA
011E4C10 8B0D 948D2001 mov ecx,dword ptr ds:[1208D94]
011E4C16 89040E mov dword ptr ds:[esi+ecx],eax
011E4C19 A1 948D2001 mov eax,dword ptr ds:[1208D94]
011E4C1E 393C06 cmp dword ptr ds:[esi+eax],edi
011E4C21 0F84 2F010000 je 011E4D56 ; Magic Jump
011E4C27 33C9 xor ecx,ecx
直接改011E4C21 jmp 011E4D56,此时修改代码也非常的容易、方便,更不需要在IAT处理结束后再还原代码了。
三、用内存断点大法直抵OEP
Alt+M 查看内存,在401000开始的段上 下内存访问断点,F9运行
0040B7E4 55 push ebp ; 红色代码区域
0040B7E5 8BEC mov ebp,esp
0040B7E7 6A FF push -1
0040B7E9 68 E0324100 push fraps.004132E0
0040B7EE 68 E0DC4000 push fraps.0040DCE0
0040B7F3 64:A1 00000000 mov eax,dword ptr fs:[0]
0040B7F9 50 push eax
0040B7FA 64:8925 00000000 mov dword ptr fs:[0],esp
0040B801 83EC 58 sub esp,58
0040B804 53 push ebx
0040B805 56 push esi
0040B806 57 push edi
0040B807 8965 E8 mov dword ptr ss:[ebp-18],esp
0040B80A FF15 8C1D3801 call dword ptr ds:[1381D8C] ; kernel32.GetVersion
0040B810 33D2 xor edx,edx
0040B812 8AD4 mov dl,ah
0040B814 8915 9C309A00 mov dword ptr ds:[9A309C],edx
0040B81A 8BC8 mov ecx,eax
0040B81C 81E1 FF000000 and ecx,0FF
0040B822 890D 98309A00 mov dword ptr ds:[9A3098],ecx
在0040B7E4处用在这儿用LordPE纠正ImageSize,发现居然无法完全DUMP这个进程,取而代之的是:“Couldn't grab
process memory.”居然无法读取被调试内存,看来程序在脱壳的过程中发生异常或者是因为其它操作导致程序无法
被dumper出来,本来以为到达OEP就算大功告成,没想到却引发其它非实质性问题,看来这次的脱壳算是完成失败。
又想到破解有时不止有一种方法,可爆破,也可用注册码完成注册,脱壳何尝不可,一怒之下重组思路,用另一种方
法来脱吧。
四、另觅途径寻找OEP
既然A计划失败,但预计中还剩一个B计划,只有不得已而为之,GO!
009E0B93 f>/$ 55 push ebp ; 再次载入OD后停在这里
009E0B94 |. 8BEC mov ebp,esp
009E0B96 |. 6A FF push -1
009E0B98 |. 68 F8AEA000 push fraps.00A0AEF8
009E0B9D |. 68 D0089E00 push fraps.009E08D0 ; SE handler installation
脱壳思路:
下BP VirtualProtect断点,F9运行,这时要留意堆?变化开始记下按F9的次数,直到程序运行,如果你在按下N次时
程序运行了,那重新载入程序下断时,要在N-1下时停止,然后选择适当的时机返回程序,这样就达到另辟途径来寻
找OEP了,OK,实例分析来得更实际,GO!
下断:BP VirtualProtect, F9 运行
7C801AD0 k> 8BFF mov edi,edi ; 断在这里,留意堆栈
7C801AD2 55 push ebp
7C801AD3 8BEC mov ebp,esp
在这里中断23次,然后Alt+F9返回程序,并取消断点
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC
0012D6C8 011D1000 |Address = 011D1000
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC
0012D6C8 011FB000 |Address = 011FB000
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC
0012D6C8 011FE000 |Address = 011FE000
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC
0012D6C8 01211000 |Address = 01211000
0012D6C4 009CC2E2 /CALL 到 VirtualProtect 来自 fraps.009CC2DC ; 在这里按F9时,进入缓冲区较大地带
0012D6C8 01214000 |Address = 01214000
00127D1C 011F4417 /CALL 到 VirtualProtect 来自 011F4411
00127D20 00401000 |Address = fraps.00401000
00127D1C 011F445E /CALL 到 VirtualProtect 来自 011F4458
00127D20 00401000 |Address = fraps.00401000
00127D1C 011F4417 /CALL 到 VirtualProtect 来自 011F4411
00127D20 00413000 |Address = fraps.00413000
00127D1C 011F445E /CALL 到 VirtualProtect 来自 011F4458
00127D20 00413000 |Address = fraps.00413000
00127D1C 011F4417 /CALL 到 VirtualProtect 来自 011F4411
00127D20 00415000 |Address = fraps.00415000
00127D1C 011F445E /CALL 到 VirtualProtect 来自 011F4458
00127D20 00415000 |Address = fraps.00415000
00127D1C 011F4417 /CALL 到 VirtualProtect 来自 011F4411
00127D20 00A8D1F0 |Address = fraps.00A8D1F0
00127D1C 011F445E /CALL 到 VirtualProtect 来自 011F4458 ; 在这里按F9时,再次进入缓冲区较大地带
00127D20 00A8D1F0 |Address = fraps.00A8D1F0
00127D1C 011F5539 /CALL 到 VirtualProtect 来自 011F5533
00127D20 00401000 |Address = fraps.00401000
00127D1C 011F56A6 /CALL 到 VirtualProtect 来自 011F56A0
00127D20 00401000 |Address = fraps.00401000
00127CF8 011F63CD /CALL 到 VirtualProtect 来自 011F63CB
00127CFC 00400000 |Address = fraps.00400000
00127CF8 011F63F9 /CALL 到 VirtualProtect 来自 011F63F7
00127CFC 00400000 |Address = fraps.00400000
00127CF8 011F6410 /CALL 到 VirtualProtect 来自 011F640E
00127CFC 00A43FE0 |Address = fraps.00A43FE0
00127CF8 011F6431 /CALL 到 VirtualProtect 来自 011F642F
00127CFC 00A43FE0 |Address = fraps.00A43FE0
00127CF8 011F643C /CALL 到 VirtualProtect 来自 011F643A
00127CFC 00400000 |Address = fraps.00400000
00127CF8 011F6450 /CALL 到 VirtualProtect 来自 011F644E
00127CFC 00400000 |Address = fraps.00400000
00127CF8 011F6469 /CALL 到 VirtualProtect 来自 011F6467
00127CFC 004000E8 |Address = fraps.004000E8
00127CF8 011F64A7 /CALL 到 VirtualProtect 来自 011F64A5 ; 返回的时机,GO!
00127CFC 004000E8 |Address = fraps.004000E8
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
因为此时再按一次F9程序就运行了,所以我们在它要运行的前一步先做点工夫,也可为寻觅OEP作铺垫!
011F64A7 5E pop esi ; kernel32.VirtualProtect
011F64A8 5F pop edi ; 返回到这里
011F64A9 5B pop ebx
011F64AA C9 leave
011F64AB C3 retn
为了方便,避免多余代码的出现,可用Ctrl+F9略过,大约几次之后,可到以下地方。
009CB912 |. 83C4 04 add esp,4 ; 返回到这里
009CB915 |. 8945 FC mov dword ptr ss:[ebp-4],eax
009CB918 |. 837D EC FF cmp dword ptr ss:[ebp-14],-1
009CB91C |. 74 0B je short fraps.009CB929 ; 跳
009CB91E |. 8B55 EC mov edx,dword ptr ss:[ebp-14]
009CB921 |. 8915 FCC2A000 mov dword ptr ds:[A0C2FC],edx
009CB927 |. EB 10 jmp short fraps.009CB939
009CB929 |> 837D FC 01 cmp dword ptr ss:[ebp-4],1
009CB92D |. 74 0A je short fraps.009CB939 ; 跳
009CB92F |. C705 FCC2A000 01000>mov dword ptr ds:[A0C2FC],1
009CB939 |> 837D B0 00 cmp dword ptr ss:[ebp-50],0
009CB93D |. 74 0A je short fraps.009CB949 ; 跳
009CB93F |. 8B45 B0 mov eax,dword ptr ss:[ebp-50]
009CB942 |. 50 push eax ; /hWnd
009CB943 |. FF15 2452A000 call dword ptr ds:[<&USER32.DestroyWindow> ; \DestroyWindow
009CB949 |> 8B45 FC mov eax,dword ptr ss:[ebp-4]
009CB94C |> 8BE5 mov esp,ebp
009CB94E |. 5D pop ebp
009CB94F \. C3 retn
009CCE61 . 8945 E4 mov dword ptr ss:[ebp-1C],eax
009CCE64 . 6A 00 push 0 ; /Arg1 = 00000000
009CCE66 . E8 6D000000 call fraps.009CCED8 ; \fraps.009CCED8
009CCE6B . 83C4 04 add esp,4
009CCE6E . 6A 00 push 0
009CCE70 . E8 37390100 call fraps.009E07AC
009CCE75 . 83C4 04 add esp,4
009CCE78 . 837D E4 01 cmp dword ptr ss:[ebp-1C],1
009CCE7C . 75 11 jnz short fraps.009CCE8F
009CCE7E . 68 08BEA000 push fraps.00A0BE08
009CCE83 . FF15 30BEA000 call dword ptr ds:[A0BE30] ; 这个CALL用F7跟进
009CCE89 . 83C4 04 add esp,4
009CCE8C . 8945 E4 mov dword ptr ss:[ebp-1C],eax
进入上面009CCE83的call之后会来到以下代码:
011F746E 53 push ebx ; 停在这里
011F746F 56 push esi
011F7470 8B7424 0C mov esi,dword ptr ss:[esp+C]
011F7474 57 push edi
011F7475 6A FE push -2
011F7477 C605 CEEC2001 01 mov byte ptr ds:[120ECCE],1
011F747E C705 70102001 401F200>mov dword ptr ds:[1201070],1201F40
011F7488 833E 02 cmp dword ptr ds:[esi],2
011F748B 5B pop ebx
011F748C 75 63 jnz short 011F74F1 ; 跳
011F748E 6A 00 push 0
011F7490 E8 4BF3FFFF call 011F67E0
011F7495 A1 084F2001 mov eax,dword ptr ds:[1204F08]
011F749A 59 pop ecx
011F749B 8B48 74 mov ecx,dword ptr ds:[eax+74]
011F749E 8B50 58 mov edx,dword ptr ds:[eax+58]
011F74A1 3348 38 xor ecx,dword ptr ds:[eax+38]
011F74A4 33CA xor ecx,edx
011F74A6 74 14 je short 011F74BC
011F74A8 8B78 48 mov edi,dword ptr ds:[eax+48]
011F74AB 3378 30 xor edi,dword ptr ds:[eax+30]
011F74AE 8B46 1C mov eax,dword ptr ds:[esi+1C]
011F74B1 33FA xor edi,edx
011F74B3 2BC7 sub eax,edi
011F74B5 03C1 add eax,ecx
011F74B7 8946 20 mov dword ptr ds:[esi+20],eax
011F74BA EB 04 jmp short 011F74C0
011F74BC 8366 20 00 and dword ptr ds:[esi+20],0
011F74C0 FF76 1C push dword ptr ds:[esi+1C]
011F74C3 E8 5C16FFFF call 011E8B24
011F74C8 59 pop ecx
011F74C9 BF C0482001 mov edi,12048C0
011F74CE 8BCF mov ecx,edi
011F74D0 E8 8D0CFEFF call 011D8162
011F74D5 84C0 test al,al
011F74D7 75 09 jnz short 011F74E2
011F74D9 6A 01 push 1
011F74DB 8BCF mov ecx,edi
011F74DD E8 B758FEFF call 011DCD99
011F74E2 B9 D8062101 mov ecx,12106D8
011F74E7 E8 F4F2FFFF call 011F67E0
011F74EC E9 A2000000 jmp 011F7593
011F74F1 E8 A3AFFEFF call 011E2499
011F74F6 C705 70102001 381F200>mov dword ptr ds:[1201070],1201F38
011F7500 E8 0ADAFEFF call 011E4F0F
011F7505 6A 00 push 0
011F7507 E8 1816FFFF call 011E8B24
011F750C 59 pop ecx
011F750D BF C0482001 mov edi,12048C0
011F7512 8BCF mov ecx,edi
011F7514 E8 490CFEFF call 011D8162
011F7519 84C0 test al,al
011F751B 75 09 jnz short 011F7526 ; 跳
011F751D 6A 01 push 1
011F751F 8BCF mov ecx,edi
011F7521 E8 7358FEFF call 011DCD99
011F7526 B9 D8062101 mov ecx,12106D8
011F752B C705 70102001 301F200>mov dword ptr ds:[1201070],1201F30
011F7535 E8 A6F2FFFF call 011F67E0
011F753A 6A 00 push 0
011F753C E8 9FF2FFFF call 011F67E0
011F7541 A1 084F2001 mov eax,dword ptr ds:[1204F08]
011F7546 59 pop ecx
011F7547 8B16 mov edx,dword ptr ds:[esi]
011F7549 8B48 74 mov ecx,dword ptr ds:[eax+74]
011F754C 3348 58 xor ecx,dword ptr ds:[eax+58]
011F754F 3348 38 xor ecx,dword ptr ds:[eax+38]
011F7552 030D 204F2001 add ecx,dword ptr ds:[1204F20] ; fraps.00400000
011F7558 85D2 test edx,edx
011F755A 75 18 jnz short 011F7574 ; 跳
011F755C 8B50 58 mov edx,dword ptr ds:[eax+58]
011F755F FF76 18 push dword ptr ds:[esi+18]
011F7562 3350 48 xor edx,dword ptr ds:[eax+48]
011F7565 FF76 14 push dword ptr ds:[esi+14]
011F7568 3350 30 xor edx,dword ptr ds:[eax+30]
011F756B FF76 10 push dword ptr ds:[esi+10]
011F756E 2BCA sub ecx,edx
011F7570 FFD1 call ecx
011F7572 EB 1D jmp short 011F7591
011F7574 83FA 01 cmp edx,1
011F7577 75 1A jnz short 011F7593
011F7579 FF76 04 push dword ptr ds:[esi+4]
011F757C 8B50 58 mov edx,dword ptr ds:[eax+58]
011F757F 3350 48 xor edx,dword ptr ds:[eax+48]
011F7582 FF76 08 push dword ptr ds:[esi+8]
011F7585 3350 30 xor edx,dword ptr ds:[eax+30]
011F7588 6A 00 push 0
011F758A FF76 0C push dword ptr ds:[esi+C]
011F758D 2BCA sub ecx,edx
011F758F FFD1 call ecx ; OEP,F7进入,代码有点变化
011F7591 8BD8 mov ebx,eax
011F7593 5F pop edi
011F7594 8BC3 mov eax,ebx
011F7596 5E pop esi
011F7597 5B pop ebx
011F7598 C3 retn
以下代码也发生了少许变化,不过程序已经完全由内存中分离出来,还愣着干什么?赶快dump啊!
0040B7E4 55 push ebp
0040B7E5 8BEC mov ebp,esp
0040B7E7 6A FF push -1
0040B7E9 68 E0324100 push fraps.004132E0
0040B7EE 68 E0DC4000 push fraps.0040DCE0
0040B7F3 64:A1 00000000 mov eax,dword ptr fs:[0]
0040B7F9 50 push eax
0040B7FA 64:8925 00000000 mov dword ptr fs:[0],esp
0040B801 83EC 58 sub esp,58
0040B804 53 push ebx
0040B805 56 push esi
0040B806 57 push edi
0040B807 8965 E8 mov dword ptr ss:[ebp-18],esp
0040B80A FF15 5C833700 call dword ptr ds:[37835C]
0040B810 33D2 xor edx,edx
0040B812 8AD4 mov dl,ah
0040B814 8915 9C309A00 mov dword ptr ds:[9A309C],edx
在0040B7E4处用LordPE纠正ImageSize,然后完全DUMP这个进程,顺利完工。
五、修复
时间关系,略过!大家可参考以前那两篇。
【后记】希望用不同状况的Armadillo来详细分析其解决之道,由于明天要出差,所以文章连夜赶工,可能比较潦草,希望
大家不要嫌弃 :)
--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
他的文章
- [原创]另觅途径寻找OEP 4734
- [原创]彩尊圣手黄金版-全国彩票缩水王 V1.50的脱壳 10652
- [原创]脱Armadillo壳(两种脱法) 9823
看原图
赞赏
雪币:
留言: