亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

c++ 如何實現線程注入

 更新時間:2021年06月23日 15:44:44   作者:LyShark  
本文主要介紹了各種API遠程線程注入的方法,分別是 遠程線程注入,普通消息鉤子注入,全局消息鉤子注入,APC應用層異步注入,ZwCreateThreadEx強力注入,純匯編實現的線程注入等

簡單編寫DLL文件:

#include <Windows.h>

extern "C" __declspec(dllexport) void MsgBox(LPCWSTR szMsg, LPCWSTR Title)
{
	MessageBox(NULL, szMsg, Title, MB_OK);
}

BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		// 進程被加載后執(zhí)行
		break;
	case DLL_THREAD_ATTACH:
		// 線程被創(chuàng)建后加載
		break;
	case DLL_THREAD_DETACH:
		// 正常退出執(zhí)行的代碼
		break;
	case DLL_PROCESS_DETACH:
		// 進程卸載本Dll后執(zhí)行的代碼
		break;
	}
	return TRUE;
}
#include <Windows.h>
#include <iostream>

typedef VOID(*PFUNMSG)(LPCWSTR szMsg, LPCWSTR Title);

int main(int argc, char *argv[])
{

	HMODULE hModule = LoadLibrary("./hook.dll");

	if (hModule != NULL)
	{
		PFUNMSG pMsgBox = (PFUNMSG)GetProcAddress(hModule, "MsgBox");
		pMsgBox(L"hello lyshark", L"msgbox");
	}

	system("pause");
	return 0;
}

x86 實現遠程線程注入:

注入原理是利用了Windows系統(tǒng)中提供的CreateRemoteThread()這個API函數,該函數第四個參數是準備運行的線程,我們將LoadLibrary()函數填入其中,這樣就可以執(zhí)行遠程進程中的LoadLibrary()函數,進而將我們自己準備的DLL加載到遠程進程空間中執(zhí)行,DLL在被裝載后則會自動執(zhí)行初始化部分,X86注入代碼如下.

#include <windows.h>
#include <stdio.h>

// 使用 CreateRemoteThread 實現遠線程注入
BOOL CreateRemoteThreadInjectDll(DWORD Pid, char *DllName)
{
	HANDLE hProcess = NULL;
	SIZE_T dwSize = 0;
	LPVOID pDllAddr = NULL;
	FARPROC pFuncProcAddr = NULL;

	// 打開注入進程,獲取進程句柄
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
	if (NULL == hProcess)
	{
		return FALSE;
	}
	// 計算欲注入 DLL 文件完整路徑的長度
	dwSize = sizeof(char)+lstrlen(DllName);

	//  在目標進程申請一塊長度為 nDllLen 大小的內存空間
	pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == pDllAddr)
	{
		return FALSE;
	}
	//  將欲注入 DLL 文件的完整路徑寫入在目標進程中申請的空間內
	if (FALSE == WriteProcessMemory(hProcess, pDllAddr, DllName, dwSize, NULL))
	{
		return FALSE;
	}
	// 獲得 LoadLibraryA()函數的地址
	pFuncProcAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
	if (NULL == pFuncProcAddr)
	{
		return FALSE;
	}
	// 使用 CreateRemoteThread 創(chuàng)建遠線程, 實現 DLL 注入
	HANDLE hRemoteThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, NULL);
	if (NULL == hRemoteThread)
	{
		return FALSE;
	}
	// 關閉句柄
	CloseHandle(hProcess);
	return TRUE;
}

int main(int argc, char *argv[])
{
	CreateRemoteThreadInjectDll(4668, "./x86.dll");
	system("pause");
	return 0;
}

x64 實現遠程線程注入:

如果想要注入X64程序,則需要在編譯時指定為64位編譯模式,并且使用LoadLibraryW()來加載動態(tài)鏈接庫,我們只需要在上面代碼的基礎上稍加改進就可以實現64位進程的注入了.

#include <windows.h>
#include <stdio.h>

