我的编程空间,编程开发者的网络收藏夹
学习永远不晚

c++ 如何实现线程注入

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

c++ 如何实现线程注入

简单编写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:
		// 进程被加载后执行
		break;
	case DLL_THREAD_ATTACH:
		// 线程被创建后加载
		break;
	case DLL_THREAD_DETACH:
		// 正常退出执行的代码
		break;
	case DLL_PROCESS_DETACH:
		// 进程卸载本Dll后执行的代码
		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系统中提供的CreateRemoteThread()这个API函数,该函数第四个参数是准备运行的线程,我们将LoadLibrary()函数填入其中,这样就可以执行远程进程中的LoadLibrary()函数,进而将我们自己准备的DLL加载到远程进程空间中执行,DLL在被装载后则会自动执行初始化部分,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 创建远线程, 实现 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()来加载动态链接库,我们只需要在上面代码的基础上稍加改进就可以实现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 创建远线程, 实现 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);
}

实现全局消息钩子注入:

该注入的原理是利用系统中的SetWindowHookEx()这个API函数,该函数可以拦截目标进程的消息到指定DLL中的导出函数上,利用这个特性,我们可以将DLL注入到全局进程中,但是在使用SetWindowsHookEx()之前首先需要将HOOK的DLL加载到本身的进程中,以此得到DLL的模块句柄,再使用GetProcAddress()得到DLL中公开的函数地址,最后遍历出待注入进程的线程ID,这样SetWindowHookEx()就可以利用这些参数进行HOOK了.

我们先来编写DLL文件,创建Dll工程hook.cpp然后将SetHook()函数导出,由于该注入方式是全局注入,所以如果我们想要注入到指定进程中,则需要在DllMain()也就是动态链接库开头位置进行判断,如果是我们需要Hook的进程,则加载Dll到指定进程中,如果不是则不执行任何操作,这样一来即可实现指定进程注入.


#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链中的函数将有机会执行被执行,每一个线程都具有一个APC链,那么只要在可以在APC链中添加一个APC,就可以完成我们所需要的DLL注入的功能.

1.将需要加载的DLL的完整路径写入目标进程空间.
2.获得LoadLibraryA()函数的地址,当然也可以是LoadLibraryW()函数的地址.
3.枚举目标进程中的所有线程,为每个线程添加一个APC函数,这样增加了注入成功的机会.

该注入的原理是利用当线程被唤醒时APC中的注册函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入的

目的,通过APC注入的流程步骤大致如下

1.当EXE里某个线程执行到SleepEx()或者WaitForSingleObjectEx()时,系统就会产生一个软中断.
2.当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数.
3.利用QueueUserAPC()这个API可以在软中断时向线程的APC队列插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的,不论如何目标程序必须有执行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);
				}
			}
			//循环下一个线程
		} 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()这个函数来完成线程注入,此方式可以注入普通的进程,但却无法注入到系统进程中,因为系统进程是处在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 创建远线程, 实现 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文件名拷贝过去,然后创建一个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调用更方便


; --------------------------------------------
; 翻转参数字节序
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
; --------------------------------------------
; 创建类似于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 ?

; --------------------------------------------
; 存放静态资源,比如常量,字符串等.
_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
; --------------------------------------------
; 循环获取每个导入函数的地址,并放入指针变量保存
		lea esi,[ebx + offset _szMessageBox]            ; 循环获取,从该函数起始地址处
		lea edi,[ebx + offset _lpMessageBox]
		.while TRUE
			_invoke	[ebx + _lpGetProcAddress],@hModule,esi
			mov [edi],eax       ; 获取到函数地址后,放入导入函数字符串中
			add edi,4           ; 每次递增4字节,指向下一个函数,遇到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++ 实现线程注入的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

c++ 如何实现线程注入

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C#中如何实现依赖注入

在C#中实现依赖注入通常可以使用一些现成的框架,比如ASP.NET Core中自带的依赖注入容器。以下是一个简单的示例:首先,定义一个接口和一个实现该接口的类:public interface IMyService{void DoSo
C#中如何实现依赖注入
2024-04-03

C#中如何实现多线程

在C#中实现多线程可以使用Thread类或Task类。以下是两种常用的实现方式:使用Thread类:using System;using System.Threading;class Program{static void Main()
C#中如何实现多线程
2024-04-03

Linux如何实现C线程池

这篇文章主要介绍了Linux如何实现C线程池,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。多线程编程,创建一个线程,指定去完成某一个任务,等待线程的退出。虽然能够满足编程需求
2023-06-28

Linux中如何实现C线程池

这篇文章主要为大家展示了“Linux中如何实现C线程池”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Linux中如何实现C线程池”这篇文章吧。Linux C线程池三个文件 1 tpool.hty
2023-06-09

C++ DLL注入怎么实现

这篇文章主要介绍“C++ DLL注入怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C++ DLL注入怎么实现”文章能帮助大家解决问题。先上源码:#include "Inject_Main.h
2023-06-29

如何使用 C++ 函数实现多线程编程?

如何使用 c++++ 函数实现多线程编程?创建一个带有可调用对象的 std::thread 对象。调用 join() 函数等待线程完成。使用互斥量、条件变量和信号量等线程同步技术来确保共享资源的访问安全。在实战案例中,您可以创建线程来并行处
如何使用 C++ 函数实现多线程编程?
2024-04-26

C#如何实现Excel导入

小编给大家分享一下C#如何实现Excel导入,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!C# Excel导入有以下几点需要我们注意:1.C# Excel导入只能
2023-06-18

Java如何实现多线程、线程同步

这篇文章主要介绍了Java如何实现多线程、线程同步的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java如何实现多线程、线程同步文章都会有所收获,下面我们一起来看看吧。1 多线程1.1 进程进程:是正在运行的程
2023-06-30

java如何实现多线程

Java多线程是Java高级特性之一,通过多线程,我们可以实现多任务同时协同工作,在一定情况下提升程序效率,但是Java多线程仍要慎重使用。 (推荐学习:java课程)首先第一点,Java多线程需要较高的编码技巧,一旦使用不当就会造成程
java如何实现多线程
2019-06-27

PHP 多线程如何实现?

php 多线程是指在一个进程中同时运行多个任务,通过创建独立运行的线程实现。php 中可以使用 pthreads 扩展模拟多线程行为,安装后可使用 thread 类创建和启动线程。例如,在处理大量数据时,可将数据分割为多个块,创建对应数量的
PHP 多线程如何实现?
2024-05-06

redis如何实现多线程

redis 通过巧妙地结合 reactor 模式、线程池和内部多线程机制实现了多线程,从而有效利用多核 cpu,提高吞吐量、优化资源利用,保持低延迟并增强扩展性,满足不同负载需求。Redis 多线程实现Redis 是一个高性能的键值数据库
redis如何实现多线程
2024-06-12

java多线程如何实现

java实现多线程的方法:(推荐:java视频教程)方式一:继承Thread类的方式1、创建一个继承于Thread类的子类2、重写Thread类中的run():将此线程要执行的操作声明在run()3、创建Thread的子类的对象4、调用此对象的start():
java多线程如何实现
2022-02-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录