目錄
_TEB
_PEB
_PEB_LDR_DATA
代碼實作DLL隱藏
Windows裝載器在進行PE裝載時,將與行程相關的DLL加載到對應虛擬地址空間.加載的所有DLL(模塊)有一部分資訊被存盤在PEB中.
_TEB
當執行緒運行在R3時,FS:[0]指向TEB(Thread Environment Block)執行緒環境塊.(段暫存器介紹).
_TEB結構如下:
struct _TEB
{
struct _NT_TIB NtTib; //0x0
VOID* EnvironmentPointer; //0x1c
struct _CLIENT_ID ClientId; //0x20
VOID* ActiveRpcHandle; //0x28
VOID* ThreadLocalStoragePointer; //0x2c
struct _PEB* ProcessEnvironmentBlock; //0x30
ULONG LastErrorValue; //0x34
ULONG CountOfOwnedCriticalSections; //0x38
VOID* CsrClientThread; //0x3c
VOID* Win32ThreadInfo; //0x40
ULONG User32Reserved[26]; //0x44
ULONG UserReserved[5]; //0xac
VOID* WOW32Reserved; //0xc0
ULONG CurrentLocale; //0xc4
ULONG FpSoftwareStatusRegister; //0xc8
VOID* SystemReserved1[54]; //0xcc
LONG ExceptionCode; //0x1a4
struct _ACTIVATION_CONTEXT_STACK* ActivationContextStackPointer; //0x1a8
UCHAR SpareBytes[36]; //0x1ac
ULONG TxFsContext; //0x1d0
struct _GDI_TEB_BATCH GdiTebBatch; //0x1d4
struct _CLIENT_ID RealClientId; //0x6b4
VOID* GdiCachedProcessHandle; //0x6bc
ULONG GdiClientPID; //0x6c0
ULONG GdiClientTID; //0x6c4
VOID* GdiThreadLocalInfo; //0x6c8
ULONG Win32ClientInfo[62]; //0x6cc
VOID* glDispatchTable[233]; //0x7c4
ULONG glReserved1[29]; //0xb68
VOID* glReserved2; //0xbdc
VOID* glSectionInfo; //0xbe0
VOID* glSection; //0xbe4
VOID* glTable; //0xbe8
VOID* glCurrentRC; //0xbec
VOID* glContext; //0xbf0
ULONG LastStatusValue; //0xbf4
struct _UNICODE_STRING StaticUnicodeString; //0xbf8
WCHAR StaticUnicodeBuffer[261]; //0xc00
VOID* DeallocationStack; //0xe0c
VOID* TlsSlots[64]; //0xe10
struct _LIST_ENTRY TlsLinks; //0xf10
VOID* Vdm; //0xf18
VOID* ReservedForNtRpc; //0xf1c
VOID* DbgSsReserved[2]; //0xf20
ULONG HardErrorMode; //0xf28
VOID* Instrumentation[9]; //0xf2c
struct _GUID ActivityId; //0xf50
VOID* SubProcessTag; //0xf60
VOID* EtwLocalData; //0xf64
VOID* EtwTraceData; //0xf68
VOID* WinSockData; //0xf6c
ULONG GdiBatchCount; //0xf70
union
{
struct _PROCESSOR_NUMBER CurrentIdealProcessor; //0xf74
ULONG IdealProcessorValue; //0xf74
struct
{
UCHAR ReservedPad0; //0xf74
UCHAR ReservedPad1; //0xf75
UCHAR ReservedPad2; //0xf76
UCHAR IdealProcessor; //0xf77
};
};
ULONG GuaranteedStackBytes; //0xf78
VOID* ReservedForPerf; //0xf7c
VOID* ReservedForOle; //0xf80
ULONG WaitingOnLoaderLock; //0xf84
VOID* SavedPriorityState; //0xf88
ULONG SoftPatchPtr1; //0xf8c
VOID* ThreadPoolData; //0xf90
VOID** TlsExpansionSlots; //0xf94
ULONG MuiGeneration; //0xf98
ULONG IsImpersonating; //0xf9c
VOID* NlsCache; //0xfa0
VOID* pShimData; //0xfa4
ULONG HeapVirtualAffinity; //0xfa8
VOID* CurrentTransactionHandle; //0xfac
struct _TEB_ACTIVE_FRAME* ActiveFrame; //0xfb0
VOID* FlsData; //0xfb4
VOID* PreferredLanguages; //0xfb8
VOID* UserPrefLanguages; //0xfbc
VOID* MergedPrefLanguages; //0xfc0
ULONG MuiImpersonation; //0xfc4
union
{
volatile USHORT CrossTebFlags; //0xfc8
USHORT SpareCrossTebBits:16; //0xfc8
};
union
{
USHORT SameTebFlags; //0xfca
struct
{
USHORT SafeThunkCall:1; //0xfca
USHORT InDebugPrint:1; //0xfca
USHORT HasFiberData:1; //0xfca
USHORT SkipThreadAttach:1; //0xfca
USHORT WerInShipAssertCode:1; //0xfca
USHORT RanProcessInit:1; //0xfca
USHORT ClonedThread:1; //0xfca
USHORT SuppressDebugMsg:1; //0xfca
USHORT DisableUserStackWalk:1; //0xfca
USHORT RtlExceptionAttached:1; //0xfca
USHORT InitialThread:1; //0xfca
USHORT SpareSameTebBits:5; //0xfca
};
};
VOID* TxnScopeEnterCallback; //0xfcc
VOID* TxnScopeExitCallback; //0xfd0
VOID* TxnScopeContext; //0xfd4
ULONG LockCount; //0xfd8
ULONG SpareUlong0; //0xfdc
VOID* ResourceRetValue; //0xfe0
};
成員 struct _PEB* ProcessEnvironmentBlock指向了行程相關資訊.
_PEB
PEB存盤了行程運行時相關資訊.結構定義如下:
struct _PEB
{
UCHAR InheritedAddressSpace; //0x0
UCHAR ReadImageFileExecOptions; //0x1
UCHAR BeingDebugged; //0x2
union
{
UCHAR BitField; //0x3
struct
{
UCHAR ImageUsesLargePages:1; //0x3
UCHAR IsProtectedProcess:1; //0x3
UCHAR IsLegacyProcess:1; //0x3
UCHAR IsImageDynamicallyRelocated:1; //0x3
UCHAR SkipPatchingUser32Forwarders:1; //0x3
UCHAR SpareBits:3; //0x3
};
};
VOID* Mutant; //0x4
VOID* ImageBaseAddress; //0x8
struct _PEB_LDR_DATA* Ldr; //0xc
struct _RTL_USER_PROCESS_PARAMETERS* ProcessParameters; //0x10
VOID* SubSystemData; //0x14
VOID* ProcessHeap; //0x18
struct _RTL_CRITICAL_SECTION* FastPebLock; //0x1c
VOID* AtlThunkSListPtr; //0x20
VOID* IFEOKey; //0x24
union
{
ULONG CrossProcessFlags; //0x28
struct
{
ULONG ProcessInJob:1; //0x28
ULONG ProcessInitializing:1; //0x28
ULONG ProcessUsingVEH:1; //0x28
ULONG ProcessUsingVCH:1; //0x28
ULONG ProcessUsingFTH:1; //0x28
ULONG ReservedBits0:27; //0x28
};
};
union
{
VOID* KernelCallbackTable; //0x2c
VOID* UserSharedInfoPtr; //0x2c
};
ULONG SystemReserved[1]; //0x30
ULONG AtlThunkSListPtr32; //0x34
VOID* ApiSetMap; //0x38
ULONG TlsExpansionCounter; //0x3c
VOID* TlsBitmap; //0x40
ULONG TlsBitmapBits[2]; //0x44
VOID* ReadOnlySharedMemoryBase; //0x4c
VOID* HotpatchInformation; //0x50
VOID** ReadOnlyStaticServerData; //0x54
VOID* AnsiCodePageData; //0x58
VOID* OemCodePageData; //0x5c
VOID* UnicodeCaseTableData; //0x60
ULONG NumberOfProcessors; //0x64
ULONG NtGlobalFlag; //0x68
union _LARGE_INTEGER CriticalSectionTimeout; //0x70
ULONG HeapSegmentReserve; //0x78
ULONG HeapSegmentCommit; //0x7c
ULONG HeapDeCommitTotalFreeThreshold; //0x80
ULONG HeapDeCommitFreeBlockThreshold; //0x84
ULONG NumberOfHeaps; //0x88
ULONG MaximumNumberOfHeaps; //0x8c
VOID** ProcessHeaps; //0x90
VOID* GdiSharedHandleTable; //0x94
VOID* ProcessStarterHelper; //0x98
ULONG GdiDCAttributeList; //0x9c
struct _RTL_CRITICAL_SECTION* LoaderLock; //0xa0
ULONG OSMajorVersion; //0xa4
ULONG OSMinorVersion; //0xa8
USHORT OSBuildNumber; //0xac
USHORT OSCSDVersion; //0xae
ULONG OSPlatformId; //0xb0
ULONG ImageSubsystem; //0xb4
ULONG ImageSubsystemMajorVersion; //0xb8
ULONG ImageSubsystemMinorVersion; //0xbc
ULONG ActiveProcessAffinityMask; //0xc0
ULONG GdiHandleBuffer[34]; //0xc4
VOID (*PostProcessInitRoutine)(); //0x14c
VOID* TlsExpansionBitmap; //0x150
ULONG TlsExpansionBitmapBits[32]; //0x154
ULONG SessionId; //0x1d4
union _ULARGE_INTEGER AppCompatFlags; //0x1d8
union _ULARGE_INTEGER AppCompatFlagsUser; //0x1e0
VOID* pShimData; //0x1e8
VOID* AppCompatInfo; //0x1ec
struct _UNICODE_STRING CSDVersion; //0x1f0
struct _ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x1f8
struct _ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x1fc
struct _ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x200
struct _ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x204
ULONG MinimumStackCommit; //0x208
struct _FLS_CALLBACK_INFO* FlsCallback; //0x20c
struct _LIST_ENTRY FlsListHead; //0x210
VOID* FlsBitmap; //0x218
ULONG FlsBitmapBits[4]; //0x21c
ULONG FlsHighIndex; //0x22c
VOID* WerRegistrationData; //0x230
VOID* WerShipAssertPtr; //0x234
VOID* pContextData; //0x238
VOID* pImageHeaderHash; //0x23c
union
{
ULONG TracingFlags; //0x240
struct
{
ULONG HeapTracingEnabled:1; //0x240
ULONG CritSecTracingEnabled:1; //0x240
ULONG SpareTracingBits:30; //0x240
};
};
};
成員struct _PEB_LDR_DATA* Ldr中三個鏈表都指向了LDR_DATA_TABLE_ENTRY(模塊基本資訊存盤在此)
_PEB_LDR_DATA
typedef struct _PEB_LDR_DATA
{
ULONG Length; //0x0
UCHAR Initialized; //0x4
VOID* SsHandle; //0x8
struct _LIST_ENTRY InLoadOrderModuleList; //0xc
struct _LIST_ENTRY InMemoryOrderModuleList; //0x14
struct _LIST_ENTRY InInitializationOrderModuleList; //0x1c
VOID* EntryInProgress; //0x24
UCHAR ShutdownInProgress; //0x28
VOID* ShutdownThreadId; //0x2c
}PEB_LDR_DATA, *PPEB_LDR_DATA;
//截取了一部分成員結構
typedef struct _LDR_DATA_TABLE_ENTRY
{
struct _LIST_ENTRY InLoadOrderLinks; //0x0
struct _LIST_ENTRY InMemoryOrderLinks; //0x8
struct _LIST_ENTRY InInitializationOrderLinks; //0x10
VOID* DllBase; //0x18
VOID* EntryPoint; //0x1c
ULONG SizeOfImage; //0x20
struct _UNICODE_STRING FullDllName; //0x24
struct _UNICODE_STRING BaseDllName; //0x2c
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
關系對應如下圖:

代碼實作DLL隱藏
方便上傳所有代碼都在一個檔案中......
#include <stdio.h>
#include <Windows.h>
#include <TlHelp32.h>
DWORD g_Flag = 1;
DWORD WINAPI PrinfProcecssModuleInfo(LPVOID lp);
DWORD HideModule(PWCHAR szModuleName);
typedef struct _UNICODE_STRING
{
USHORT Length; //0x0
USHORT MaximumLength; //0x2
WCHAR* Buffer; //0x4
}UNICODE_STRING, * PUNICODE_STRING;
typedef struct _PEB_LDR_DATA
{
ULONG Length; //0x0
UCHAR Initialized; //0x4
VOID* SsHandle; //0x8
struct _LIST_ENTRY InLoadOrderModuleList; //0xc
struct _LIST_ENTRY InMemoryOrderModuleList; //0x14
struct _LIST_ENTRY InInitializationOrderModuleList; //0x1c
VOID* EntryInProgress; //0x24
UCHAR ShutdownInProgress; //0x28
VOID* ShutdownThreadId; //0x2c
}PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _LDR_DATA_TABLE_ENTRY
{
struct _LIST_ENTRY InLoadOrderLinks; //0x0
struct _LIST_ENTRY InMemoryOrderLinks; //0x8
struct _LIST_ENTRY InInitializationOrderLinks; //0x10
VOID* DllBase; //0x18
VOID* EntryPoint; //0x1c
ULONG SizeOfImage; //0x20
struct _UNICODE_STRING FullDllName; //0x24
struct _UNICODE_STRING BaseDllName; //0x2c
}LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
int main()
{
//輸出當前行程所有模塊資訊
HANDLE hThread = CreateThread(NULL, 0, PrinfProcecssModuleInfo, NULL, 0, NULL);
if (!hThread)
{
return 0;
}
system("pause");
//加載模塊
HMODULE hModule = LoadLibraryA("C:\\TestDLL.dll");
if (!hModule)
{
return 0;
}
system("pause");
//模塊斷鏈
HideModule(L"TestDLL.dll");
system("pause");
//結束執行緒
g_Flag = 0;
WaitForSingleObject(hThread, -1);
CloseHandle(hThread);
system("pause");
return 0;
}
DWORD WINAPI PrinfProcecssModuleInfo(LPVOID lp)
{
while (g_Flag)
{
//創建行程快照
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if (hSnap == INVALID_HANDLE_VALUE)
{
continue;
}
//初始化模塊結構
MODULEENTRY32 md32 = { 0 };
md32.dwSize = sizeof(MODULEENTRY32);
//遍歷模塊資訊
BOOL bRet = Module32First(hSnap, &md32);
while (bRet)
{
printf("Module[%ws] Base[0x%08x] Size[0x%08x] \r\n", md32.szModule, md32.modBaseAddr, md32.modBaseSize);
bRet = Module32Next(hSnap, &md32);
}
//關閉句柄
if (hSnap)
{
CloseHandle(hSnap);
}
Sleep(500);
system("cls");
}
}
DWORD HideModule(PWCHAR szModuleName)
{
PPEB_LDR_DATA pLdr = NULL;
//獲取當前行程加載模塊鏈表
__asm
{
//_TEB -> _PEB* ProcessEnvironmentBlock;//0x30
MOV EAX, FS: [0x30]
//_PEB -> _PEB_LDR_DATA* Ldr;//0xc
MOV EAX, [EAX + 0xC]
MOV pLdr, EAX
}
//PEB_LDR_DATA -> InLoadOrderModuleList 對應 LDR_DATA_TABLE_ENTRY -> InLoadOrderLinks 第一個成員因此不需要修正偏移
PLDR_DATA_TABLE_ENTRY pData = (PLDR_DATA_TABLE_ENTRY)&pLdr->InLoadOrderModuleList;
//遍歷結束標記
PLDR_DATA_TABLE_ENTRY pFlg = pData;
//遍歷模塊
do
{
//比對模塊名
if (pData->BaseDllName.Buffer && wcscmp(szModuleName, pData->BaseDllName.Buffer) == 0)
{
//斷鏈
pData->InLoadOrderLinks.Flink->Blink = pData->InLoadOrderLinks.Blink;
pData->InLoadOrderLinks.Blink->Flink = pData->InLoadOrderLinks.Flink;
pData->InLoadOrderLinks.Blink = pData->InLoadOrderLinks.Flink = pData;
pData->InMemoryOrderLinks.Flink->Blink = pData->InMemoryOrderLinks.Blink;
pData->InMemoryOrderLinks.Blink->Flink = pData->InMemoryOrderLinks.Flink;
pData->InMemoryOrderLinks.Blink = pData->InMemoryOrderLinks.Flink = &pData->InMemoryOrderLinks;
pData->InInitializationOrderLinks.Flink->Blink = pData->InInitializationOrderLinks.Blink;
pData->InInitializationOrderLinks.Blink->Flink = pData->InInitializationOrderLinks.Flink;
pData->InInitializationOrderLinks.Blink = pData->InInitializationOrderLinks.Flink = &pData->InInitializationOrderLinks;
//修改記憶體屬性
DWORD dwOldProct = 0;
VirtualProtect(pData->DllBase, 0x1000, PAGE_READWRITE, &dwOldProct);
//抹除PE指紋
memset(pData->DllBase, 0, 0x1000);
//恢復記憶體屬性
VirtualProtect(pData->DllBase, 0x1000, dwOldProct, NULL);
break;
}
pData = pData->InLoadOrderLinks.Blink;
} while (pLdr != pFlg);
}
編譯后運行測驗
加載模塊前


加載模塊后


模塊斷鏈


此類隱藏只能避開部分API,行程對應內核結構體EPROCESS中VAD記錄了所有記憶體使用情況.應付一些簡單R3檢測還是有點用的......

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/348271.html
標籤:其他
上一篇:sqli-labs闖關指南--01-10關(非常詳細)
下一篇:網路空間安全導論第六章
