分类: WINDOWS
2017-03-17 18:58:53
Win32汇编和DOS汇编有个很大的区别,即DOS汇编中通过中断实现系统功能调用,而Win32汇编中则通过动态链接库中的API函数实现。PE病毒和普通PE程序一样,需要调用这些API函数来实现一些功能。但是在正常的PE程序中,有一个导入函数节,记录了代码节中所调用的API函数在DLL链接库中的真实地址。可在病毒程序中,只有代码节,没有导入函数节,病毒程序想要调用这些API函数,必须要要确定这些API函数在内存中的位置。这要用到病毒程序常用的另一个经典技术,即kernel32.dll重定位技术。
想要定位DLL链接库中API函数在内存中的位置,首先必须定位存储它们的DLL链接库在内存中的实际位置。而对于windows程序,最常用,而且往往必须要用的一个连接库就是kernel32.dll链接库。下面我们来讲一下如何定位kernel32.dll链接库。
首先了解一下线程环境快TEB(Thread Environment Block),在windows系统中每一个线程都对应着一个TEB。TEB中几乎包含了和该线程相关的所有信息。TEB中相对地址0x30的位置存储着指向PEB结构的指针,通过该指针我们可以定位PEB结构在内存中的位置。PEB的结构如下:
Typedef struct _PEB{
……
008h HINSTANCE ImageBaseAddress; //程序加载的基地址
00Ch struct _PEB_LDR_DATA *Ldr //Ptr32 _PEB_LDR_DATA
010h struct _RTL_USER_PROCESS_PARAMETERS *ProcessParameters;
……
}PEB,*PPEB;
找到PEB结构后,在PEB中相对地址为0x0C的位置,存储着指向PEB_LDR_DATA的指针,该结构的定义如下:
typedef struct _PEB_LDR_DATA
{
000 ULONG Length;
004 BOOLEAN Initialized;
008 PVOID SsHandle;
00c LIST_ENTRY InLoadOrderModuleList;
014 LIST_ENTRY InMemoryOrderModuleList;
01c LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA,*PPEB_LDR_DATA;
我们可以看到该结构中定义了三个LIST_ENTRY结构,该结构被应用于双向链表中。LIST_ENTRY只包含两个元素,即指向后一个节点的指针和指向前一个节点的指针。这里LIST_ENTRY定义的三个元素分别指向了一个双向链表中不同的节点,最重要的是该双向链表与动态链接库加载模块息息相关,其节点即为LDR_MODULE结构,该结构定义如下:
typedef struct _LDR_MODULE
{
000 LIST_ENTRY InLoadOrderModuleList;
008 LIST_ENTRY InMemoryOrderModuleList;
010 LIST_ENTRY InInitializationOrderModuleList;
018 PVOID BaseAddress;
01C PVOID EntryPoint;
020 ULONG SizeOfImage;
024 UNICODE_STRING FullDllName;
……
} LDR_MODULE, *PLDR_MODULE;
这里我把我们要用到的三个重要的元素用红色标记出来。当我们得到双向链表中某一个节点的指针时,只要遍历这个双向链表,通过比对模块的名字,即LDR_MODULE结构中的FullDllName元素,就可以找到我们想要的动态链接库模块对应的LDR_MODULE结构,并通过BaseAddress元素获取动态链接库模块在内存中的准确位置。
000 NT_TIB Tib; //线程信息块
01C PVOID EnvironmentPointer;
020 CLIENT_ID Cid;
028 PVOID ActiveRpcInfo;
02C PVOID ThreadLocalStoragePointer;
030 PPEB Peb;
034 ULONG LastErrorValue;
038 ULONG CountOfOwnedCriticalSections;
03C PVOID CsrClientThread;
040 PVOID Win32ThreadInfo;
044 ULONG Win32ClientInfo[0x1F];
0C0 PVOID WOW32Reserved;
0C4 ULONG CurrentLocale;
0C8 ULONG FpSoftwareStatusRegister;
0CC PVOID SystemReserved1[0x36];
1A4 PVOID Spare1;
1A8 LONG ExceptionCode;
1AC ULONG SpareBytes1[0x28];
1D4 PVOID SystemReserved2[0xA];
1FC GDI_TEB_BATCH GdiTebBatch;
6DC ULONG gdiRgn;
6E0 ULONG gdiPen;
6E4 ULONG gdiBrush;
6E8 CLIENT_ID RealClientId;
6F0 PVOID GdiCachedProcessHandle;
6F4 ULONG GdiClientPID;
6F8 ULONG GdiClientTID;
6FC PVOID GdiThreadLocaleInfo;
700 PVOID UserReserved[5];
714 PVOID glDispatchTable[0x118];
B74 ULONG glReserved1[0x1A];
BDC PVOID glReserved2;
BE0 PVOID glSectionInfo;
BE4 PVOID glSection;
BE8 PVOID glTable;
BEC PVOID glCurrentRC;
BF0 PVOID glContext;
BF4 NTSTATUS LastStatusValue;
BF8 UNICODE_STRING StaticUnicodeString;
C00 WCHAR StaticUnicodeBuffer[0x105];
EOC PVOID DeallocationStack;
E10 PVOID TlsSlots[0x40];
F10 LIST_ENTRY TlsLinks;
F18 PVOID Vdm;
F1C PVOID ReservedForNtRpc;
F20 PVOID DbgSsReserved[0x2];
F28 ULONG HardErrorDisabled;
F2C PVOID Instrumentation[0x10];
F6C PVOID WinSockData;
F70 ULONG GdiBatchCount;
F74 ULONG Spare2;
F78 ULONG Spare3;
F7C ULONG Spare4;
F80 PVOID ReservedForOle;
F84 ULONG WaitingOnLoaderLock;
F88 PVOID StackCommit;
F8C PVOID StackCommitMax;
F90 PVOID StackReserve;
??? PVOID MessageQueue;
} NT_TEB, *PNT_TEB;
typedef struct _NT_TIB//sizeof 1ch
{
00h struct _EXCEPTION_REGISTRATION *ExceptionList; //SEH链入口
04h PVOID StackBase; //堆栈基址
08h PVOID StackLimit; //堆栈大小
0ch PVOID SubSystemTib;
10h union {
PVOID FiberData;
DWORD Version;
};
14h PVOID ArbitraryUserPointer;
18h struct _NT_TIB *Self; //指向TIB结构自身的线性地址
}NT_TIB;
typedef struct _PEB // Size: 0x1D8
{
000h UCHAR InheritedAddressSpace;
001h UCHAR ReadImageFileExecOptions;
002h UCHAR BeingDebugged; //Debug运行标志
003h UCHAR SpareBool;
004h HANDLE Mutant;
008h HINSTANCE ImageBaseAddress; //程序加载的基地址
00Ch struct _PEB_LDR_DATA *Ldr //Ptr32 _PEB_LDR_DATA
010h struct _RTL_USER_PROCESS_PARAMETERS *ProcessParameters;
014h ULONG SubSystemData;
018h HANDLE DefaultHeap;
01Ch KSPIN_LOCK FastPebLock;
020h ULONG FastPebLockRoutine;
024h ULONG FastPebUnlockRoutine;
028h ULONG EnvironmentUpdateCount;
02Ch ULONG KernelCallbackTable;
030h LARGE_INTEGER SystemReserved;
038h struct _PEB_FREE_BLOCK *FreeList
03Ch ULONG TlsExpansionCounter;
040h ULONG TlsBitmap;
044h LARGE_INTEGER TlsBitmapBits;
04Ch ULONG ReadOnlySharedMemoryBase;
050h ULONG ReadOnlySharedMemoryHeap;
054h ULONG ReadOnlyStaticServerData;
058h ULONG AnsiCodePageData;
05Ch ULONG OemCodePageData;
060h ULONG UnicodeCaseTableData;
064h ULONG NumberOfProcessors;
068h LARGE_INTEGER NtGlobalFlag; // Address of a local copy
070h LARGE_INTEGER CriticalSectionTimeout;
078h ULONG HeapSegmentReserve;
07Ch ULONG HeapSegmentCommit;
080h ULONG HeapDeCommitTotalFreeThreshold;
084h ULONG HeapDeCommitFreeBlockThreshold;
088h ULONG NumberOfHeaps;
08Ch ULONG MaximumNumberOfHeaps;
090h ULONG ProcessHeaps;
094h ULONG GdiSharedHandleTable;
098h ULONG ProcessStarterHelper;
09Ch ULONG GdiDCAttributeList;
0A0h KSPIN_LOCK LoaderLock;
0A4h ULONG OSMajorVersion;
0A8h ULONG OSMinorVersion;
0ACh USHORT OSBuildNumber;
0AEh USHORT OSCSDVersion;
0B0h ULONG OSPlatformId;
0B4h ULONG ImageSubsystem;
0B8h ULONG ImageSubsystemMajorVersion;
0BCh ULONG ImageSubsystemMinorVersion;
0C0h ULONG ImageProcessAffinityMask;
0C4h ULONG GdiHandleBuffer[0x22];
14Ch ULONG PostProcessInitRoutine;
150h ULONG TlsExpansionBitmap;
154h UCHAR TlsExpansionBitmapBits[0x80];
1D4h ULONG SessionId;
} PEB, *PPEB;
typedef struct _PEB_LDR_DATA
{
000 ULONG Length;
004 BOOLEAN Initialized;
008 PVOID SsHandle;
00c LIST_ENTRY InLoadOrderModuleList;
014 LIST_ENTRY InMemoryOrderModuleList;
01c LIST_ENTRY InInitializationOrderModuleList;
024} PEB_LDR_DATA,*PPEB_LDR_DATA;
typedef struct _LIST_ENTRY
{
struct _LIST_ENTRY *Flink;
struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _LDR_MODULE
{
000 LIST_ENTRY InLoadOrderModuleList;
008 LIST_ENTRY InMemoryOrderModuleList;
010 LIST_ENTRY InInitializationOrderModuleList;
018 PVOID BaseAddress;
01C PVOID EntryPoint;
020 ULONG SizeOfImage;
024 UNICODE_STRING FullDllName;
02C UNICODE_STRING BaseDllName;
034 ULONG Flags;
038 SHORT LoadCount;
03A SHORT TlsIndex;
03C HANDLE SectionHandle;
040 ULONG CheckSum;
044 ULONG TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;