擦除模塊痕跡

對於擦除模塊痕跡,我實驗了兩種方法,下面一一闡述:

1.修改PEB結構,用代碼說話

typedef struct _PEB_LDR_DATA
 
{
  ULONG               Length;
  BOOLEAN             Initialized;
  BYTE    reserved[
3];
  PVOID               SsHandle;
  LIST_ENTRY          InLoadOrderModuleList;
  LIST_ENTRY          InMemoryOrderModuleList;
  LIST_ENTRY          InInitializationOrderModuleList;
 }
 PEB_LDR_DATA, *PPEB_LDR_DATA;

 typedef 
struct _UNICODE_STRING
 
{
  USHORT Length;
  USHORT MaximumLength;
  PWSTR Buffer;
 }
 UNICODE_STRING, *PUNICODE_STRING;

 typedef 
struct _LDR_MODULE {
  LIST_ENTRY InLoadOrderModuleList;
  LIST_ENTRY InMemoryOrderModuleList;
  LIST_ENTRY InInitializationOrderModuleList;
  PVOID BaseAddress;
  PVOID EntryPoint;
  ULONG SizeOfImage;
  UNICODE_STRING FullDllName;
  UNICODE_STRING BaseDllName;
  ULONG Flags;
  SHORT LoadCount;
  SHORT TlsIndex;
  LIST_ENTRY HashTableEntry;
  ULONG TimeDateStamp;
 }
 LDR_MODULE, *PLDR_MODULE;


 typedef 
struct RTL_DRIVE_LETTER_CURDIR
 
{
  USHORT              Flags;
  USHORT              Length;
  ULONG               TimeStamp;
  UNICODE_STRING      DosPath;
 }
 RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;

 typedef 
struct _RTL_USER_PROCESS_PARAMETERS
 
{
  ULONG               AllocationSize;
  ULONG               Size;
  ULONG               Flags;
  ULONG               DebugFlags;
  HANDLE              hConsole;
  ULONG               ProcessGroup;
  HANDLE              hStdInput;
  HANDLE              hStdOutput;
  HANDLE              hStdError;
  UNICODE_STRING      CurrentDirectoryName;
  HANDLE              CurrentDirectoryHandle;
  UNICODE_STRING      DllPath;
  UNICODE_STRING      ImagePathName;
  UNICODE_STRING      CommandLine;
  PWSTR               Environment;
  ULONG               dwX;
  ULONG               dwY;
  ULONG               dwXSize;
  ULONG               dwYSize;
  ULONG               dwXCountChars;
  ULONG               dwYCountChars;
  ULONG               dwFillAttribute;
  ULONG               dwFlags;
  ULONG               wShowWindow;
  UNICODE_STRING      WindowTitle;
  UNICODE_STRING      Desktop;
  UNICODE_STRING      ShellInfo;
  UNICODE_STRING      RuntimeInfo;
  RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[
0x20];
 }
 RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

 typedef VOID (_stdcall 
*PPEBLOCKROUTINE)(PVOID);

 typedef 
struct _PEB_FREE_BLOCK
 
{
  
struct _PEB_FREE_BLOCK* Next;
  ULONG Size;
 }
 PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;

 
struct _NT_PEB 
 
{
  BOOLEAN InheritedAddressSpace;
  BOOLEAN ReadImageFileExecOptions;
  BOOLEAN BeingDebugged;
  BOOLEAN Spare;
  HANDLE Mutant;
  PVOID ImageBaseAddress;
  PPEB_LDR_DATA LoaderData;
  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
  PVOID SubSystemData;
  PVOID ProcessHeap;
  PVOID FastPebLock;
  PPEBLOCKROUTINE FastPebLockRoutine;
  PPEBLOCKROUTINE FastPebUnlockRoutine;
  ULONG EnvironmentUpdateCount;
  PVOID 
*KernelCallbackTable;
  PVOID EventLogSection;
  PVOID EventLog;
  PPEB_FREE_BLOCK FreeList;
  ULONG TlsExpansionCounter;
  PVOID TlsBitmap;
  ULONG TlsBitmapBits[
0x2];
  PVOID ReadOnlySharedMemoryBase;
  PVOID ReadOnlySharedMemoryHeap;
  PVOID 
*ReadOnlyStaticServerData;
  PVOID AnsiCodePageData;
  PVOID OemCodePageData;
  PVOID UnicodeCaseTableData;
  ULONG NumberOfProcessors;
  ULONG NtGlobalFlag;
  BYTE Spare2[
0x4];
  LARGE_INTEGER CriticalSectionTimeout;
  ULONG HeapSegmentReserve;
  ULONG HeapSegmentCommit;
  ULONG HeapDeCommitTotalFreeThreshold;
  ULONG HeapDeCommitFreeBlockThreshold;
  ULONG NumberOfHeaps;
  ULONG MaximumNumberOfHeaps;
  PVOID 
**ProcessHeaps;
  PVOID GdiSharedHandleTable;
  PVOID ProcessStarterHelper;
  PVOID GdiDCAttributeList;
  PVOID LoaderLock;
  ULONG OSMajorVersion;
  ULONG OSMinorVersion;
  ULONG OSBuildNumber;
  ULONG OSPlatformId;
  ULONG ImageSubSystem;
  ULONG ImageSubSystemMajorVersion;
  ULONG ImageSubSystemMinorVersion;
  ULONG GdiHandleBuffer[
0x22];
  ULONG PostProcessInitRoutine;
  ULONG TlsExpansionBitmap;
  BYTE TlsExpansionBitmapBits[
0x80];
  ULONG SessionId;
 }