// 使用 CreateRemoteThread 實現遠線程注入
BOOL CreateRemoteThreadInjectDll(DWORD Pid, PCWSTR DllName)
{
	BOOL ret = FALSE;
	HANDLE hProcess, hThread = NULL;
	FARPROC pfnThreadRtn = NULL;
	PWSTR pwszPara = NULL;

	// 打開注入進程,獲取進程句柄
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
	if (NULL == hProcess)
	{
		return FALSE;
	}

	// 計算欲注入 DLL 文件完整路徑的長度
	size_t iProxyFileLen = wcslen(DllName) * sizeof(WCHAR);

	//  在目標進程申請一塊長度為 nDllLen 大小的內存空間
	pwszPara = (PWSTR)VirtualAllocEx(hProcess, NULL, iProxyFileLen, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == pwszPara)
	{
		return FALSE;
	}

	//  將欲注入 DLL 文件的完整路徑寫入在目標進程中申請的空間內
	if (FALSE == WriteProcessMemory(hProcess, pwszPara, (PVOID)DllName, iProxyFileLen, NULL))
	{
		return FALSE;
	}

	// 獲得 LoadLibraryW()函數的地址
	pfnThreadRtn = GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
	if (NULL == pfnThreadRtn)
	{
		return FALSE;
	}

	// 使用 CreateRemoteThread 創(chuàng)建遠線程, 實現 DLL 注入
	hThread = CreateRemoteThread(hProcess, NULL, 1024, (LPTHREAD_START_ROUTINE)pfnThreadRtn, pwszPara, 0, NULL);
	WaitForSingleObject(hThread, INFINITE);
	if (NULL != hThread)
	{
		CloseHandle(hThread);
		CloseHandle(hProcess);
		VirtualFreeEx(hProcess, pwszPara, 0, MEM_RELEASE);
		return TRUE;
	}
	return FALSE;
}

int main(int argc, char *argv[])
{
	CreateRemoteThreadInjectDll(8224, L"./x64.dll");
	system("pause");
	return 0;
}

實現普通消息鉤子注入:

Windows提供的鉤子類型非常多,其中一種類型的鉤子非常實用,那就是WH_GETME SSAGE鉤子,它可以很方便地將DLL文件注入到所有的基于消息機制的目標程序中,代碼非常簡單,這里直接給出DLL文件的代碼,具體如下:

#include <windows.h>

extern "C" __declspec(dllexport) VOID SetHookOn();
extern "C" __declspec(dllexport) VOID SetHookOff();

HHOOK g_HHook = NULL;
HINSTANCE g_hInst = NULL;

VOID DoSomeThing()
{
	MessageBoxA(0, "hello lyshark", 0, 0);
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{
	switch (fdwReason)
	{
		case DLL_PROCESS_ATTACH:
		{
			g_hInst = hinstDLL;
			DoSomeThing();
			break;
		}
	}
	return TRUE;
}

LRESULT CALLBACK GetMsgProc(int code,WPARAM wParam,LPARAM lParam)
{
	return CallNextHookEx(g_HHook, code, wParam, lParam);
}

VOID SetHookOn()
{
	g_HHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hInst, 0);
}

VOID SetHookOff()
{
	UnhookWindowsHookEx(g_HHook);
}

實現全局消息鉤子注入:

該注入的原理是利用系統(tǒng)中的SetWindowHookEx()這個API函數,該函數可以攔截目標進程的消息到指定DLL中的導出函數上,利用這個特性,我們可以將DLL注入到全局進程中,但是在使用SetWindowsHookEx()之前首先需要將HOOK的DLL加載到本身的進程中,以此得到DLL的模塊句柄,再使用GetProcAddress()得到DLL中公開的函數地址,最后遍歷出待注入進程的線程ID,這樣SetWindowHookEx()就可以利用這些參數進行HOOK了.

我們先來編寫DLL文件,創(chuàng)建Dll工程hook.cpp然后將SetHook()函數導出,由于該注入方式是全局注入,所以如果我們想要注入到指定進程中,則需要在DllMain()也就是動態(tài)鏈接庫開頭位置進行判斷,如果是我們需要Hook的進程,則加載Dll到指定進程中,如果不是則不執(zhí)行任何操作,這樣一來即可實現指定進程注入.

#include <windows.h>
HHOOK Global_Hook;

