最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c++ 如何實現(xiàn)線程注入

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

簡單編寫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:
		// 進(jìn)程被加載后執(zhí)行
		break;
	case DLL_THREAD_ATTACH:
		// 線程被創(chuàng)建后加載
		break;
	case DLL_THREAD_DETACH:
		// 正常退出執(zhí)行的代碼
		break;
	case DLL_PROCESS_DETACH:
		// 進(jìn)程卸載本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 實現(xiàn)遠(yuǎn)程線程注入:

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

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

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

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

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

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

x64 實現(xiàn)遠(yuǎn)程線程注入:

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

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

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

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

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

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

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

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

	// 使用 CreateRemoteThread 創(chuàng)建遠(yuǎn)線程, 實現(xiàn) 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;
}

實現(xiàn)普通消息鉤子注入:

Windows提供的鉤子類型非常多,其中一種類型的鉤子非常實用,那就是WH_GETME SSAGE鉤子,它可以很方便地將DLL文件注入到所有的基于消息機(jī)制的目標(biāo)程序中,代碼非常簡單,這里直接給出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);
}

實現(xiàn)全局消息鉤子注入:

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

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

#include <windows.h>
HHOOK Global_Hook;

// 設(shè)置全局消息回調(diào)函數(shù)
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;
}

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

#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應(yīng)用層異步注入:

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

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

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

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

1.當(dāng)EXE里某個線程執(zhí)行到SleepEx()或者WaitForSingleObjectEx()時,系統(tǒng)就會產(chǎn)生一個軟中斷.
2.當(dāng)線程再次被喚醒時,此線程會首先執(zhí)行APC隊列中的被注冊的函數(shù).
3.利用QueueUserAPC()這個API可以在軟中斷時向線程的APC隊列插入一個函數(shù)指針,如果我們插入的是Loadlibrary()執(zhí)行函數(shù)的話,就能達(dá)到注入DLL的目的,不論如何目標(biāo)程序必須有執(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);

	// 打開目標(biāo)進(jìn)程
	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE, dwPid);
	if (hProcess == NULL)
	{
		return FALSE;
	}
	// 在目標(biāo)進(jìn)程申請一塊長度為 nDllLen 大小的內(nèi)存空間
	PVOID pDllAddr = VirtualAllocEx(hProcess,NULL, nDllLen,MEM_COMMIT,PAGE_READWRITE);
	if (pDllAddr == NULL)
	{
		CloseHandle(hProcess);
		return FALSE;
	}
	DWORD dwWriteNum = 0;
	// 將欲注入 DLL 文件的完整路徑寫入在目標(biāo)進(jìn)程中申請的空間內(nèi)
	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()函數(shù)的地址
	FARPROC pFunAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
	DWORD dwRet = 0;
	//得到第一個線程
	if (Thread32First(handleSnap, &te))
	{
		do
		{
			//進(jìn)行進(jìn)程 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);
					//關(guān)閉句柄
					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強(qiáng)力注入:

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

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

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

// 使用 ZwCreateThreadEx 實現(xiàn)遠(yuǎn)線程注入
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;

	// 打開注入進(jìn)程,獲取進(jìn)程句柄
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
	if (NULL == hProcess)
	{
		return FALSE;
	}
	// 在注入進(jìn)程中申請內(nèi)存
	dwSize = sizeof(char)+lstrlen(pDllName);
	pDllAddr = ::VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
	if (NULL == pDllAddr)
	{
		return FALSE;
	}
	// 向申請的內(nèi)存中寫入數(shù)據(jù)
	if (FALSE == ::WriteProcessMemory(hProcess, pDllAddr, pDllName, dwSize, NULL))
	{
		return FALSE;
	}
	// 加載 ntdll.dll
	HMODULE hNtdllDll = ::LoadLibrary("ntdll.dll");
	if (NULL == hNtdllDll)
	{
		return FALSE;
	}
	// 獲取LoadLibraryA函數(shù)地址
	pFuncProcAddr = ::GetProcAddress(::GetModuleHandle("Kernel32.dll"), "LoadLibraryA");
	if (NULL == pFuncProcAddr)
	{
		return FALSE;
	}
	// 獲取ZwCreateThread函數(shù)地址
#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)建遠(yuǎn)線程, 實現(xiàn) DLL 注入
	dwStatus = ZwCreateThreadEx(&hRemoteThread, PROCESS_ALL_ACCESS, NULL, hProcess, 
		(LPTHREAD_START_ROUTINE)pFuncProcAddr, pDllAddr, 0, 0, 0, 0, NULL);
	if (NULL == hRemoteThread)
	{
		return FALSE;
	}
	// 關(guān)閉句柄
	::CloseHandle(hProcess);
	::FreeLibrary(hNtdllDll);
	return TRUE;
}

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

	system("pause");
	return 0;
}

強(qiáng)制卸載進(jìn)程中的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;
}

純匯編實現(xiàn)遠(yuǎn)程Dll注入:

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

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

; 在進(jìn)程中分配空間并將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

純匯編實現(xiàn)遠(yuǎn)程代碼注入:

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

