首页
社区
课程
招聘
[原创]另觅途径寻找OEP
发表于: 2005-7-17 00:46 4733

[原创]另觅途径寻找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来详细分析其解决之道,由于明天要出差,所以文章连夜赶工,可能比较潦草,希望
        大家不要嫌弃 :)

--------------------------------------------------------------------------------
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 898
活跃值: (4039)
能力值: ( LV9,RANK:3410 )
在线值:
发帖
回帖
粉丝
2
1、Fraps V2.6.0.4791是单进程标准壳,因此不需要BP OpenMutexA

2、Armadillo修改了区段属性,使得无法dump,可以在OllyDGB里面直接修改各区段为完整权限,这样就可以用LordPE来dump。或者用PETools,应该可以直接dump出来

3、Fraps虽然是标准壳,但是使用了远程地址和输入表乱序

0040DB9B FF15 58033801 call dword ptr ds:[1380358]; kernel32.HeapCreate
0040DBA1 85C0 test eax,eax
0040DBA3 E9 E3912903 jmp 036A6D8B

这部分需要处理好
2005-7-17 01:29
0
游客
登录 | 注册 方可回帖
返回
//