软件下载地址:
http://www.dreamingsoft.com/download/pfsetup.exe
侦壳:用PEiD查壳,Armadillo 1.xx - 2.xx -> Silicon Realms Toolworks 加壳,打开LordPE看见该程序有2个进程,证明该软件具有双进程特征,下面我们就必须先分离父进程,要程序把自己当成子进程运行。
.分离父进程,使程序把自己当成子进程运行
设置Ollydbg忽略所有其它异常选项。老规矩:用IsDebug 1.4插件去掉Ollydbg的调试器标志。
Ollydbg载入主程序:
00483914 > 55 push ebp // OD载入后停在这里
004B1915 |. 8BEC mov ebp,esp
004B1917 |. 6A FF push -1
004B1919 |. 68 D0B54B00 push pfDeskto.004BB5D0
004B191E |. 68 34144B00 push pfDeskto.004B1434 ; SE handler installation
004B1923 |. 64:A1 00000000 mov eax,dword ptr fs:[0]
004B1929 |. 50 push eax
004B192A |. 64:8925 0000000>mov dword ptr fs:[0],esp
004B1931 |. 83EC 58 sub esp,58
004B1934 |. 53 push ebx
004B1935 |. 56 push esi
004B1936 |. 57 push edi
004B1937 |. 8965 E8 mov dword ptr ss:[ebp-18],esp
004B193A |. FF15 68814B00 call dword ptr ds:[<&KERNEL32.GetVersion>] ; kernel32.GetVersion
命令行下断:BP OpenMutexA 然后F9运行:
77E62391 > 55 push ebp // 注意观察堆栈
77E62392 8BEC mov ebp,esp
77E62394 51 push ecx
77E62395 51 push ecx
77E62396 837D 10 00 cmp dword ptr ss:[ebp+10],0
77E6239A 56 push esi
77E6239B 0F84 C2E30100 je kernel32.77E80763
77E623A1 64:A1 18000000 mov eax,dword ptr fs:[18]
77E623A7 FF75 10 push dword ptr ss:[ebp+10]
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
注意看BP OpenMutexA 时的堆栈:
0012F5B8 0047E85D /CALL 到 OpenMutexA 来自 pptFlash.0047E857
0012F5BC 001F0001 |Access = 1F0001
0012F5C0 00000000 |Inheritable = FALSE
0012F5C4 0012FBF8 \MutexName = "7A4:A3935EA83" ★注意这个地址:0012FBF8
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
Ctrl+G:401000 键入以下代码:
00401000 60 pushad
00401001 9C pushfd
00401002 68 F8FB1200 push 12FBF8 ★ 堆栈里看到的值
00401007 33C0 xor eax,eax
00401009 50 push eax
0040100A 50 push eax
0040100B E8 B5A6A577 call kernel32.CreateMutexA
00401010 9D popfd
00401011 61 popad
00401012 - E9 7A13A677 jmp kernel32.OpenMutexA
在401000处新建起源,F9运行,再次中断在OpenMutexA处,此时Ctrl+G:401000 撤销刚才的修改的代码,使代码还原。OK,父进程分离完毕!把这段代码以二进制保存起来,下次用时直接粘贴,修改00401002处push的值就OK了。
二进制代码:60 9C 68 F8 FB 12 00 33 C0 50 50 E8 2F DB 40 7C 9D 61 E9 04 DC 40 7C
2、寻找Magic Jump,避开IAT加密
取消以前所有的断点,下断:BP GetModuleHandleA 然后F9运行:
77E5AD86 > 837C24 04 00 cmp dword ptr ss:[esp+4],0 // 断在这,注意看堆栈
77E5AD8B 0F84 37010000 je kernel32.77E5AEC8
77E5AD91 FF7424 04 push dword ptr ss:[esp+4]
77E5AD95 E8 F8050000 call kernel32.77E5B392
77E5AD9A 85C0 test eax,eax
77E5AD9C 74 08 je short kernel32.77E5ADA6
77E5AD9E FF70 04 push dword ptr ds:[eax+4]
77E5ADA1 E8 27060000 call kernel32.GetModuleHandleW
77E5ADA6 C2 0400 retn 4
在这里中断N次,然后Alt+F9返回程序。其实很好判断返回程序的时机。
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
注意看BP GetModuleHandleA 时的堆栈变化:
0012ED04 77C059FC /CALL 到 GetModuleHandleA 来自 msvcrt.77C059F6
0012ED08 77BE31AC \pModule = "kernel32.dll"
0012EDC8 772A8663 /CALL 到 GetModuleHandleA 来自 772A865D
0012EDCC 772AF8FC \pModule = "KERNEL32.DLL"
0012ECF0 770FB124 /CALL 到 GetModuleHandleA 来自 OLEAUT32.770FB11E
0012ECF4 771722E4 \pModule = "KERNEL32.DLL"
0012ECEC 770FB124 /CALL 到 GetModuleHandleA 来自 OLEAUT32.770FB11E
0012ECF0 771722E4 \pModule = "KERNEL32.DLL"
0012F570 0047DDD9 /CALL 到 GetModuleHandleA 来自 pptFlash.0047DDD3
0012F574 00000000 \pModule = NULL
0012E00C 003D60DB /CALL 到 GetModuleHandleA 来自 003D60D5
0012E010 003EB808 \pModule = "kernel32.dll"
0012E00C 003D60DB /CALL 到 GetModuleHandleA 来自 003D60D5
0012E010 003EB7FC \pModule = "user32.dll"
0012E048 003E0375 /CALL 到 GetModuleHandleA 来自 003E036F
0012E04C 00C52008 \pModule = "SHLWAPI.dll"
0012E02C 003D653E /CALL 到 GetModuleHandleA 来自 003D6538 ★注意!在这里Alt+F9返回程序
0012E030 00000000 \pModule = NULL
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
当堆栈如上变化后,就可以Alt+F9返回程序代码了。
003D6522 55 push ebp
003D6523 8BEC mov ebp,esp
003D6525 53 push ebx
003D6526 56 push esi
003D6527 57 push edi
003D6528 33FF xor edi,edi
003D652A 33DB xor ebx,ebx
003D652C 66:F745 0E FFFF test word ptr ss:[ebp+E],0FFFF
003D6532 75 03 jnz short 003D6537
003D6534 8B5D 0C mov ebx,dword ptr ss:[ebp+C]
003D6537 57 push edi
003D6538 FF15 CC903E00 call dword ptr ds:[3E90CC] ; kernel32.GetModuleHandleA
003D653E 8B4D 08 mov ecx,dword ptr ss:[ebp+8] // 返回到这里
003D6541 3BC8 cmp ecx,eax
003D6543 75 07 jnz short 003D654C
003D6545 B8 A8B33E00 mov eax,3EB3A8
003D654A EB 2F jmp short 003D657B
003D654C 393D D8B73E00 cmp dword ptr ds:[3EB7D8],edi
003D6552 B8 D8B73E00 mov eax,3EB7D8
003D6557 74 0C je short 003D6565 ★ Magic Jump ★ // 改为 :jmp 003D6565
003D6559 3B48 08 cmp ecx,dword ptr ds:[eax+8]
003D655C 74 1A je short 003D6578
003D655E 83C0 0C add eax,0C
003D6561 3938 cmp dword ptr ds:[eax],edi
003D6563 ^ 75 F4 jnz short 003D6559
003D6565 FF75 0C push dword ptr ss:[ebp+C]
003D6568 FF75 08 push dword ptr ss:[ebp+8]
003D656B FF15 F8903E00 call dword ptr ds:[3E90F8] ; kernel32.GetProcAddress
003D6571 5F pop edi
003D6572 5E pop esi
003D6573 5B pop ebx
003D6574 5D pop ebp
003D6575 C2 0800 retn 8
我已经修改了Magic Jump处
第2区段内存断点大法,直达OEP
Alt+M 查看内存,在401000区段上下“内存访问断点”,F9运行,直接中断在OEP处:
004119F2 6A 60 push 60
004119F4 68 00AA4700 push pfDeskto.0047AA00
004119F9 E8 C60D0000 call pfDeskto.004127C4
004119FE BF 94000000 mov edi,94
00411A03 8BC7 mov eax,edi
00411A05 E8 E6F6FFFF call pfDeskto.004110F0
00411A0A 8965 E8 mov dword ptr ss:[ebp-18],esp
00411A0D 8BF4 mov esi,esp
00411A0F 893E mov dword ptr ds:[esi],edi
00411A11 56 push esi
00411A12 FF15 44434700 call dword ptr ds:[474344] ; kernel32.GetVersionExA
00411A18 8B4E 10 mov ecx,dword ptr ds:[esi+10]
00411A1B 890D 24364A00 mov dword ptr ds:[4A3624],ecx
00411A21 8B46 04 mov eax,dword ptr ds:[esi+4]
00411A24 A3 30364A00 mov dword ptr ds:[4A3630],eax
00411A29 8B56 08 mov edx,dword ptr ds:[esi+8]
00411A2C 8915 34364A00 mov dword ptr ds:[4A3634],edx
00411A32 8B76 0C mov esi,dword ptr ds:[esi+C]
00411A35 81E6 FF7F0000 and esi,7FFF
00411A3B 8935 28364A00 mov dword ptr ds:[4A3628],esi
00411A41 83F9 02 cmp ecx,2
运行ImportREC 1.6,选择这个进程。把OEP改为004119F2 ,点IT AutoSearch,函数有3个是无效。剪贴以后FixDump,不能正常运行.希望FLY大哥看看是怎么回事.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)