為了后期編程方便,編寫一個反轉(zhuǎn)宏Macro.inc用來翻轉(zhuǎn)參數(shù),使用定義_invoke調(diào)用更方便

; --------------------------------------------
; 翻轉(zhuǎn)參數(shù)字節(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 ?
; --------------------------------------------
; 放入導(dǎo)入函數(shù)的字符串
_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         ; 取當(dāng)前模塊句柄
		mov [ebx + _hInstance],eax
		lea eax,[ebx + offset _szDllUser]           
		_invoke [ebx + _lpGetModuleHandle],eax          ; 取user32.dll模塊句柄
		mov @hModule,eax
; --------------------------------------------
; 循環(huán)獲取每個導(dǎo)入函數(shù)的地址,并放入指針變量保存
		lea esi,[ebx + offset _szMessageBox]            ; 循環(huán)獲取,從該函數(shù)起始地址處
		lea edi,[ebx + offset _lpMessageBox]
		.while TRUE
			_invoke	[ebx + _lpGetProcAddress],@hModule,esi
			mov [edi],eax       ; 獲取到函數(shù)地址后,放入導(dǎo)入函數(shù)字符串中
			add edi,4           ; 每次遞增4字節(jié),指向下一個函數(shù),遇到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       ; 調(diào)用信息框
		ret
_RemoteThread endp

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

以上就是c++ 如何實現(xiàn)線程注入的詳細(xì)內(nèi)容,更多關(guān)于c++ 實現(xiàn)線程注入的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++編程中指針的聲明與基本使用講解

    C++編程中指針的聲明與基本使用講解

    這篇文章主要介紹了詳解C++編程中C++編程中指針的聲明與基本使用講解,文中舉了簡單的例子來講如何在基本的數(shù)據(jù)結(jié)構(gòu)中使用指針,以及固定和可變指針的介紹,需要的朋友可以參考下
    2016-01-01
  • C++中基類和派生類之間的轉(zhuǎn)換實例教程

    C++中基類和派生類之間的轉(zhuǎn)換實例教程

    這篇文章主要介紹了C++中基類和派生類之間的轉(zhuǎn)換,有助于深入理解C++面向?qū)ο蟪绦蛟O(shè)計,需要的朋友可以參考下
    2014-08-08
  • c++實現(xiàn)簡單的線程池

    c++實現(xiàn)簡單的線程池

    這里給大家介紹了C++中對于pthread線程的一個簡單應(yīng)用以及使用繼承CDoit,實現(xiàn)其中的start和end,有需要的小伙伴可以參考下
    2015-11-11
  • C++實現(xiàn)String與UF8互轉(zhuǎn)

    C++實現(xiàn)String與UF8互轉(zhuǎn)

    這篇文章介紹了C++實現(xiàn)String與UF8互轉(zhuǎn)的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C++實例分析講解臨時對象與右值引用的用法

    C++實例分析講解臨時對象與右值引用的用法

    對性能來說,許多的問題都需要和出現(xiàn)頻率及本身執(zhí)行一次的開銷掛鉤,有些問題雖然看似比較開銷較大,但是很少會執(zhí)行到,那也不會對程序有大的影響;同樣一個很小開銷的函數(shù)執(zhí)行很頻繁,同樣會對程序的執(zhí)行效率有很大影響。本章中作者主要根據(jù)臨時對象來闡述這樣一個觀點
    2022-08-08
  • 一篇文章教你自己動手實現(xiàn)C語言庫函數(shù)

    一篇文章教你自己動手實現(xiàn)C語言庫函數(shù)

    這篇文章主要介紹了C語言庫函數(shù)的相關(guān)資料,小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-09-09
  • C語言小游戲之小熊跳板功能的實現(xiàn)

    C語言小游戲之小熊跳板功能的實現(xiàn)

    這篇文章主要介紹了C語言小游戲之小熊跳板功能的實現(xiàn),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • 在C++中加載TorchScript模型的方法

    在C++中加載TorchScript模型的方法

    這篇文章主要介紹了在C++中加載TorchScript模型的方法,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • c語言打開文件函數(shù)使用方法

    c語言打開文件函數(shù)使用方法

    這篇文章主要介紹了c語言打開文件函數(shù)使用方法,需要的朋友可以參考下
    2014-02-02
  • c語言 字符串的拼接和分割實例

    c語言 字符串的拼接和分割實例

    今天小編就為大家分享一篇c語言 字符串的拼接和分割實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12

最新評論

泗水县| 望谟县| 当雄县| 中江县| 教育| 信宜市| 巴楚县| 丹巴县| 上思县| 乐山市| 平潭县| 双鸭山市| 镇沅| 察雅县| 乌兰察布市| 循化| 海城市| 廉江市| 尤溪县| 德安县| 洛宁县| 陆川县| 桂东县| 承德县| 九台市| 营口市| 措美县| 县级市| 图木舒克市| 安化县| 陕西省| 芜湖县| 嘉禾县| 怀宁县| 临泽县| 壶关县| 宣威市| 沭阳县| 环江| 白朗县| 顺平县|