// 設置全局消息回調函數
LRESULT CALLBACK MyProc(int nCode, WPARAM wParam, LPARAM lParam)
{
	return CallNextHookEx(Global_Hook, nCode, wParam, lParam);
}
// 安裝全局鉤子,此處的hook.dll可以是外部其他的dll
extern "C" __declspec(dllexport) void SetHook()
{
	Global_Hook = SetWindowsHookEx(WH_CBT, MyProc, GetModuleHandle(TEXT("hook.dll")), 0);
}
// 卸載全局鉤子
extern "C" __declspec(dllexport) void UnHook()
{
	if(Global_Hook)
		UnhookWindowsHookEx(Global_Hook);
}

bool APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
	HWND hwnd = FindWindowW(L"valve001",NULL);
	DWORD pid;
	GetWindowThreadProcessId(hwnd, &pid);
	if (GetCurrentProcessId() == pid)
	{
		MessageBox(hwnd, TEXT("hello lyshark"), 0, 0);
	}
	return true;
}

調用代碼:注意必須將上方編譯好的hook.dll與下方工程放到同一個目錄下,通過LoadLibrary()函數獲取到模塊句柄,然后通過GetProcAddress()獲取到導出函數地址,并通過函數指針調用,由于全局注入依賴于父進程,所以下面的代碼必須一直運行.

#include <windows.h>

int main(int argc, char *argv[])
{
	HMODULE hMod = LoadLibrary(TEXT("hook.dll"));

	typedef void(*pSetHook)(void);
	pSetHook SetHook = (pSetHook)GetProcAddress(hMod, "SetHook");
	SetHook();
	while (1)
	{
		Sleep(1000);
	}
	return 0;
}

APC應用層異步注入:

APC 是異步過程調用,在Windows下每個線程在可被喚醒時在其APC鏈中的函數將有機會執(zhí)行被執(zhí)行,每一個線程都具有一個APC鏈,那么只要在可以在APC鏈中添加一個APC,就可以完成我們所需要的DLL注入的功能.

1.將需要加載的DLL的完整路徑寫入目標進程空間.
2.獲得LoadLibraryA()函數的地址,當然也可以是LoadLibraryW()函數的地址.
3.枚舉目標進程中的所有線程,為每個線程添加一個APC函數,這樣增加了注入成功的機會.

該注入的原理是利用當線程被喚醒時APC中的注冊函數會被執(zhí)行的機制,并以此去執(zhí)行我們的DLL加載代碼,進而完成DLL注入的

目的,通過APC注入的流程步驟大致如下

1.當EXE里某個線程執(zhí)行到SleepEx()或者WaitForSingleObjectEx()時,系統(tǒng)就會產生一個軟中斷.
2.當線程再次被喚醒時,此線程會首先執(zhí)行APC隊列中的被注冊的函數.
3.利用QueueUserAPC()這個API可以在軟中斷時向線程的APC隊列插入一個函數指針,如果我們插入的是Loadlibrary()執(zhí)行函數的話,就能達到注入DLL的目的,不論如何目標程序必須有執(zhí)行SleepEx()或者WaitForSingleObjectEx()否則DLL不會加載.

#include <windows.h>
#include <tlhelp32.h>
#include <stdio.h>

