恶意软件为了反调试/反汇编、使用的一种安全技术。
参考链接:
https://kibazen.cn/win32-xia-fs-ji-cun-qi-teb-he-peb-xiang-jie/
实现思路
- 利用PEB处获取module base
- 根据pe导出表结构获取导出函数GetProcAddr地址
- 调用GetProcAddr加载其他api函数
cpp
FARPROC sp5Shellcode_NoneThread(void* param)
{
int ret = 0;
HMODULE hUser32 = 0;
HMODULE hModuleBase = 0;
ptrGetProcAddress lpGetProcAddress;
ptrLoadLibraryA lpLoadLibraryA = 0;
ptrCreateThread lpCreateThread = 0;
ptrCreateFileA lpCreateFileA = 0;
ptrCloseHandle lpCloseHandle = 0;
ptrSendMessageA lpSendMessageA = 0;
ptrSleep lpSleep = 0;
ptrMessageBoxA lpMessageBoxA = 0;
ptrVirtualAlloc lpVirtualAlloc = 0;
ptrEnumWindows lpEnumWindows = 0;
ptrIsWindowVisible lpIsWindowVisible = 0;
ptrgetpeername lpgetpeername;
ptrgetsockopt lpgetsockopt;
ptrWSAStartup lpWSAStartup;
ptrsend lpsend;
ptrntohs lpntohs;
__asm
{
mov eax, fs: [30h] //PEB
mov eax, [eax + 0ch] //_PER_LDR_DATA
mov eax, [eax + 14h]//InMemoryOrderModuleList
mov eax, [eax]
mov eax, [eax]
mov eax, [eax + 10h]
mov hModuleBase, eax
}
if (hModuleBase == 0) {
return 0;
}
PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hModuleBase;
PIMAGE_NT_HEADERS32 lpNtHeader = (PIMAGE_NT_HEADERS32)((DWORD)hModuleBase + lpDosHeader->e_lfanew);
if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size) {
return NULL;
}
if (!lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress) {
return NULL;
}
PIMAGE_EXPORT_DIRECTORY lpExports = (PIMAGE_EXPORT_DIRECTORY)((DWORD)hModuleBase +
(DWORD)lpNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
PDWORD lpdwFunName = (PDWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfNames);
PWORD lpword = (PWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfNameOrdinals);
PDWORD lpdwFunAddr = (PDWORD)((DWORD)hModuleBase + (DWORD)lpExports->AddressOfFunctions);
for (DWORD dwLoop = 0; dwLoop <= lpExports->NumberOfNames - 1; dwLoop++) {
char* pFunName = (char*)(lpdwFunName[dwLoop] + (DWORD)hModuleBase);
if (pFunName[0] == 'G' &&
pFunName[1] == 'e' &&
pFunName[2] == 't' &&
pFunName[3] == 'P' &&
pFunName[4] == 'r' &&
pFunName[5] == 'o' &&
pFunName[6] == 'c' &&
pFunName[7] == 'A' &&
pFunName[8] == 'd' &&
pFunName[9] == 'd' &&
pFunName[10] == 'r' &&
pFunName[11] == 'e' &&
pFunName[12] == 's' &&
pFunName[13] == 's')
{
lpGetProcAddress = (ptrGetProcAddress)(lpdwFunAddr[lpword[dwLoop]] + (DWORD)hModuleBase);
break;
}
}
char szSleep[] = { 'S','l','e','e','p',0 };
char szLoadLibraryA[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };
char szCreateThread[] = { 'C','r','e','a','t','e','T','h','r','e','a','d',0 };
char szCreateFileA[] = { 'C','r','e','a','t','e','F','i','l','e','A',0 };
char szCloseHandle[]{ 'C','l','o','s','e','H','a','n','d','l','e',0 };
char szMessageBoxA[]{ 'M','e','s','s','a','g','e','B','o','x','A',0 };
char szVirtualAlloc[] = { 'V','i','r','t','u','a','l','A','l','l','o','c',0 };
lpLoadLibraryA = (ptrLoadLibraryA)lpGetProcAddress(hModuleBase, szLoadLibraryA);
lpCreateThread = (ptrCreateThread)lpGetProcAddress(hModuleBase, szCreateThread);
lpCloseHandle = (ptrCloseHandle)lpGetProcAddress(hModuleBase, szCloseHandle);
lpCreateFileA = (ptrCreateFileA)lpGetProcAddress(hModuleBase, szCreateFileA);
lpSleep = (ptrSleep)lpGetProcAddress(hModuleBase, szSleep);
lpVirtualAlloc = (ptrVirtualAlloc)lpGetProcAddress(hModuleBase, szVirtualAlloc);
char szUser32[] = { 'U','s','e','r','3','2','.','d','l','l',0 };
hUser32 = lpLoadLibraryA(szUser32);
PEB TEB等数据结构
cpp
#define PEB_BASE (0x7ffdf000)
typedef struct _NT_TIB
{ // Size: 01C
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; // 000
PVOID StackBase; // 004
PVOID StackLimit; // 008
PVOID SubSystemTib; // 00C
union // 010
{
PVOID FiberData;
ULONG Version;
};
PVOID ArbitraryUserPointer; // 014
struct _NT_TIB *Self; // 018
} NT_TIB, *PNT_TIB;
typedef struct _TEB
{ // Size: FBC
NT_TIB Tib; // 000
PVOID EnvironmentPointer; // 01C
CLIENT_ID Cid; // 020
PVOID ActiveRpcHandle; // 028
PVOID ThreadLocalStoragePointer; // 02C
struct _PEB *ProcessEnvironmentBlock; // 030
ULONG LastErrorValue; // 034
ULONG CountOfOwnedCriticalSections; // 038
PVOID CsrClientThread; // 03C
struct _W32THREAD* Win32ThreadInfo; // 040
ULONG User32Reserved[0x1A]; // 044
ULONG UserReserved[5]; // 0AC
PVOID WOW32Reserved; // 0C0
LCID CurrentLocale; // 0C4
ULONG FpSoftwareStatusRegister; // 0C8
PVOID SystemReserved1[0x36]; // 0CC
LONG ExceptionCode; // 1A4
struct _ACTIVATION_CONTEXT_STACK *ActivationContextStackPointer; // 1A8
UCHAR SpareBytes1[0x28]; // 1AC
GDI_TEB_BATCH GdiTebBatch; // 1D4
CLIENT_ID RealClientId; // 6B4
PVOID GdiCachedProcessHandle; // 6BC
ULONG GdiClientPID; // 6C0
ULONG GdiClientTID; // 6C4
PVOID GdiThreadLocalInfo; // 6C8
ULONG Win32ClientInfo[62]; // 6CC
PVOID glDispatchTable[0xE9]; // 7C4
ULONG glReserved1[0x1D]; // B68
PVOID glReserved2; // BDC
PVOID glSectionInfo; // BE0
PVOID glSection; // BE4
PVOID glTable; // BE8
PVOID glCurrentRC; // BEC
PVOID glContext; // BF0
NTSTATUS LastStatusValue; // BF4
UNICODE_STRING StaticUnicodeString; // BF8
WCHAR StaticUnicodeBuffer[0x105]; // C00
PVOID DeallocationStack; // E0C
PVOID TlsSlots[0x40]; // E10
LIST_ENTRY TlsLinks; // F10
PVOID Vdm; // F18
PVOID ReservedForNtRpc; // F1C
PVOID DbgSsReserved[0x2]; // F20
ULONG HardErrorDisabled; // F28
PVOID Instrumentation[14]; // F2C
PVOID SubProcessTag; // F64
PVOID EtwTraceData; // F68
PVOID WinSockData; // F6C
ULONG GdiBatchCount; // F70
BOOLEAN InDbgPrint; // F74
BOOLEAN FreeStackOnTermination; // F75
BOOLEAN HasFiberData; // F76
UCHAR IdealProcessor; // F77
ULONG GuaranteedStackBytes; // F78
PVOID ReservedForPerf; // F7C
PVOID ReservedForOle; // F80
ULONG WaitingOnLoaderLock; // F84
ULONG SparePointer1; // F88
ULONG SoftPatchPtr1; // F8C
ULONG SoftPatchPtr2; // F90
PVOID *TlsExpansionSlots; // F94
ULONG ImpersionationLocale; // F98
ULONG IsImpersonating; // F9C
PVOID NlsCache; // FA0
PVOID pShimData; // FA4
ULONG HeapVirualAffinity; // FA8
PVOID CurrentTransactionHandle; // FAC
PTEB_ACTIVE_FRAME ActiveFrame; // FB0
PVOID FlsData; // FB4
UCHAR SafeThunkCall; // FB8
UCHAR BooleanSpare[3]; // FB9
} TEB, *PTEB;
typedef struct _LIST_ENTRY
{ // Size: 008
struct _LIST_ENTRY *Flink; // 000 从前到后
struct _LIST_ENTRY *Blink; // 004 从后到前
} LIST_ENTRY, *PLIST_ENTRY;
typedef struct _PER_LDR_DATA
{ // Size: 0024
ULONG Length; // 000
BOOLEAN Initialize; // 004
PVOID SsHandle; // 008
LIST_ENTRY InLoadOrderModuleList; // 00C
LIST_ENTRY InMemoryOrderModuleList; // 014
LIST_ENTRY InInitializationOrderModuleList; // 01C
} PER_LDR_DATA, *PPER_LDR_DATA;
typedef struct _UNICODE_STRING
{ // Size: 008
USHORT Length; // 000 占用的内存字节数,个数*2;
USHORT MaximumLength; // 002
PWSTR Buffer; // 004
} UNICODE_STRING ,*PUNICODE_STRING;
typedef struct _LDR_DATA_TABLE_ENTRY
{ // Size: 050
LIST_ENTRY InLoadOrderLinks; // 000 LIST_ENTRY里的Flink和Blink其实是指向LDR_MODULE结构,即LDR_DATA_TABLE_ENTRY
LIST_ENTRY InMemoryOrderLinks; // 008 同上
LIST_ENTRY InInitializationOrderLinks; // 010 同上
PVOID DllBase; // 018
PVOID EntryPoint; // 01C
ULONG SizeOfImage; // 020
UNICODE_STRING FullDllName; // 024
UNICODE_STRING BaseDllName; // 02C
ULONG Flags; // 034
WORD LoadCount; // 038
WORD TlsIndex; // 03A
union // 03C
{
LIST_ENTRY HashLinks; // 03C
struct
{
PVOID SectionPointer; // 03C
ULONG CheckSum; // 040
};
};
union
{
ULONG TimeDateStamp; // 044
PVOID LoadedImports; // 044
};
_ACTIVATION_CONTEXT * EntryPointActivationContext; // 048
PVOID PatchInformation; // 04C
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _PEB
{ // Size: 1D8
UCHAR InheritedAddressSpace; // 000
UCHAR ReadImageFileExecOptions; // 001
UCHAR BeingDebugged; // 002
UCHAR SpareBool; // 003 Allocation size
HANDLE Mutant; // 004
HINSTANCE ImageBaseAddress; // 008
struct _PER_LDR_DATA *Ldr; // 00C
strcut _RTL_USER_PPROCESS_PARAMETERS *ProcessParameters; // 010
ULONG SubSystemData; // 014
HANDLE DefaultHeap; // 018
KSPIN_LOCK FastPebLock; // 01C
ULONG FastPebLockRoutine; // 020
ULONG FastPebUnlockRoutine; // 024
ULONG EnvironmentUpdateCount; // 028
ULONG KernelCallbackTable; // 02C
LARGE_INTEGER SystemReserved; // 030
struct _PER_FREE_BLOCK *FreeList; // 038
ULONG TlsExpansionCounter; // 03C
ULONG TlsBitmap; // 040
LARGE_INTEGER TlsBitmapBits; // 044
ULONG ReadOnlySharedMemoryBase; // 04C
ULONG ReadOnlySharedMemoryHeap; // 050
ULONG ReadOnlyStaticServerData; // 054
ULONG AnsiCodePageData; // 058
ULONG OemCodePageData; // 05C
ULONG UnicodeCaseTableData; // 060
ULONG NumberOfProcessors; // 064
LARGE_INTEGER NtGlobalFlag; // 068 Address of a local copy
LARGE_INTEGER CriticalSectionTimeout; // 070
ULONG HeapSegmentReserve; // 078
ULONG HeapSegmentCommit; // 07C
ULONG HeapDeCommitTotalFreeThreshold; // 080
ULONG HeapDeCommitFreeBlockThreshold; // 084
ULONG NumberOfHeaps; // 088
ULONG MaximumNumberOfHeaps; // 08C
ULONG ProcessHeaps; // 090
ULONG GdiSharedHandleTable; // 094
ULONG ProcessStarterHelper; // 098
ULONG GdiDCAttributeList; // 09C
KSPIN_LOCK LoaderLock; // 0A0
ULONG OSMajorVersion; // 0A4
ULONG OSMinorVersion; // 0A8
USHORT OSBuildNumber; // 0AC
USHORT OSCSDVersion; // 0AE
ULONG OSPlatformId; // 0B0
ULONG ImageSubsystem; // 0B4
ULONG ImageSubsystemMajorVersion; // 0B8
ULONG ImageSubsystemMinorVersion; // 0BC
ULONG ImageProcessAffinityMask; // 0C0
ULONG GdiHandleBuffer[0x22]; // 0C4
ULONG PostProcessInitRoutine; // 14C
ULONG TlsExpansionBitmap; // 150
UCHAR TlsExpansionBitmapBits[0x80]; // 154
ULONG SessionId; // 1D4
} PEB, *PPEB;