65.9K
CodeProject 正在变化。 阅读更多。
Home

将我的 DLL 注入进程

starIconstarIconstarIconstarIconstarIcon

5.00/5 (8投票s)

2009年7月25日

CPOL

3分钟阅读

viewsIcon

41366

downloadIcon

903

一个 Windows Mobile 间谍程序。

InjectDLLIntoProcess/main.JPG

引言

有时,我们需要在另一个模块中运行代码,而没有源代码,例如 Microsoft Word、Microsoft Excel 或任何其他模块。 如何才能做到这一点? 在这种情况下,如果您的经理要求您更改 Microsoft 进程中的样式对话框,您该怎么办?

Using the Code

首先,我们必须谈谈内核模式。 内核模式意味着您如何访问系统中任何进程的内部,例如内核系统进程。

因此,为了拥有这种能力,coredll.dll 中有一些未公开的函数,例如:

extern "C" {
	BOOL    SetKMode(BOOL fMode);
	DWORD   SetProcPermissions(DWORD);
	LPVOID  MapPtrToProcess (LPVOID lpv, HANDLE hProc);
	DWORD   PerformCallBack4(PCALLBACKINFO pcbi, ...);	//execute function 
							//inside process
}

前两个函数让您可以访问其他进程

BOOL bMode = SetKMode(TRUE);
DWORD dwPerm = SetProcPermissions(0xFFFFFFFF);

想象一下您自己在 note.exe 内部,并且您想要加载任何 DLL。 您肯定会调用 LoadLibrary(L”xxx.dll”);

但是,如果您想加载库但没有源代码,则应使用 performcallback 函数

HANDLE hProcess=GetProcessHandle(L"notes.exe");//get handle
/***************************************************************************
Now I will put my DLL into the present process and you can
function inside this DLL.
**************************************************************************/
CALLBACKINFO cbi;
cbi.hProc = hProcess;
cbi.pfn = (FARPROC)MapPtrToProcess(GetProcAddress
	(GetModuleHandle(L"COREDLL"), L"LoadLibraryW"), hProcess);
cbi.pvArg0 = (LPVOID)MapPtrToProcess(L"\\windows\\mydll.dll", GetCurrentProcess());
HINSTANCE hInst = (HINSTANCE)PerformCallBack4(&cbi, 0,0,0);

第一个语句只是为了获取特定进程的句柄。 现在,您可以通过发送句柄和要复制到进程地址空间中的 DLL 来调用 CallBack 函数……

注意:有时 PerformCallBack 效果不佳。 "小心。"

要检查 mydll.dll 现在是否附加在 note.exe 中,请转到远程进程视图。

InjectDLLIntoProcess/img_small.JPG

现在您的 DLL 已附加到 note.exe 中,因此我现在的任务是对编辑控件进行子类化。 要获取句柄,我必须打开 note.exe 并打开像这样的 RemoteSpy 工具

spy_small.JPG - Click to enlarge image

以编程方式获取此句柄

/***********to execute your function *********************/
HWND m_hWnd=::GetForegroundWindow();//handle for note
m_hWnd=::GetWindow(m_hWnd,GW_CHILD);//handle for InkX
m_hWnd=::GetWindow(m_hWnd,GW_CHILD);//handle for richink
cbi.hProc = hProcess;
cbi.pfn = (FARPROC)MapPtrToProcess(GetProcAddress
	(hInst, L"SubClassEdit"), hProcess);//my function inside DLL
cbi.pvArg0 = m_hWnd;//handle of richedit control
hInst = (HINSTANCE)PerformCallBack4(&cbi, 0,0,0);

如果您确定“note”是其前台窗口,请调用 GetForegroundWindow() 函数,否则我建议使用 FindWindow(L"Worker","Note") 来获取窗口句柄,以获取有关 FindWindow 函数的更多信息。

现在您可以跳转到 note.exe 中的任何特定控件,在本例中,我们需要使用 getwindow 函数进入“richink”。

不要忘记在调用回调函数之前检查句柄是否正确。

让我谈谈回调函数参数

  1. hProc:特定进程的句柄,在本例中,我们谈论的是 note.exe
  2. pFn:此进程内部的函数,我们要调用
  3. pvArg0:函数参数,SubClassEdit 函数接受句柄 m_hWnd
_declspec(dllexport) void SubClassEdit(HWND m_editHandle)

查看 mydll.dll 内部

现在让我们谈谈 mydll.dll。 它非常简单。 只有一个用于子类化的函数,如下所示

__declspec(dllexport) void SubClassEdit(HWND m_editHandle)
{
	g_pOldWndProc = (WNDPROC)GetWindowLong(m_editHandle, GWL_WNDPROC);
	SetWindowLong(m_editHandle, GWL_WNDPROC, (LONG)EditTopmostProc);
}
LRESULT EditTopmostProc(HWND hWnd, UINT uMsgs, WPARAM wParam, LPARAM lParam)
{
		if ( uMsgs == WM_KILLFOCUS )//
		{
			GetWindowText(hWnd,buffer,1025);
			MessageBox(hWnd,buffer,L"you saved",MB_OK);
			/***********************************************************/
			 return CallWindowProc(g_pOldWndProc, hWnd, 
					uMsgs, wParam, lParam); //Info
		}
		 return CallWindowProc(g_pOldWndProc, 
					hWnd, uMsgs, wParam, lParam); //Info
}

在 SubClass 理论中,您应该获取并保存旧的过程句柄以使用它。

g_pOldWndProc = (WNDPROC)GetWindowLong(m_editHandle, GWL_WNDPROC);

g_pOldWndProc 现在具有 richink 过程的原始指针。

现在您可以设置您的过程而不是原始过程

SetWindowLong(m_editHandle, GWL_WNDPROC, (LONG)EditTopmostProc);

EditTopmostProc 中,我想替换 WM_KILLFOCUS,否则我将调用原始的。

CallWindowProc(g_pOldWndProc, hWnd, uMsgs, wParam, lParam); //Info

当然,您可以替换任何功能...

InjectDLLIntoProcess/note.JPG

...然后单击“确定”。

InjectDLLIntoProcess/exit.JPG

关注点

在此示例中,您可以了解子类化。 子类化是一种允许应用程序拦截发送到另一个窗口的消息的技术。 应用程序可以通过拦截发往另一个窗口的消息来增强、监视或修改窗口的默认行为。 子类化是一种在不重新开发窗口的情况下更改或扩展窗口行为的有效方法。 对默认控件窗口类(按钮控件、编辑控件、列表控件、组合框控件、静态控件和滚动条控件)进行子类化是获得控件功能并修改其行为的便捷方法。 例如,如果对话框中包含多行编辑控件,并且用户按下 ENTER 键,则对话框将关闭。 通过对编辑控件进行子类化,应用程序可以让编辑控件在文本中插入回车符和换行符,而无需退出对话框。 编辑控件不必专门针对应用程序的需求而开发。

您还可以了解 PerformCallBack,这是一种 Microsoft 技术,用于在另一个进程中执行代码。

这对其他人有什么帮助

如果有人想要在外部进程中创建自定义控件,例如在某些可编辑控件中添加从右到左的功能,则可以使用它。

历史

  • 2009 年 7 月 25 日:初始发布
© . All rights reserved.