// APC注入
BOOL ApcInjectDll(DWORD dwPid, char * szDllName)
{
	// 計算欲注入 DLL 文件完整路徑的長度
	int nDllLen = lstrlen(szDllName) + sizeof(char);

	// 打開目標進程
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwPid);
	if (hProcess == NULL)
	{
		return FALSE;
	}
	// 在目標進程申請一塊長度為 nDllLen 大小的內存空間
	PVOID pDllAddr = VirtualAllocEx(hProcess,NULL, nDllLen,MEM_COMMIT,PAGE_READWRITE);
	if (pDllAddr == NULL)
	{
		CloseHandle(hProcess);
		return FALSE;
	}
	DWORD dwWriteNum = 0;
	// 將欲注入 DLL 文件的完整路徑寫入在目標進程中申請的空間內
	WriteProcessMemory(hProcess, pDllAddr, szDllName,nDllLen, &dwWriteNum);
	CloseHandle(hProcess);

	THREADENTRY32 te = { 0 };
	te.dwSize = sizeof(THREADENTRY32);
	//得到線程快照
	HANDLE handleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
	if (INVALID_HANDLE_VALUE == handleSnap)
	{
		CloseHandle(hProcess);
		return FALSE;
	}
	// 獲得 LoadLibraryA()函數的地址
	FARPROC pFunAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
	DWORD dwRet = 0;
	//得到第一個線程
	if (Thread32First(handleSnap, &te))
	{
		do
		{
			//進行進程 ID 對比
			if (te.th32OwnerProcessID == dwPid)
			{
				//得到線程句柄
				HANDLE hThread = OpenThread(THREAD_ALL_ACCESS,FALSE,te.th32ThreadID);
				if (hThread)
				{
					//向線程插入 APC
					dwRet = QueueUserAPC((PAPCFUNC)pFunAddr,hThread,(ULONG_PTR)pDllAddr);
					//關閉句柄
					CloseHandle(hThread);
				}
			}
			//循環(huán)下一個線程
		} while (Thread32Next(handleSnap, &te));
	}
	CloseHandle(handleSnap);
	return TRUE;
}

int main(int argc, char *argv[])
{
	ApcInjectDll(9608, "c:/x86.dll");
	system("pause");
	return 0;
}

ZwCreateThreadEx強力注入:

在前面的注入方式中,我們使用了CreateRemoteThread()這個函數來完成線程注入,此方式可以注入普通的進程,但卻無法注入到系統(tǒng)進程中,因為系統(tǒng)進程是處在SESSION0高權限級別的會話層.

由于CreateRemoteThread()底層會調用ZwCreateThreadEx()這個未公開的內核函數,所以我們必須手動調用ZwCreateThread()這一內核函數,將第七個參數設置為0即可,ZwCreateThreadEx函數在ntdll.dll中并未聲明,所以必須手動使用GetProcAddress函數將其地址導出.

#include <windows.h>
#include <stdio.h>

// 使用 ZwCreateThreadEx 實現遠線程注入
BOOL ZwCreateThreadExInjectDll(DWORD dwProcessId, char * pDllName)
{
	HANDLE hProcess = NULL;
	SIZE_T dwSize = 0;
	LPVOID pDllAddr = NULL;
	FARPROC pFuncProcAddr = NULL;
	HANDLE hRemoteThread = NULL;
	DWORD dwStatus = 0;

	// 打開注入進程,獲取進程句柄
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
	if (NULL == hProcess)
	{
		return FALSE;
	}
	// 在注入進程中申請內存
	dwSize = sizeof(char)+lstrlen(pDllName);
	pDllAddr = ::VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == pDllAddr)
	{
		return FALSE;
	}
	// 向申請的內存中寫入數據
	if (FALSE == ::WriteProcessMemory(hProcess, pDllAddr, pDllName, dwSize, NULL))
	{
		return FALSE;
	}
	// 加載 ntdll.dll
	HMODULE hNtdllDll = ::LoadLibrary("ntdll.dll");
	if (NULL == hNtdllDll)
	{
		return FALSE;
	}
	// 獲取LoadLibraryA函數地址
	pFuncProcAddr = ::GetProcAddress(::GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
	if (NULL == pFuncProcAddr)
	{
		return FALSE;
	}
	// 獲取ZwCreateThread函數地址
#ifdef _WIN64
	typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
		PHANDLE ThreadHandle,
		ACCESS_MASK DesiredAccess,
		LPVOID ObjectAttributes,
		HANDLE ProcessHandle,
		LPTHREAD_START_ROUTINE lpStartAddress,
		LPVOID lpParameter,
		ULONG CreateThreadFlags,
		SIZE_T ZeroBits,
		SIZE_T StackSize,
		SIZE_T MaximumStackSize,
		LPVOID pUnkown);
#else
	typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
		PHANDLE ThreadHandle,
		ACCESS_MASK DesiredAccess,
		LPVOID ObjectAttributes,
		HANDLE ProcessHandle,
		LPTHREAD_START_ROUTINE lpStartAddress,
		LPVOID lpParameter,
		BOOL CreateSuspended,
		DWORD dwStackSize,
		DWORD dw1,
		DWORD dw2,
		LPVOID pUnkown);
