不能有全局變量 (其實也是使用了絕對位址)
不能使用常量字元串
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檔案。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI2EzX4xSZz91ZsAzNfRHLGZkRGZkRfJ3bs92YsAjMfVmepNHL90zZiBnRqVWQClGVF5UMR9Fd4VGdsATNfd3bkFGazxycykFaKdkYzZUbapXNXlleSdVY2pESa9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL4EGNwkzY4YWOygTM4Q2Y5IWOlRjNyMGZ3YWZ4ATYmdzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
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