远程代码注入,并调用相关call

目的

在目标程序远程注入代码,并执行注入的调用代码。


这是原来正常调用时弹出的消息

下图是经过了远程注入代码调用的消息

原理:将调用目标函数的代码,sellcode的形式写入到目标进程中,再远程调用写入的代码。

核心代码:

//构造的调用目标函数
void MsgCall(LPVOID lParam)
{
	DWORD moduleBase = 0;
	MessageParam* msgPara = (MessageParam*)(lParam);
	_GetModuleHandle m = (_GetModuleHandle)(*(DWORD*)(lParam));
	moduleBase = (DWORD)m(NULL);
	DWORD nameBase = msgPara->maistrBase;
	if (moduleBase)
	{
		DWORD _CALL = moduleBase + CALL_MSG_BASE;
		_asm
		{
			push nameBase
			mov eax, _CALL
			call eax
			add esp,4
		}
	}
}
//************************************************************************************** 
//函数名:InSendFunc
//功能  :封装远程注入的函数 
//参数 1:进程句柄  
//参数 2:进程ID  
//参数 3:被注入函数指针<函数名>  
//参数 4:参数  
//参数 5:参数长度  
//参数 6:注入函数地址
//参数 7:注入的参数地址
//************************************************************************************** 
void InSendFunc(HANDLE hProcess, DWORD dwProcId, LPVOID mFunc, LPVOID Param, DWORD ParamSize, LPVOID mFuncAddr, LPVOID ParamAddr)
{

	HANDLE hThread = NULL;    //线程句柄 
	DWORD NumberOfByte = NULL; //辅助返回值 
	//打开被注入的进程句柄     
	__try {

		//写内存  
		if (!WriteProcessMemory(hProcess, mFuncAddr, mFunc, 128, &NumberOfByte)) {
			__leave;
		}
		WriteProcessMemory(hProcess, ParamAddr, Param, ParamSize, &NumberOfByte);

		//创建远程线程 
		hThread = ::CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)mFuncAddr,
			ParamAddr, 0, &NumberOfByte);
		if (hThread == NULL) {
			__leave;
		}
		WaitForSingleObject(hThread, INFINITE); //等待线程结束 
		//释放申请有内存 
	}
	__finally {
		//释放远程句柄 
		if (hThread)
		{
			CloseHandle(hThread);
		}
	}
}

void CRemoteCallDemoDlg::OnBnClickedOk()
{
	UpdateData(TRUE);
	HWND hGameWnd = ::FindWindow(NULL, _T("演示DEMO"));
	if (NULL == hGameWnd)
	{
		MessageBox(_T("未找到窗口"));
		return;
	}
	DWORD dwProcessId = 0;
	DWORD dwThreadId = ::GetWindowThreadProcessId(hGameWnd, &dwProcessId);
	//获得目标进程中 LoadLibrary函数的地址
#if _UNICODE
	void(*addrRemoteLoadLibrary)(wchar_t*) = (void(*)(wchar_t*))GetProcAddress(GetModuleHandle(_T("Kernel32.dll")), "GetModuleHandleW");
#else
	void(*addrRemoteLoadLibrary)(char*) = (void(*)(char*))GetProcAddress(GetModuleHandle(_T("Kernel32.dll")), "GetModuleHandle");
#endif
	//提权
	ImproveProcPriv();
	HANDLE hProcess = INVALID_HANDLE_VALUE;
	hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, TRUE, dwProcessId);
	if (NULL == hProcess) {
		MessageBox(_T("无法打开进程"));
		return;
	}
	//先申请内存
	LPVOID mFuncAddr = NULL;//申请函数内存地址         
	LPVOID ParamAddr = NULL;//申请参数内存地址 
	LPVOID MsgConAddr = NULL;
	//申请内存  这里函数128个字节足够用了,如果以后写的调用函数更多,则这里需要加大字节数
	mFuncAddr = ::VirtualAllocEx(hProcess, NULL, 128, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	ParamAddr = ::VirtualAllocEx(hProcess, NULL, sizeof(MessageParam), MEM_COMMIT, PAGE_READWRITE);

	std::wstring strName = CString(_T("Romte CALL Test Success!"));
	//&str.c_str();
	int len = strName.length()*2 +2 ;
	//开始申请写入内容
	MsgConAddr = ::VirtualAllocEx(hProcess, NULL, len, MEM_COMMIT, PAGE_READWRITE);
	DDwrite(hProcess, MsgConAddr, strName.c_str(), strName.length()*2);
	MessageParam mailP;
	mailP.getModulBase = (DWORD)addrRemoteLoadLibrary;
	mailP.maistrBase = (DWORD)MsgConAddr;
	InSendFunc(hProcess, dwProcessId, MsgCall, &mailP, sizeof(MessageParam), mFuncAddr, ParamAddr);
	if (MsgConAddr)
	{
		::VirtualFreeEx(hProcess, MsgConAddr, len, MEM_RELEASE);
	}
	if (mFuncAddr)
	{
		::VirtualFreeEx(hProcess, mFuncAddr, 128, MEM_RELEASE);
	}
	if (ParamAddr)
	{
		::VirtualFreeEx(hProcess, ParamAddr, sizeof(MessageParam), MEM_RELEASE);
	}
	UpdateData(FALSE);
}

代码实现都是相对简单的,难点在与,如何找到目标call,并分析出目标call的调用逻辑,堆栈平衡等问题,崩溃的原因往往是堆栈不平衡造成的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值