Inject集合----远程线程注入(NtCreateThreadEx)

介绍:

前面写过一片远程线程注入的文章,用到的是CreateRemoteThread函数来远程注入线程的,这次我们用NtCreateThreadEx来创建远程线程,其实并没有技术的升级,而是进行了创建远程线程函数的升级,下面是CreateRemoteThread在Reactos中的源码

    /* Create the Kernel Thread Object */
    Status = NtCreateThread(&hThread,
                            THREAD_ALL_ACCESS,
                            ObjectAttributes,
                            hProcess,
                            &ClientId,
                            &Context,
                            &InitialTeb,
                            TRUE);

 

可以发现CreaeteRemoteThread函数实现中调用了 NtCreateThread函数的,但我们这篇文章是使用NtCreateThreadEx 一个未公开的函数,使用方法和 CreaeteRemoteThread类似。

步骤:

  • 获取进程ID        __NtQuerySystemInformation
  • 打开进程,获取进程句柄  SeEnableSeDebugPrivilege OpenProcess
  • 在目标进程中申请内存空间 VirtualAllocEx
  • 在目标进程中写入DLL完整路径 WriteProcessMemory
  • 从Ntdll中获取NtCreateThreadEx地址,从Kernel32中获取LoadLibraryA/W地址
  • 调用NtCreateThreadEx创建远程线程

 代码:

获取进程ID

https://blog.csdn.net/qq_42021840/article/details/106137368

 打开进程,获取进程句柄

https://blog.csdn.net/qq_42021840/article/details/106137834

在目标进程中申请内存空间

	ULONG BufferLength = 0;
	//在目标进程空间中申请内存
	BufferLength = (_tcslen(BufferData) + 1) * sizeof(TCHAR);
	//目标进程空间中申请内存
	VirtualAddress = VirtualAllocEx(ProcessHandle, NULL, BufferLength, MEM_COMMIT, PAGE_READWRITE);

在目标进程中写入DLL完整路径

 

ProcessMemoryWriteSafe(ProcessHandle, VirtualAddress, BufferData, BufferLength, &ReturnLength)


BOOL ProcessMemoryWriteSafe(HANDLE ProcessHandle, LPVOID VirtualAddress, LPCVOID BufferData, SIZE_T BufferLength, SIZE_T* ReturnLength)
	{
		SIZE_T  v1 = 0;
		SIZE_T* v2 = 0;
		int    LastError = 0;
		DWORD  OldProtect = 0;
		BOOL   IsOk = FALSE;
		if ((ProcessHandle == 0) || (VirtualAddress == 0) || (BufferData == 0) || (BufferLength == 0))
		{

			LastError = ERROR_INVALID_PARAMETER;
			goto Exit;
		}
		if (!ReturnLength)
		{
			v2 = &v1;
		}
		else
		{
			v2 = ReturnLength;
		}

		if (!WriteProcessMemory(ProcessHandle, VirtualAddress, BufferData, BufferLength, v2))
			/*BOOL WriteProcessMemory(  ****函数能写入某一进程的内存区域
				HANDLE hProcess,       由OpenProcess返回的进程句柄。如参数传数据为 INVALID_HANDLE_VALUE 【即-1】目标进程为自身进程
				LPVOID lpBaseAddress,  要写的内存首地址 再写入之前,此函数将先检查目标地址是否可用,并能容纳待写入的数据
				LPVOID lpBuffer,       指向要写的数据的指针。
				DWORD nSize,           要写入的字节数。
				LPDWORD lpNumberOfBytesWritten  实际数据的长度
			);*/
		{
			if (VirtualProtectEx(ProcessHandle, VirtualAddress, BufferLength, PAGE_EXECUTE_READWRITE, &OldProtect))
			{
				if (WriteProcessMemory(ProcessHandle, VirtualAddress, BufferData, BufferLength, v2))
				{
					IsOk = TRUE;
				}
				else
				{
					LastError = GetLastError();
				}
				VirtualProtectEx(ProcessHandle, VirtualAddress, BufferLength, OldProtect, &OldProtect);
			}
			else
			{
				LastError = GetLastError();
			}
		}
		else
		{
			IsOk = TRUE;
		}
	Exit:

		SetLastError(LastError);
		return IsOk;
	}
	

从Ntdll中获取NtCreateThreadEx地址,从Kernel32中获取LoadLibraryA/W地址

	//当前exe模块中没有该函数导入
	__NtCreateThreadEx = (LPFN_NTCREATETHREADEX)GetProcAddress(NtdllModuleBase,
		"NtCreateThreadEx");

	if (__NtCreateThreadEx == NULL)
	{
		goto Exit;
	}

	//使用Kernel32模块中的导出函数地址  Anti(IAThook)

#ifdef UNICODE
	__LoadLibrary = (LPFN_LOADLIBRARYW)GetProcAddress(Kernel32ModuleBase, "LoadLibraryW");
#else
	__LoadLibrary = (LPFN_LOADLIBRARYA)GetProcAddress(Kernel32ModuleBase, "LoadLibraryA");
#endif

 

调用NtCreateThreadEx创建远程线程

//再目标进程中启动一个线程
	HANDLE ThreadHandle = INVALID_HANDLE_VALUE;
	IsOk = __NtCreateThreadEx(&ThreadHandle,
		THREAD_ALL_ACCESS, NULL, ProcessHandle, (LPTHREAD_START_ROUTINE)__LoadLibrary, VirtualAddress,
		FALSE, NULL, NULL, NULL, NULL);

WaitForSingleObject(ThreadHandle, INFINITE);

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值