天天看點

shellcode加載器

不能有全局變量 (其實也是使用了絕對位址)

不能使用常量字元串

char szBuffer[] = "ShellCode"; //會使用常量區,是以不可用

//寫成
char szBuffer[] = {'S', 'h', 'e', 'l', '\0'}; //這個使用堆棧

char szBuffer[] = {'K', '0', 'e', '0', '\0'}; //UNICODE格式,高位元組為零,占2個字元,一般函數名為UinCode格式
           

編寫shellcode不能使用絕對位址,因為當我們加載到其他函數中時絕對位址儲存的可能什麼也沒有,甚至是其他函數,是以當我們需要調用一個函數時,需要動态擷取函數的位址實作調用。

想要動态擷取函數位址,可以使用以下函數

GetProcAddress 從dll中擷取函數的位址

LoadLibraryA 将指定的子產品加載到調用程序的位址空間中

舉個例子:

LPVOID lp = GetProcAddress(LoadLibraryA("user32.dll"),"MessageBoxA");
_asm
{
	push 0
	push 0
	push 0
	push 0
	call lp
}
           

這樣就可以擷取到MessageBoxA函數的位址,并且通過彙編代碼實作了調用。

當然如果我們想要在MessageBoxA函數中輸出一個字元串的話,可以設定一個字元串指針:

char * pszData =“helloworld”;

并且修改對應的push 參數就可以了。

這種方法可行,但是并不靈活,再看一下更加靈活的方式

用 CreatFileA 函數來示範一下

int entrymain()
{
	typedef HANDLE (WINAPI* FN_CreateFileA)(
	__in	 LPCSTR lpFileName,
	__in	 DWORD dwDesiredAccess,
	__in	 DWORD dwShareMode,
	__in	 LPSECURITY_ATTRIBUTES lpSecruityAttributes,
	__in	 DWORD dwCreationDisposition,
	__in	 DWORD dwFlagsAndAttributes,
	__in_opt HANDLE hTemplateFile
	);
	FN_CreatFileA fn_CreateFileA;
	fn_CreateFileA = (FN_CreatFileA)GetProcAddress(LoadLibraryA("kernel32.dll"),"CreateFileA");
	CreatFileA("hello.txt",GENERIC_WRITE,0,NULL,CREAT_ALWAYS,0,NULL);
}
           

我們可以自定義一個與想調用的函數一樣的新類型,這樣我們就可以随便使用,因為這個函數是我們自定義的函數。

當然,明眼的人可能已經發現,我們在使用GetProcAddress函數去獲得函數的位址時,GetProcAddress函數本身不就已經是調用的絕對位址了嗎?當然LoadLibraryA函數也一樣。

這裡我們就需要了解一下PEB和TEB與FS寄存器,FS0偏移處是teb結構體,30h偏移處是PEB結構體,而PEB結構體中有三個成員連結清單分别儲存了三個順序,代碼中有詳解。通過這三個順序我們分别可以使用三個方法獲得kernel32的基址。擷取這個基址的方法還有很多,推薦一篇部落格

__declspec(nacked) DWORD getKernel32()
{
	__asm
	{
		mov eax,fs:[30]   //fs:[30] 純存的是PEB,也就是程序環境塊,作業系統在加載程序的過程中會自動初始化一個PEB結構體用來初始化該程序的各種資訊的結構體
		mov eax,[eax+0ch]    //也就是PEB 0ch處的偏移,該結構體的三個成員連結清單都可以擷取kernel32的基址
		mov eax,[eax+14h]    //擷取初始化順序連結清單的位址,首位址是第一個子產品
		mov eax,[eax]        //第二個子產品
		mov eax,[eax]        //第三個子產品
		mov eax,[eax+10h]    // 10h偏移處就是kernel32的基位址
	}
}
           

看完上面的代碼,會有疑惑,為什麼是第三個參數呢?看下圖,是因為kernel32.dll是第三個被加載的dll檔案。