;

 typedef 
struct _CLIENT_ID
 
{
  HANDLE UniqueProcess;
  HANDLE UniqueThread;
 }
 CLIENT_ID, *PCLIENT_ID;

 typedef 
struct _GDI_TEB_BATCH
 
{
  ULONG Offset;
  ULONG HDC;
  ULONG Buffer[
0x136];
 }
 GDI_TEB_BATCH, *PGDI_TEB_BATCH;

 
struct _NT_TEB
 
{
  NT_TIB Tib;                         
/* 00h */
  PVOID EnvironmentPointer;           
/* 1Ch */
  CLIENT_ID Cid;                      
/* 20h */
  PVOID ActiveRpcInfo;                
/* 28h */
  PVOID ThreadLocalStoragePointer;    
/* 2Ch */
  _NT_PEB 
*Peb;                       /* 30h */
  ULONG LastErrorValue;               
/* 34h */
  ULONG CountOfOwnedCriticalSections; 
/* 38h */
  PVOID CsrClientThread;              
/* 3Ch */
  
void* Win32ThreadInfo;    /* 40h */
  ULONG Win32ClientInfo[
0x1F];        /* 44h */
  PVOID WOW32Reserved;                
/* C0h */
  LCID CurrentLocale;                 
/* C4h */
  ULONG FpSoftwareStatusRegister;     
/* C8h */
  PVOID SystemReserved1[
0x36];        /* CCh */
  PVOID Spare1;                       
/* 1A4h */
  LONG ExceptionCode;                 
/* 1A8h */
  UCHAR SpareBytes1[
0x28];            /* 1ACh */
  PVOID SystemReserved2[
0xA];         /* 1D4h */
  GDI_TEB_BATCH GdiTebBatch;          
/* 1FCh */
  ULONG gdiRgn;                       
/* 6DCh */
  ULONG gdiPen;                       
/* 6E0h */
  ULONG gdiBrush;                     
/* 6E4h */
  CLIENT_ID RealClientId;             
/* 6E8h */
  PVOID GdiCachedProcessHandle;       
/* 6F0h */
  ULONG GdiClientPID;                 
/* 6F4h */
  ULONG GdiClientTID;                 
/* 6F8h */
  PVOID GdiThreadLocaleInfo;          
/* 6FCh */
  PVOID UserReserved[
5];              /* 700h */
  PVOID glDispatchTable[
0x118];       /* 714h */
  ULONG glReserved1[
0x1A];            /* B74h */
  PVOID glReserved2;                  
/* BDCh */
  PVOID glSectionInfo;                
/* BE0h */
  PVOID glSection;                    
/* BE4h */
  PVOID glTable;                      
/* BE8h */
  PVOID glCurrentRC;                  
/* BECh */
  PVOID glContext;                    
/* BF0h */
  LONG LastStatusValue;    
/* BF4h */
  UNICODE_STRING StaticUnicodeString; 
/* BF8h */
  WCHAR StaticUnicodeBuffer[
0x105];   /* C00h */
  PVOID DeallocationStack;            
/* E0Ch */
  PVOID TlsSlots[
0x40];               /* E10h */
  LIST_ENTRY TlsLinks;                
/* F10h */
  PVOID Vdm;                          
/* F18h */
  PVOID ReservedForNtRpc;             
/* F1Ch */
  PVOID DbgSsReserved[
0x2];           /* F20h */
  ULONG HardErrorDisabled;            
/* F28h */
  PVOID Instrumentation[
0x10];        /* F2Ch */
  PVOID WinSockData;                  
/* F6Ch */
  ULONG GdiBatchCount;                
/* F70h */
  USHORT Spare2;                      
/* F74h */
  BOOLEAN IsFiber;                    
/* F76h */
  UCHAR Spare3;                       
/* F77h */
  ULONG Spare4;                       
/* F78h */
  ULONG Spare5;                       
/* F7Ch */
  PVOID ReservedForOle;               
/* F80h */
  ULONG WaitingOnLoaderLock;          
/* F84h */
  ULONG Unknown[
11];                  /* F88h */
  PVOID FlsSlots;                     
/* FB4h */
  PVOID WineDebugInfo;                
/* Needed for WINE DLL's  */
 }
