MFC 之动态链接库编写与注入
对于一般的 dll
文件,我们可以在其他的 exe
文件中进行导入,并使用从该 dll
文件中导出的函数,同样的,MFC 程序也可以编译成动态链接库的形式。
当然我们今天讨论的主题是编写一个图形化界面的 MFC dll
,通过注入工具将该 dll
注入到其他程序,然后打开我们编写的图形化界面。
一、编写 MFC 动态链接库
首先我们需要新建一个 MFC 动态链接库
项目,并指定如下类型:
注:通过指定静态链接属性,当我们的 dll 程序可以运行在没有 mfc140.dll 的系统上。
1 新建一个窗口并与类文件绑定
此时,我们需要新建一个窗口,该窗口就是用于接收我们各种操作的窗口,右键资源文件 -> 添加 -> 资源,选择 Dialog
新建:
此时就生成了窗口,我们也可以对窗口进行各种属性的设置,如窗口标题、大小等。然后我们需要右键该新建窗口 -> 添加类,将其与类文件绑定,指定基类为 CDialog
:
CDialogEx 基类比 CDialog 基类的功能更加丰富,适用于 XP 以后的系统,而 CDialog 基类更加简单,兼容性更强,后面演示代码基于 CDialog 基类。
然后在主文件中添加刚刚新建的类头文件:
2 在 MFC 初始化函数中开启模态对话框线程
通过上面的操作新建好对话框后,我们接下来需要在 MFC 动态链接库初始化的时候开启一个线程,该线程用于启动我们刚刚创建的模态对话框,下面是 MFC 动态链接库的初始化函数:
// CMFCLibrary1App 初始化
BOOL CMFCLibrary1App::InitInstance()
{
CWinApp::InitInstance();
return TRUE;
}
注:当 DLL 被加载后会触发该函数做一些初始化工作,如窗口的创建、显示等(对应的卸载函数为 ExitInstance())。
接下来我们编写线程函数,并开启一个线程执行该函数:
// 注入 dll 后用于打开窗口的线程回调函数
CMainDialog* pCMainDialog = NULL;
DWORD WINAPI ThreadFunction(LPARAM lparam)
{
pCMainDialog = new CMainDialog();
pCMainDialog->DoModal(); // 创建模态对话框然后堵塞,等待窗口关闭后才会继续往下执行
FreeLibraryAndExitThread(theApp.m_hInstance, 1); // 释放,会触发 ExitInstance() 函数
return 0;
}
// CMFCLibrary1App 初始化
BOOL CMFCLibrary1App::InitInstance()
{
CWinApp::InitInstance();
if (!::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunction, NULL, 0, NULL))
{
MessageBoxA(NULL, "CreateThread() error", NULL, 0);
}
return TRUE;
}
二、注入 MFC dll
选择一个任意的注入软件,并选择一个任意的进程注入,效果如下:
三、调试 MFC dll
如果是需要调试 exe
文件,直接可以在 VS 编译器里面点击调试器运行即可,但是 dll
文件如何调试呢?
以调试刚刚编写的 dll
为例,我们首先打开待注入的进程,这里是 notepad.exe
,然后点击 VS 的调试 -> 附加到进程,然后找到我们待注入的进程进行附加:
此时 VS 进入调试状态,我们就可以下断点了:
然后通过注入将需要调试的 dll 注入到 VS 附加的进程中,此时已经断下:
接下来就可以和 exe
程序一样调试了。