shellcode加載器
FARPROC _GetProcAddress(HMODULE hModuleBase) 
{
    PIMAGE_DOS_HEADER lpDosHeader = (PIMAGE_DOS_HEADER)hModuleBase;
    PIMAGE_NT_HEADERS32 lpNtHeader = (PIMAGE_NT_HEADERS)((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);

    DWORD dwLoop = 0;
    FARPROC pRet = NULL;
    for (; 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')
        {
            pRet = (FARPROC)(lpdwFunAddr[lpword[dwLoop]] + (DWORD)hModuleBase);
            break;
        }
    }
    return pRet;
}

           

這段代碼大意是

PEB_LDR_DATA 結構體

ntdll!_PEB_LDR_DATA  
   +0x000 Length            //結構體大小 
   +0x004 Initialized      //程序是否初始化完成
   +0x008 SsHandle 
   +0x00c InLoadOrderModuleList : _LIST_ENTRY             子產品在加載時候的順序
   +0x014 InMemoryOrderModuleList : _LIST_ENTRY        子產品在記憶體中的順序
   +0x01c InInitializationOrderModuleList : _LIST_ENTRY       子產品在初始化的一個順序
   +0x024 EntryInProgress
   +0x028 ShutdownInProgress
   +0x02c ShutdownThreadId
           

PEB結構體

ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 BitField         : UChar
   +0x003 ImageUsesLargePages : Pos 0, 1 Bit
   +0x003 IsProtectedProcess : Pos 1, 1 Bit
   +0x003 IsLegacyProcess  : Pos 2, 1 Bit
   +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit
   +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit
   +0x003 SpareBits        : Pos 5, 3 Bits
   +0x004 Mutant           : Ptr32 Void
   +0x008 ImageBaseAddress : Ptr32 Void
   +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
   +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : Ptr32 Void
   +0x018 ProcessHeap      : Ptr32 Void
   +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION
   +0x020 AtlThunkSListPtr : Ptr32 Void
   +0x024 IFEOKey          : Ptr32 Void
   +0x028 CrossProcessFlags : Uint4B
   +0x028 ProcessInJob     : Pos 0, 1 Bit
   +0x028 ProcessInitializing : Pos 1, 1 Bit
   +0x028 ProcessUsingVEH  : Pos 2, 1 Bit
   +0x028 ProcessUsingVCH  : Pos 3, 1 Bit
   +0x028 ProcessUsingFTH  : Pos 4, 1 Bit
   +0x028 ReservedBits0    : Pos 5, 27 Bits
   +0x02c KernelCallbackTable : Ptr32 Void
   +0x02c UserSharedInfoPtr : Ptr32 Void
   +0x030 SystemReserved   : [1] Uint4B
   +0x034 AtlThunkSListPtr32 : Uint4B
   +0x038 ApiSetMap        : Ptr32 Void
   +0x03c TlsExpansionCounter : Uint4B
   +0x040 TlsBitmap        : Ptr32 Void
   +0x044 TlsBitmapBits    : [2] Uint4B
   +0x04c ReadOnlySharedMemoryBase : Ptr32 Void
   +0x050 HotpatchInformation : Ptr32 Void
   +0x054 ReadOnlyStaticServerData : Ptr32 Ptr32 Void
   +0x058 AnsiCodePageData : Ptr32 Void
   +0x05c OemCodePageData  : Ptr32 Void
   +0x060 UnicodeCaseTableData : Ptr32 Void
   +0x064 NumberOfProcessors : Uint4B
   +0x068 NtGlobalFlag     : Uint4B
   +0x070 CriticalSectionTimeout : _LARGE_INTEGER
   +0x078 HeapSegmentReserve : Uint4B
   +0x07c HeapSegmentCommit : Uint4B
   +0x080 HeapDeCommitTotalFreeThreshold : Uint4B
   +0x084 HeapDeCommitFreeBlockThreshold : Uint4B
   +0x088 NumberOfHeaps    : Uint4B
   +0x08c MaximumNumberOfHeaps : Uint4B
   +0x090 ProcessHeaps     : Ptr32 Ptr32 Void
   +0x094 GdiSharedHandleTable : Ptr32 Void
   +0x098 ProcessStarterHelper : Ptr32 Void
   +0x09c GdiDCAttributeList : Uint4B
   +0x0a0 LoaderLock       : Ptr32 _RTL_CRITICAL_SECTION
   +0x0a4 OSMajorVersion   : Uint4B
   +0x0a8 OSMinorVersion   : Uint4B
   +0x0ac OSBuildNumber    : Uint2B
   +0x0ae OSCSDVersion     : Uint2B
   +0x0b0 OSPlatformId     : Uint4B
   +0x0b4 ImageSubsystem   : Uint4B
   +0x0b8 ImageSubsystemMajorVersion : Uint4B
   +0x0bc ImageSubsystemMinorVersion : Uint4B
   +0x0c0 ActiveProcessAffinityMask : Uint4B
   +0x0c4 GdiHandleBuffer  : [34] Uint4B
   +0x14c PostProcessInitRoutine : Ptr32     void 
   +0x150 TlsExpansionBitmap : Ptr32 Void
   +0x154 TlsExpansionBitmapBits : [32] Uint4B
   +0x1d4 SessionId        : Uint4B
   +0x1d8 AppCompatFlags   : _ULARGE_INTEGER
   +0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER
   +0x1e8 pShimData        : Ptr32 Void
   +0x1ec AppCompatInfo    : Ptr32 Void
   +0x1f0 CSDVersion       : _UNICODE_STRING
   +0x1f8 ActivationContextData : Ptr32 _ACTIVATION_CONTEXT_DATA
   +0x1fc ProcessAssemblyStorageMap : Ptr32 _ASSEMBLY_STORAGE_MAP
   +0x200 SystemDefaultActivationContextData : Ptr32 _ACTIVATION_CONTEXT_DATA
   +0x204 SystemAssemblyStorageMap : Ptr32 _ASSEMBLY_STORAGE_MAP
   +0x208 MinimumStackCommit : Uint4B
   +0x20c FlsCallback      : Ptr32 _FLS_CALLBACK_INFO
   +0x210 FlsListHead      : _LIST_ENTRY
   +0x218 FlsBitmap        : Ptr32 Void
   +0x21c FlsBitmapBits    : [4] Uint4B
   +0x22c FlsHighIndex     : Uint4B
   +0x230 WerRegistrationData : Ptr32 Void
   +0x234 WerShipAssertPtr : Ptr32 Void
   +0x238 pContextData     : Ptr32 Void
   +0x23c pImageHeaderHash : Ptr32 Void
   +0x240 TracingFlags     : Uint4B
   +0x240 HeapTracingEnabled : Pos 0, 1 Bit
   +0x240 CritSecTracingEnabled : Pos 1, 1 Bit
   +0x240 SpareTracingBits : Pos 2, 30 Bits
           

TEB結構體

ntdll!_TEB
   +0x000 NtTib            : _NT_TIB  //TIB結構
   	[+0x000] ExceptionList    : 0x1df360 [Type: _EXCEPTION_REGISTRATION_RECORD *]//指向SEH鍊
    [+0x004] StackBase        : 0x1e0000 [Type: void *]//堆棧基址
    [+0x008] StackLimit       : 0x1dd000 [Type: void *]//堆棧大小
    [+0x00c] SubSystemTib     : 0x0 [Type: void *]//
    [+0x010] FiberData        : 0x1e00 [Type: void *]
    [+0x010] Version          : 0x1e00 [Type: unsigned long]
    [+0x014] ArbitraryUserPointer : 0x0 [Type: void *]
    [+0x018] Self             : 0x7ffde000 [Type: _NT_TIB *]//指向自身的指針,也就是說Self同時是指向TEB和TIB頭部的指針(因為TIB為TEB結構的第一個成員)
   +0x01c EnvironmentPointer : Ptr32 Void//環境指針
   +0x020 ClientId         : _CLIENT_ID//CLIENT_ID結構,存儲PID和目前線程ID
   +0x028 ActiveRpcHandle  : Ptr32 Void//活動的RPC句柄
   +0x02c ThreadLocalStoragePointer : Ptr32 Void//指向線程局部存儲數組
   +0x030 ProcessEnvironmentBlock : Ptr32 _PEB//指向PEB結構
   +0x034 LastErrorValue   : Uint4B//儲存着LastError的值
   +0x038 CountOfOwnedCriticalSections : Uint4B//所擁有的臨界區數量
   +0x03c CsrClientThread  : Ptr32 Void//指向CSR客戶線程
   +0x040 Win32ThreadInfo  : Ptr32 Void//指向Win32線程資訊
   +0x044 User32Reserved   : [26] Uint4B
   +0x0ac UserReserved     : [5] Uint4B
   +0x0c0 WOW32Reserved    : Ptr32 Void
   +0x0c4 CurrentLocale    : Uint4B//目前的Locale
   +0x0c8 FpSoftwareStatusRegister : Uint4B//FP軟體狀态寄存器
   +0x0cc SystemReserved1  : [54] Ptr32 Void
   +0x1a4 ExceptionCode    : Int4B//異常碼
   +0x1a8 ActivationContextStackPointer : Ptr32 _ACTIVATION_CONTEXT_STACK//指向活動上下文棧的指針
   +0x1ac SpareBytes       : [36] UChar//空閑位元組
   +0x1d0 TxFsContext      : Uint4B
   +0x1d4 GdiTebBatch      : _GDI_TEB_BATCH
   +0x6b4 RealClientId     : _CLIENT_ID
   +0x6bc GdiCachedProcessHandle : Ptr32 Void
   +0x6c0 GdiClientPID     : Uint4B//真實的程序PID
   +0x6c4 GdiClientTID     : Uint4B//真實的線程TID
   +0x6c8 GdiThreadLocalInfo : Ptr32 Void
   +0x6cc Win32ClientInfo  : [62] Uint4B
   +0x7c4 glDispatchTable  : [233] Ptr32 Void
   +0xb68 glReserved1      : [29] Uint4B
   +0xbdc glReserved2      : Ptr32 Void
   +0xbe0 glSectionInfo    : Ptr32 Void
   +0xbe4 glSection        : Ptr32 Void
   +0xbe8 glTable          : Ptr32 Void
   +0xbec glCurrentRC      : Ptr32 Void
   +0xbf0 glContext        : Ptr32 Void
   +0xbf4 LastStatusValue  : Uint4B
   +0xbf8 StaticUnicodeString : _UNICODE_STRING
   +0xc00 StaticUnicodeBuffer : [261] Wchar
   +0xe0c DeallocationStack : Ptr32 Void
   +0xe10 TlsSlots         : [64] Ptr32 Void
   +0xf10 TlsLinks         : _LIST_ENTRY
   +0xf18 Vdm              : Ptr32 Void
   +0xf1c ReservedForNtRpc : Ptr32 Void
   +0xf20 DbgSsReserved    : [2] Ptr32 Void
   +0xf28 HardErrorMode    : Uint4B
   +0xf2c Instrumentation  : [9] Ptr32 Void
   +0xf50 ActivityId       : _GUID
   +0xf60 SubProcessTag    : Ptr32 Void
   +0xf64 EtwLocalData     : Ptr32 Void
   +0xf68 EtwTraceData     : Ptr32 Void
   +0xf6c WinSockData      : Ptr32 Void
   +0xf70 GdiBatchCount    : Uint4B
   +0xf74 CurrentIdealProcessor : _PROCESSOR_NUMBER
   +0xf74 IdealProcessorValue : Uint4B
   +0xf74 ReservedPad0     : UChar
   +0xf75 ReservedPad1     : UChar
   +0xf76 ReservedPad2     : UChar
   +0xf77 IdealProcessor   : UChar
   +0xf78 GuaranteedStackBytes : Uint4B
   +0xf7c ReservedForPerf  : Ptr32 Void
   +0xf80 ReservedForOle   : Ptr32 Void
   +0xf84 WaitingOnLoaderLock : Uint4B
   +0xf88 SavedPriorityState : Ptr32 Void
   +0xf8c SoftPatchPtr1    : Uint4B
   +0xf90 ThreadPoolData   : Ptr32 Void
   +0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void
   +0xf98 MuiGeneration    : Uint4B
   +0xf9c IsImpersonating  : Uint4B
   +0xfa0 NlsCache         : Ptr32 Void
   +0xfa4 pShimData        : Ptr32 Void
   +0xfa8 HeapVirtualAffinity : Uint4B
   +0xfac CurrentTransactionHandle : Ptr32 Void
   +0xfb0 ActiveFrame      : Ptr32 _TEB_ACTIVE_FRAME
   +0xfb4 FlsData          : Ptr32 Void
   +0xfb8 PreferredLanguages : Ptr32 Void
   +0xfbc UserPrefLanguages : Ptr32 Void
   +0xfc0 MergedPrefLanguages : Ptr32 Void
   +0xfc4 MuiImpersonation : Uint4B
   +0xfc8 CrossTebFlags    : Uint2B
   +0xfc8 SpareCrossTebBits : Pos 0, 16 Bits
   +0xfca SameTebFlags     : Uint2B
   +0xfca SafeThunkCall    : Pos 0, 1 Bit
   +0xfca InDebugPrint     : Pos 1, 1 Bit
   +0xfca HasFiberData     : Pos 2, 1 Bit
   +0xfca SkipThreadAttach : Pos 3, 1 Bit
   +0xfca WerInShipAssertCode : Pos 4, 1 Bit
   +0xfca RanProcessInit   : Pos 5, 1 Bit
   +0xfca ClonedThread     : Pos 6, 1 Bit
   +0xfca SuppressDebugMsg : Pos 7, 1 Bit
   +0xfca DisableUserStackWalk : Pos 8, 1 Bit
   +0xfca RtlExceptionAttached : Pos 9, 1 Bit
   +0xfca InitialThread    : Pos 10, 1 Bit
   +0xfca SpareSameTebBits : Pos 11, 5 Bits
   +0xfcc TxnScopeEnterCallback : Ptr32 Void
   +0xfd0 TxnScopeExitCallback : Ptr32 Void
   +0xfd4 TxnScopeContext  : Ptr32 Void
   +0xfd8 LockCount        : Uint4B
   +0xfdc SpareUlong0      : Uint4B
   +0xfe0 ResourceRetValue : Ptr32 Void
           

繼續閱讀