#endif
	typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)::GetProcAddress(hNtdllDll, "ZwCreateThreadEx");
	if (NULL == ZwCreateThreadEx)
	{
		return FALSE;
	}
	// 使用 ZwCreateThreadEx 創(chuàng)建遠線程, 實現 DLL 注入
	dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, hProcess, 
		(LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, 0, 0, 0, NULL);
	if (NULL == hRemoteThread)
	{
		return FALSE;
	}
	// 關閉句柄
	::CloseHandle(hProcess);
	::FreeLibrary(hNtdllDll);
	return TRUE;
}

int main(int argc, char *argv[])
{
	BOOL bRet = ZwCreateThreadExInjectDll(2940, "hook.dll");

	system("pause");
	return 0;
}

強制卸載進程中的DLL:

#include <Windows.h>
#include <stdio.h>
#include <TlHelp32.h>

BOOL UnLoad_Module(DWORD dwPID, LPCTSTR szDllName)
{
	BOOL bMore = FALSE, bFound = FALSE;
	HANDLE hSnapshot, hProcess, hThread;
	HMODULE hModule = NULL;
	MODULEENTRY32 me = { sizeof(me) };
	LPTHREAD_START_ROUTINE pThreadProc;

	hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
	bMore = Module32First(hSnapshot, &me);
	for (; bMore; bMore = Module32Next(hSnapshot, &me))
	{
		if (!_tcsicmp((LPCTSTR)me.szModule, szDllName) || !_tcsicmp((LPCTSTR)me.szExePath, szDllName))
		{
			bFound = TRUE;
			break;
		}
	}
	if (!(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)))
		return FALSE;

	hModule = GetModuleHandle(L"kernel32.dll");
	pThreadProc = (LPTHREAD_START_ROUTINE)GetProcAddress(hModule, "FreeLibrary");
	hThread = CreateRemoteThread(hProcess, NULL, 0, pThreadProc, me.modBaseAddr, 0, NULL);
	WaitForSingleObject(hThread, INFINITE);
	if (hThread != 0)
	{
		CloseHandle(hThread);
		CloseHandle(hProcess);
		CloseHandle(hSnapshot);
		return TRUE;
	}
	return FALSE;
}

int main(int argc, char *argv[])
{
	UnLoad_Module(2012, "lyshark.dll");

	system("pause");
	return 0;
}

純匯編實現遠程Dll注入:

.data
	szMyDll        db "\lyshark.dll",0h       ; 要注入的DLL
	szDllKernel    db "Kernel32.dll",0h
	szLoadLibrary  db "LoadLibraryA",0h
	lpFileName     db "Tutorial-i386",0h      ; 指定要注入進程
	lpDllName      dd ?
.data?
	szMyDllFull    db MAX_PATH dup (?)
	lpLoadLibrary  dd ?
	dwProcessID    dd ?     
	dwThreadID     dd ?
	hProcess       dd ?
.code
	main PROC
; 準備工作:獲取dll的全路徑文件名、獲取LoadLibrary函數地址等
		invoke GetCurrentDirectory,MAX_PATH,addr szMyDllFull
		invoke lstrcat,addr szMyDllFull,addr szMyDll
		invoke GetModuleHandle,addr szDllKernel
		invoke GetProcAddress,eax,offset szLoadLibrary
		mov lpLoadLibrary,eax

; 查找文件管理器窗口并獲取進程ID,然后打開進程
		invoke FindWindow,NULL,addr lpFileName
		invoke GetWindowThreadProcessId,eax,offset dwProcessID
  		mov dwThreadID,eax
  		invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,dwProcessID
		mov hProcess,eax

; 在進程中分配空間并將DLL文件名拷貝過去,然后創(chuàng)建一個LoadLibrary線程
		invoke VirtualAllocEx,hProcess,NULL,MAX_PATH,MEM_COMMIT,PAGE_READWRITE
		mov lpDllName,eax
		invoke WriteProcessMemory,hProcess,eax,offset szMyDllFull,MAX_PATH,NULL
		invoke CreateRemoteThread,hProcess,NULL,0,lpLoadLibrary,lpDllName,0,NULL
		ret
	main endp
