大家好,早闻看雪高手云集,这里学习的技术气氛也很好,一直关注, 第一次发贴,还请多多关照。
是一个关于“PECompact 2.x -> Jeremy Collake”壳的问题,dump下来后,修复了,不能运行,困扰了好久,在百度和谷歌上都找不到类似的问题,故特来请教。
简单的说,是一个程序,用“PECompact 2.x”加了壳后,我找到了正确的oep,dump下来,却不能运行,修复IAT表后,问题依旧,通过OD跟踪,发现问题可能是壳做了加密之类的手脚,把一些程序的代码放在内存很远的地址,dump下来的文件中不包括那些数据,结果执行后访问内存出错。
以下是一些片段:
******************* 加壳程序刚载入OD时的代码 *************
00422D7E >/$ B8 24164600 mov eax, 00461624
00422D83 |. 50 push eax
00422D84 |? 64:FF35 00000>push dword ptr fs:[0]
00422D8B |? 64:8925 00000>mov dword ptr fs:[0], esp
00422D92 |? 33C0 xor eax, eax
00422D94 |. 8908 mov dword ptr [eax], ecx
00422D96 |? 50 push eax
00422D97 |? 45 inc ebp
00422D98 |? 43 inc ebx
00422D99 |? 6F outs dx, dword ptr es:[edi]
00422D9A |? 6D ins dword ptr es:[edi], dx
00422D9B |. 70 61 jo short 00422DFE
00422D9D |? 637432 00 arpl word ptr [edx+esi], si
00422DA1 |. EB 6B jmp short 00422E0E
*******************************************************
程序默认载入是00400000,刚进来时,在009a0000这么很远的地址处是访问不到的,可是当壳解压后,把一小段数据放在了这里,以后dump的程序就是因为访问此类地方出错。
*************** 找到了解壳后的OEP ************************
00422D7E >/$ 55 push ebp <--- oep(
此处是在一段pop后,jump eax到达的,dump下来后可以用peid看,没有问题)
00422D7F |. 8BEC mov ebp, esp
00422D81 |. 6A FF push -1
00422D83 |. 68 98B04200 push 0042B098
00422D88 |. 68 E22E4200 push 00422EE2 ; jmp to msvcrt._except_handler3; SE handler installation
00422D8D |. 64:A1 0000000>mov eax, dword ptr fs:[0]
00422D93 |. 50 push eax
00422D94 |. 64:8925 00000>mov dword ptr fs:[0], esp
00422D9B |. 83EC 68 sub esp, 68
00422D9E |. 53 push ebx
00422D9F |. 56 push esi
00422DA0 |. 57 push edi
00422DA1 |. 8965 E8 mov dword ptr [ebp-18], esp
00422DA4 |. 33DB xor ebx, ebx
00422DA6 |. 895D FC mov dword ptr [ebp-4], ebx
00422DA9 |. 6A 02 push 2
00422DAB |. FF15 80554200 call dword ptr [425580] ; msvcrt.__set_app_type
00422DB1 |. 59 pop ecx
00422DB2 |. 830D 40354500>or dword ptr [453540], FFFFFFFF
00422DB9 |. 830D 44354500>or dword ptr [453544], FFFFFFFF
00422DC0 |. FF15 84554200 call dword ptr [425584] ; msvcrt.__p__fmode
00422DC6 |. 8B0D 30354500 mov ecx, dword ptr [453530]
*******************************************************
注意,此时,在009a0000这个地址开始就有值了,是壳解到这里的,类似的还有003a0000之类的地方,在oep处可以通过D 看这个地址,实际上就是:
009A0000 B8 8200817C mov eax, kernel32.GlobalUnlock
009A0005 FFE0 jmp eax
009A0007 B8 1901817C mov eax, kernel32.GlobalLock
009A000C FFE0 jmp eax
009A000E B8 2DFF807C mov eax, kernel32.GlobalAlloc
009A0013 FFE0 jmp eax
009A0015 B8 57B3807C mov eax, kernel32.GetModuleFileNameA
009A001A FFE0 jmp eax
009A001C B8 4399807C mov eax, kernel32.GetACP
009A0021 FFE0 jmp eax
009A0023 B8 4224807C mov eax, kernel32.Sleep
009A0028 FFE0 jmp eax
009A002A B8 AB14817C mov eax, kernel32.GetVersion
009A002F FFE0 jmp eax
009A0031 B8 48013A00 mov eax, 3A0148 <--------
009A0036 FFE0 jmp eax
009A0038 B8 3103937C mov eax, ntdll.RtlGetLastWin32Error
009A003D FFE0 jmp eax
009A003F B8 BDE4817C mov eax, kernel32.CreateEventA
009A0044 FFE0 jmp eax
009A0046 B8 161E807C mov eax, kernel32.TerminateProcess
009A004B FFE0 jmp eax
009A004D B8 3025807C mov eax, kernel32.WaitForSingleObjec>
009A0052 FFE0 jmp eax
009A0054 B8 779B807C mov eax, kernel32.CloseHandle
********************************************************
然后我把oep处的dump下来后,运行,代码到这里:
00422E20 |. 50 push eax
00422E21 |. FF35 24354500 push dword ptr [453524]
00422E27 |. 8D45 9C lea eax, dword ptr [ebp-64]
00422E2A |. 50 push eax
00422E2B |. 8D45 90 lea eax, dword ptr [ebp-70]
00422E2E |. 50 push eax
00422E2F |. 8D45 A0 lea eax, dword ptr [ebp-60]
00422E32 |. 50 push eax
00422E33 |. FF15 74554200 call dword ptr [425574] ; msvcrt.__getmainargs
00422E39 |. 68 30F04200 push 0042F030
00422E3E |. 68 00F04200 push 0042F000
00422E43 |. E8 B2000000 call 00422EFA <------------ ; break 进入
00422E48 |. 83C4 24 add esp, 24
00422E4B |. A1 70554200 mov eax, dword ptr [425570]
00422E50 |. 8B30 mov esi, dword ptr [eax]
*******************************************
会发现最终来到这里
00406CC0 . B9 EC7B4400 mov ecx, 00447BEC
00406CC5 . E9 12BA0100 jmp 004226DC ; jmp to MFC42.#800_CString::~CString
00406CCA 90 nop
00406CCB 90 nop
00406CCC 90 nop
00406CCD 90 nop
00406CCE 90 nop
00406CCF 90 nop
00406CD0 . E9 0B000000 jmp 00406CE0
00406CD5 90 nop
00406CD6 90 nop
00406CD7 90 nop
00406CD8 90 nop
00406CD9 90 nop
00406CDA 90 nop
00406CDB 90 nop
00406CDC 90 nop
00406CDD 90 nop
00406CDE 90 nop
00406CDF 90 nop
00406CE0 > 68 68F04200 push 0042F068 ; ASCII "PEC2_IsPacked"
00406CE5 . 6A FF push -1
00406CE7 . FF15 AC504200 call dword ptr [4250AC] <-- 进入009a0000地址
00406CED . A3 E87B4400 mov dword ptr [447BE8], eax
00406CF2 . C3 retn
00406CF3 90 nop
在箭头处的[4250AC]中存的就是009a0000为首地址中的一个地址,但在我的dump程序中是没有在此处有数据的,所以出错,而原壳程序可以正常运行。
我想问的是,这个问题到底是怎么引起来的,是不是壳对IAT做了手脚,如果是,应该怎么解决呢,待高人解答。(另,我不会贴图,下次可以把图发上来,看的更清晰)谢谢了!!!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)