-
-
[原创]Zprotect,与你同行
-
发表于:
2008-6-12 12:05
10546
-
Zprotect,或者说PeCancer。反正是某保护系统,感谢了一大串的XX人士。我们就直接飘过……
我们用OD陪伴他启动一次。
首先,目标的选择。如你们所见我选择的是Zp的Demo版。
Q:为什么不是正式版呢?
A:我穷……
Q:我倒……
然后我们为什么要选择Zp的Demo版
Q:主程序是软柿子?
A:不是,因为一般保护系统都喜欢用正式版的较强的保护给Demo版加壳,所以用Demo版我们可以体验仅可能多的保护。
Q:我晕……
之后,我们来看下我们的目标。Exe,明显没加壳,然后看代码,纯龙套一个。然后我们把眼光投向了Zpreotect.Dll,我们Peid一下发现第
一个区段是空的而且名字为.textbss,一般而言,编译出来的程序想重定位基址有难度,所以一般的保护都是添加区段写入自己。所以我们
用Notepad试验一下,加壳之后我们发现textbss区段依然是第一个,依然为空,而且大小刚好是Notepad的ImageSize。所以……
我们开工吧:
ZpDLL.Main
查找自己的PeHeader(话说Dll的入口参数里面不就有么……)
查找自身引入表获取GetProcAddress和LoadLibraryA
获取GPA->VirtualAlloc(0,2fdd8h,RWE)->0B50000h,ZShell32.DLL
102367ab call ZShell32.OL_n10000 ( ZpDll.ImageBase,addr_GPA,addr_LoadLibraryA)
ZpShell32.OL_n10000
查找自己的PeHeader(我很想说真的很有意义么……)
这里下个写入断点会比较省事。
参数引用,GPA->VirtualAlloc(+1cb88h),GetModuleHandleA(+1cb9ch),zpdll.data.base(+1ccc0h),
CreateProcessA(+16e48h),GlobalLock(+16e4ch)(连续地址?我们去数据窗口看看,为什么这么像什么东西呢……)
00B66E00 77DA7883 ADVAPI32.RegQueryValueExA
00B66E04 77DAEBE7 ADVAPI32.RegSetValueExA
00B66E08 77DA6BF0 ADVAPI32.RegCloseKey
00B66E0C 77DCC41B ADVAPI32.RegOpenKeyA
00B66E10 77DCD5BB ADVAPI32.RegCreateKeyA
00B66E18 77EFA02C GDI32.ExtCreateRegion
00B66E1C 77EF6F79 GDI32.BitBlt
00B66E20 77EFB067 GDI32.StretchDIBits
00B66E24 77EF6BFA GDI32.DeleteObject
00B66E28 77EFA92D GDI32.CreateDIBitmap
00B66E2C 77EF5B70 GDI32.SelectObject
00B66E30 77EF8C5E GDI32.GetObjectA
00B66E34 77EF6E5F GDI32.DeleteDC
00B66E38 77EF9A91 GDI32.CreateDIBSection
00B66E3C 77EF9C1D GDI32.CombineRgn
00B66E40 77EF5FE0 GDI32.CreateCompatibleDC
00B66E48 7C802367 kernel32.CreateProcessA
00B66E4C 7C80FF19 kernel32.GlobalLock
00B66E50 7C80A7D4 kernel32.GetLocalTime
00B66E54 7C809AE4 kernel32.VirtualFree
00B66E58 7C80FE82 kernel32.GlobalUnlock
00B66E5C 7C80FD2D kernel32.GlobalAlloc
00B66E60 7C809A51 kernel32.VirtualAlloc
00B66E64 7C8123B9 kernel32.GlobalReAlloc
00B66E68 7C8310F2 kernel32.GlobalMemoryStatus
00B66E6C 7C821363 kernel32.GetWindowsDirectoryA
00B66E70 7C821BA5 kernel32.GetVolumeInformationA
00B66E74 7C810B1C kernel32.SystemTimeToFileTime
00B66E78 7C80ADA0 kernel32.GetProcAddress
00B66E7C 7C831DB9 kernel32.GetSystemDirectoryW
00B66E80 7C812ADE kernel32.GetVersionExA
00B66E84 7C80A0D4 kernel32.WideCharToMultiByte
00B66E88 7C80EEE1 kernel32.FindFirstFileW
00B66E8C 7C8328F7 kernel32.ResumeThread
00B66E90 7C810B8E kernel32.SetFilePointer
00B66E94 7C80B905 kernel32.MapViewOfFile
00B66E98 7C80EDD7 kernel32.FindClose
00B66E9C 7C80B974 kernel32.UnmapViewOfFile
00B66EA0 7C801D77 kernel32.LoadLibraryA
00B66EA4 7C80945C kernel32.CreateFileMappingA
00B66EA8 7C80180E kernel32.ReadFile
00B66EAC 7C814EEA kernel32.GetSystemDirectoryA
00B66EB0 7C80B4CF kernel32.GetModuleFileNameA
00B66EB4 7C80C058 kernel32.ExitThread
00B66EB8 7C80B6A1 kernel32.GetModuleHandleA
00B66EBC 7C81042C kernel32.CreateRemoteThread
00B66EC0 7C8137D9 kernel32.FindFirstFileA
00B66EC4 7C801A24 kernel32.CreateFileA
00B66EC8 7C80929C kernel32.GetTickCount
00B66ECC 7C810A77 kernel32.GetFileSize
00B66ED0 7C80DDF5 kernel32.GetCurrentProcess
00B66ED4 7C812641 kernel32.FlushFileBuffers
00B66ED8 7C835484 kernel32.WriteConsoleW
00B66EDC 7C81B18F kernel32.GetConsoleOutputCP
00B66EE0 7C81CF25 kernel32.WriteConsoleA
00B66EE4 7C81DC03 kernel32.SetStdHandle
00B66EE8 7C80CCA8 kernel32.LCMapStringW
00B66EEC 7C838DE8 kernel32.LCMapStringA
00B66EF0 7C80A490 kernel32.GetStringTypeW
00B66EF4 7C838A0C kernel32.GetStringTypeA
00B66EF8 7C80D262 kernel32.GetLocaleInfoA
00B66EFC 7C809BF8 kernel32.MultiByteToWideChar
00B66F00 7C81AF14 kernel32.GetConsoleMode
00B66F04 7C8740E3 kernel32.GetConsoleCP
00B66F08 7C8110CB kernel32.IsValidCodePage
00B66F0C 7C8127A7 kernel32.GetOEMCP
00B66F10 7C809915 kernel32.GetACP
00B66F14 7C812E76 kernel32.GetCPInfo
00B66F18 7C810637 kernel32.CreateThread
00B66F1C 7C863F58 kernel32.Process32Next
00B66F20 7C83970D kernel32.GetThreadContext
00B66F24 7C812F1D kernel32.GetCommandLineA
00B66F28 7C82FC00 kernel32.OpenThread
00B66F2C 7C809920 kernel32.GetCurrentProcessId
00B66F30 7C81CDDA kernel32.ExitProcess
00B66F34 7C809B47 kernel32.CloseHandle
00B66F38 7C8021CC kernel32.ReadProcessMemory
00B66F3C 7C863DE5 kernel32.Process32First
00B66F40 7C802442 kernel32.Sleep
00B66F44 7C85A480 kernel32.WaitForDebugEvent
00B66F48 7C864B0F kernel32.CreateToolhelp32Snapshot
00B66F4C 7C834FFE kernel32.GetCurrentDirectoryA
00B66F50 7C8309E1 kernel32.OpenProcess
00B66F54 7C862A69 kernel32.SetThreadContext
00B66F58 7C813093 kernel32.IsDebuggerPresent
00B66F5C 7C85A565 kernel32.ContinueDebugEvent
00B66F60 7C801AD0 kernel32.VirtualProtect
00B66F64 7C9305D4 ntdll.RtlAllocateHeap
00B66F68 7C801E16 kernel32.TerminateProcess
00B66F6C 7C862E2A kernel32.UnhandledExceptionFilter
00B66F70 7C84467D kernel32.SetUnhandledExceptionFilter
00B66F74 7C930331 ntdll.RtlGetLastWin32Error
00B66F78 7C93043D ntdll.RtlFreeHeap
00B66F7C 7C809728 kernel32.GetCurrentThreadId
00B66F80 7C80ABC1 kernel32.GetProcessHeap
00B66F84 7C812A09 kernel32.RaiseException
00B66F88 7C957A40 ntdll.RtlUnwind
00B66F8C 7C93188A ntdll.RtlDeleteCriticalSection
00B66F90 7C9210ED ntdll.RtlLeaveCriticalSection
00B66F94 7C921005 ntdll.RtlEnterCriticalSection
00B66F98 7C9379FD ntdll.RtlReAllocateHeap
00B66F9C 7C810EF8 kernel32.HeapDestroy
00B66FA0 7C812BB6 kernel32.HeapCreate
00B66FA4 7C810D87 kernel32.WriteFile
00B66FA8 7C812F39 kernel32.GetStdHandle
00B66FAC 7C809740 kernel32.TlsGetValue
00B66FB0 7C812D9F kernel32.TlsAlloc
00B66FB4 7C809BC5 kernel32.TlsSetValue
00B66FB8 7C8136D7 kernel32.TlsFree
00B66FBC 7C809766 kernel32.InterlockedIncrement
00B66FC0 7C930340 ntdll.RtlSetLastWin32Error
00B66FC4 7C80977A kernel32.InterlockedDecrement
00B66FC8 7C9309ED ntdll.RtlSizeHeap
00B66FCC 7C80CC97 kernel32.SetHandleCount
00B66FD0 7C810E51 kernel32.GetFileType
00B66FD4 7C801EEE kernel32.GetStartupInfoA
00B66FD8 7C81DF77 kernel32.FreeEnvironmentStringsA
00B66FDC 7C81CF5B kernel32.GetEnvironmentStringsA
00B66FE0 7C814AE7 kernel32.FreeEnvironmentStringsW
00B66FE4 7C812F08 kernel32.GetEnvironmentStringsW
00B66FE8 7C80A427 kernel32.QueryPerformanceCounter
00B66FEC 7C8017E5 kernel32.GetSystemTimeAsFileTime
00B66FF0 7C809EF1 kernel32.InitializeCriticalSection
00B66FF4 7C80B9D1 kernel32.VirtualQuery
00B66FFC 7D610EE0 SHELL32.ShellExecuteA <-LastOne
00B67004 77D18F9C USER32.GetSystemMetrics
00B67008 77D1B61D USER32.EndPaint
00B6700C 77D2F52B USER32.SetWindowTextA
00B67010 77D1DAEA USER32.DestroyWindow
00B67014 77D1D7F9 USER32.UpdateWindow
00B67018 77D2E002 USER32.GetMessageA
00B6701C 77D1FF33 USER32.CreateWindowExA
00B67020 77D56B50 USER32.DialogBoxIndirectParamA
00B67024 77D1B609 USER32.BeginPaint
00B67028 77D1FFB2 USER32.SetWindowRgn
00B6702C 77D1EF69 USER32.LoadCursorA
00B67030 77D23DCE USER32.GetDlgItem
00B67034 77D22DA0 USER32.RegisterClassExA
00B67038 77D186C7 USER32.GetDC
00B6703C 77D259C9 USER32.EndDialog
00B67040 77D18BF6 USER32.TranslateMessage
00B67044 77D1D4EE USER32.DefWindowProcA
00B67048 77D2E1D1 USER32.PostQuitMessage
00B6704C 77D18C42 USER32.KillTimer
00B67050 77D3212B USER32.GetWindowTextA
00B67054 77D1D8A4 USER32.ShowWindow
00B67058 77D1B5C6 USER32.SetRect
00B6705C 77D196B8 USER32.DispatchMessageA
00B67060 77D5058A USER32.MessageBoxA
00B67064 77D18C2E USER32.SetTimer
一个外壳他想用CreateProcess和ShellExecute做什么……
地球好危险,我还是找个机会回火星好了……
我们先把这一串备份下来,然后我们继续
+2f156h VirtualAlloc(0,270bh,RWE)->0b80000
Reload("ntdll.dll")->0b91000
Reload("Kernel32.dll")
Reload("User32.dll")
Reload("GDI32.dll")
Reload("Advapi32.dll")
Reload("Shell32.dll")
覆盖获取的API~(为什么我没觉得少了些什么呢……)
CC+CV,世界很好很强大,我们刚刚虐待了CPU+内存……
+28cb1h CreateThread(ZShell32.OL_n10044,CREATE_SUSPENDED)
+24022h IsDebuggerPresent
CreateToolhelp32Snapshot(TH32CS_SNAPROCESS,MyProcessID)查找自己的父进程
+21888h OpenProcess(VM_READ,FALSE,ParentPID)
+2c529h ReadProcessMemory(hProcess,0x410044h,0x20h)
引用+1931ch B9 83 19 4B 00 EB 05 B9 8A 19 4B 00 51 A1 14 D6 4C 00 03 05 48 D4 4C 00 05 04 01 00 00 50 E8 C5
挖靠,特征码比较……杀软?还特意针对OD的……等等!我们XX一下,休息休息……
然后置Eax=1之后邪恶的0xCC,顺手还清了DrX寄存器……+14f70我们继续……
CreateFile(ZpDll),全地址映射。对自己做了点Xor,猜测是解密了某块代码……
然后修改了下ZpDll头部中对第一个区段的属性(And 0x7fffffff),修改CheckSum……
然后XXOO了ZpDll。并试图LoadLibrary("ZPreotectSDK.dll"),不过我没这个文件怎么办……
然后填充REAL_ZpDll的IAT,获取的地址在+22403(Relocate)之后写入分配的Heap(pHeap=0B20000h)中。
中间有一个AntiHook:严格检查API地址是否在第一个区段的范围内
获取方法:使用压入的Key,然后XXOO之后查表[+1d2a8]。一共177项(好像,没仔细看)
然后结束了漫长的Dll初始化,到达了Exe的OEP,然后EXE的WinMain也只做了一件时间,Jmp ZpDll.StartPeCancer
然后观察我们发现了一点东西,然后我休息休息,召唤人肉反编译器和Vm超人们……
push Key
Jmp ZShell32.OL_n10035(VM)
ascii "PeCancer.SDK.VMCodeBegin"
ascii "PeCancer.SDK.VMCodeEnd"
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!