end main

純匯編實現遠程代碼注入:

1.首先使用匯編編寫一個代碼注入器,其命名為main.asm

.data
	lpLoadLibrary      dd ?
	lpGetProcAddress   dd ?
	lpGetModuleHandle  dd ?
	dwProcessID        dd ?
	dwThreadID         dd ?
	hProcess           dd ?
	lpRemoteCode       dd ?
.const
	ProcHandle        db "lyshark.exe",0h
	KernelBase        db "Kernel32.dll",0h
	szLoadLibrary     db "LoadLibraryA",0h
	szGetProcAddress  db "GetProcAddress",0h
	szGetModuleHandle db "GetModuleHandleA",0h
.code
include Macro.inc
include ShellCode.asm
	main proc
		invoke GetModuleHandle,addr KernelBase
		mov ebx,eax
		invoke GetProcAddress,ebx,offset szLoadLibrary
		mov lpLoadLibrary,eax
		invoke GetProcAddress,ebx,offset szGetProcAddress
		mov lpGetProcAddress,eax
		invoke GetProcAddress,ebx,offset szGetModuleHandle
		mov lpGetModuleHandle,eax

		invoke FindWindow,NULL,addr ProcHandle
		invoke GetWindowThreadProcessId,eax,offset dwProcessID
		mov dwThreadID,eax
		invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,dwProcessID
		mov hProcess,eax

		invoke VirtualAllocEx,hProcess,NULL,2048,MEM_COMMIT,PAGE_EXECUTE_READWRITE
			.if eax
				mov lpRemoteCode,eax
				invoke WriteProcessMemory,hProcess,lpRemoteCode,offset REMOTE_CODE_START,1024,NULL
				invoke WriteProcessMemory,hProcess,lpRemoteCode,offset lpLoadLibrary,sizeof dword * 3,NULL
				mov eax,lpRemoteCode
				add eax,offset _RemoteThread - offset REMOTE_CODE_START
				invoke CreateRemoteThread,hProcess,NULL,0,eax,0,0,NULL
				invoke CloseHandle,eax
			.endif
			invoke CloseHandle,hProcess	
	invoke ExitProcess,NULL
	ret
	main endp
end main

為了后期編程方便,編寫一個反轉宏Macro.inc用來翻轉參數,使用定義_invoke調用更方便

; --------------------------------------------
; 翻轉參數字節(jié)序
reverseArgs macro arglist:VARARG
	LOCAL txt,count
	txt TEXTEQU <>
	count=0
	for i,<arglist>
		count = count+1
		txt TEXTEQU @CatStr(i,<!,>,<%txt>)
	endm
	if count GT 0
		txt SUBSTR txt,1,@SizeStr(%txt)-1
	endif
	exitm txt
endm
; --------------------------------------------
; 創(chuàng)建類似于INVOKE的宏代碼
_invoke macro _Proc,args:VARARG
	LOCAL count
	count = 0
%	for i,< reverseArgs( args ) >
		count = count+1
		push i
	endm
	call dword ptr _Proc    
endm

最后編寫注入代碼,此處命名為shellcode.asm該代碼包括了子定位功能.

REMOTE_CODE_START equ this byte
_lpLoadLibrary      dd ?
_lpGetProcAddress   dd ?
_lpGetModuleHandle  dd ?

; --------------------------------------------
; 存放靜態(tài)資源,比如常量,字符串等.
_hInstance          dd ?
_szShowTitle        db "hello lyshark",0h

; --------------------------------------------
; 存放獲取到的指針
_lpDllUser          dd ?
_lpMessageBox       dd ?
; --------------------------------------------
; 放入導入函數的字符串
_szDllUser		db	"user32.dll",0h
_szMessageBox           db      "MessageBoxA",0h,0
; --------------------------------------------
_RemoteThread proc uses ebx esi edi
		LOCAL @hModule
; --------------------------------------------
; 計算指令的偏移地址,用ebx作為基址指針
		call @F
		@@:
		pop ebx
		sub ebx,offset @B