;

 
static struct _NT_TEB* GetCurrentThreadTEB()                     //獲得TEB
 {
  
struct _NT_TEB *pTeb=NULL;

  _asm
  
{
   mov  eax,fs:[
0x18]
   mov  pTeb,eax
  }

  
return pTeb;
 }


 
void HideModule(std::string strModuleName)
 
{
  
struct _NT_TEB *pTeb = GetCurrentThreadTEB();
  
struct _NT_PEB *pPeb = pTeb->Peb;                                //由TEB獲得PEB
  PPEB_LDR_DATA pLdrData = pPeb->LoaderData;
  PLDR_MODULE pFirstLdrModule 
= (PLDR_MODULE)pLdrData->InLoadOrderModuleList.Flink; 
  PLDR_MODULE pLdrModule 
= pFirstLdrModule;
  PLDR_MODULE pLastModule,pNextModule;

  
//名字通通轉爲WideChar,因此Windows內部是Unicode的
  WCHAR pWStrModuleName[MAX_PATH] = {WCHAR(0)};
  MultiByteToWideChar(CP_ACP,
0,strModuleName.c_str(), -1,pWStrModuleName,strModuleName.size()); 

  
//PEB裏面有當前進程的模塊列表,ToolHelp裏面的函數就是根據這個列表來遍歷的因此,修改此列表可以達到隱藏的目的
  do 
  
{
   
//判斷是否是我們要屏蔽的模塊
   if(wcscmp(pLdrModule->BaseDllName.Buffer, pWStrModuleName) == 0)
   
{
    
//更改指針,達到隱藏的目的
    pLastModule = (PLDR_MODULE)(pLdrModule->InLoadOrderModuleList.Blink);
    pNextModule 
= (PLDR_MODULE)(pLdrModule->InLoadOrderModuleList.Flink);
    pLastModule
->InLoadOrderModuleList.Flink = (PLIST_ENTRY)pNextModule;
    pNextModule
->InLoadOrderModuleList.Blink = (PLIST_ENTRY)pLastModule;

    
//因爲PEB裏面有三個列表(分別是以Load順序、地址順序、初始化順序來排序),所以通過覆蓋的方式修改另外兩個列表,達到隱藏的目的
    pLdrModule->BaseAddress = pLastModule->BaseAddress;
    pLdrModule
->BaseDllName = pLastModule->BaseDllName;
    pLdrModule
->EntryPoint = pLastModule->EntryPoint;
    pLdrModule
->Flags = pLastModule->Flags;
    pLdrModule
->FullDllName = pLastModule->FullDllName;
    pLdrModule
->HashTableEntry = pLastModule->HashTableEntry;
    pLdrModule
->LoadCount = pLastModule->LoadCount;
    pLdrModule
->SizeOfImage = pLastModule->SizeOfImage;
    pLdrModule
->TimeDateStamp = pLastModule->TimeDateStamp;
    pLdrModule
->TlsIndex = pLastModule->TlsIndex;
   }

   pLdrModule 
= (PLDR_MODULE)pLdrModule->InLoadOrderModuleList.Flink;

  }
 while(pLdrModule != pFirstLdrModule);
 }

 2.手動完成dll的加載:剛開始研究手動加載的時候覺得比較複雜,但是通過實踐之後,其實還是很簡單的,代碼比較長這裏就不詳加敘述了,我就用下面幾個步驟來分別敘述:

  • 首先要分配一個空間給dll,可以根據PE結構裏面的SizeOfImage來分配;
  • 然後把dll加載到分配的空間裏面去,需要注意的是不能單純拷貝,對於每個Section而言,需要安排到Section列表裏面指定的虛擬地址偏移裏面去(即RAV + 分配到的空間開始地址<可以稱爲模塊句柄>);
  • 然後要做的就是完成IAT的填寫(根據INT)以及重定位表的處理
  • ok,打完收工(還有些比較複雜的處理我還不太明白,比如TLS,努力學習中)

    因爲手動加載dll沒有經過系統的干涉,所以上面的PEB結構裏面也就不會有相應的模塊結構,也就達到了隱藏的目的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章