; --------------------------------------------
		_invoke [ebx + _lpGetModuleHandle],NULL         ; 取當前模塊句柄
		mov [ebx + _hInstance],eax
		lea eax,[ebx + offset _szDllUser]           
		_invoke [ebx + _lpGetModuleHandle],eax          ; 取user32.dll模塊句柄
		mov @hModule,eax
; --------------------------------------------
; 循環(huán)獲取每個導入函數的地址,并放入指針變量保存
		lea esi,[ebx + offset _szMessageBox]            ; 循環(huán)獲取,從該函數起始地址處
		lea edi,[ebx + offset _lpMessageBox]
		.while TRUE
			_invoke	[ebx + _lpGetProcAddress],@hModule,esi
			mov [edi],eax       ; 獲取到函數地址后,放入導入函數字符串中
			add edi,4           ; 每次遞增4字節(jié),指向下一個函數,遇到0則停止
			@@:
			lodsb
			or al,al
			jnz @B
			.break .if !byte ptr [esi]
		.endw
; --------------------------------------------
		;lea esi,[ebx+ offset _szMessageBox]            ; 取msgbox模塊地址
		;_invoke [ebx+_lpGetProcAddress],@hModule,esi   ; 獲取地址
		;mov [ebx+_lpMessageBox],eax                    ; 存入變量中
		lea esi,[ebx + offset _szShowTitle]             ; 獲取彈窗資源
		_invoke [ebx + _lpMessageBox],0,esi,eax,0       ; 調用信息框
		ret
_RemoteThread endp

文章出處:https://www.cnblogs.com/lyshark

以上就是c++ 如何實現線程注入的詳細內容,更多關于c++ 實現線程注入的資料請關注腳本之家其它相關文章!

相關文章

  • C語言實現電話訂餐管理系統(tǒng)

    C語言實現電話訂餐管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現電話訂餐管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 如何用C寫一個web服務器之GCC項目編譯

    如何用C寫一個web服務器之GCC項目編譯

    本文主要介紹了,如何用C寫一個web服務器,Linux下用GCC進行項目編譯,對此感興趣的同學,可以參考下。
    2021-05-05
  • C語言實例講解嵌套語句的用法

    C語言實例講解嵌套語句的用法

    所謂嵌套(Nest),就是一條語句里面還有另一條語句,例如 for 里面還有 for,while 里 面還有 while,或者 for 里面有 while,while 里面有 if-else,這都是允許的
    2022-05-05
  • C++深淺拷貝和string類的兩種寫法詳解

    C++深淺拷貝和string類的兩種寫法詳解

    這篇文章主要為大家詳細介紹了C++深淺拷貝和string類的兩種寫法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++索引越界的解決方法

    C++索引越界的解決方法

    本文主要介紹了C++索引越界的解決方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C++中的覆蓋和隱藏詳解

    C++中的覆蓋和隱藏詳解

    這篇文章主要介紹了C++中重載、重寫(覆蓋)和隱藏的區(qū)別,是C++面向對象程序設計非常重要的概念,需要的朋友可以參考下,希望能夠給你帶來幫助
    2021-08-08
  • C++中的HTTP協(xié)議問題

    C++中的HTTP協(xié)議問題

    這篇文章主要介紹了C++中的HTTP協(xié)議問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 使用單鏈表實現多項式計算示例

    使用單鏈表實現多項式計算示例

    這篇文章主要介紹了使用單鏈表實現多項式計算示例,需要的朋友可以參考下
    2014-03-03
  • C++?Qt實現音視頻播放功能

    C++?Qt實現音視頻播放功能

    Qt版本?5.9?基于C++11?Qt核心組件與附加組件安裝時請打鉤?否則可能出現項目中缺少視頻播放模塊的問題,由于最近著手的Qt項目需要視頻播放自己做的時候踩很多坑避免以后踩坑,故在此記錄實現過程,感謝的朋友參考下吧
    2021-11-11
  • C++使用宏函數實現單例模板詳解

    C++使用宏函數實現單例模板詳解

    在我們日常開發(fā)中,無可避免需要使用單例模式進行設計類對象。這篇文章主要介紹了如何使用宏函數實現單例模板,感興趣的小伙伴可以了解一下
    2023-02-02

最新評論