前几天看到XX老师编写的 编写Win32控制台程序 注入带窗口的DLL,的教程,闲来无事,也跟着视频教程自己动手写个,主要是代码简短,比起以往看的一些视频,代码都比较繁琐,好多都不懂,也懂得去找资料去一探究竟,本来新手一个,视频中用的VS2010.本人机器里XP只有很久之前留的一个VC6++;本以为都 一样,教程里也说装一个VC6,VC7,VC8,VC9,VC2010,VC2012,VC2013都一样,于是我就信了,就打开VC6++开始了,
>
两个确定,然后插入资源>或者
>
>
>,视频中是双击新建的窗体建立此窗体的类向导(将刚的窗体类化),而VC6++双击新建的资源窗体直接跳到代码区了,VC6++是在窗体上点右键或者点上面菜单>查看建立类向导,VS2010和VC6++出来的类向导界面也不一样,VS2010是直接输入一个类名就可以了,而VC6++
>
>
,切找到
,因为要使用这个类,先要包含这个头文件,即加上#include "MainDialogWnd.h",加上这个头文件后,主窗口的class CMainDialogWnd 这个就可以使用了,视频中MFC_DLL.cpp初化后面还有一个InitInstance()这个函数来着,可是VC6++MFC_DLL.cpp的代码到CMy_DllApp theApp;就没了,于是我就加一个函数
BOOL CMFC_DLLApp::InitInstance()
{
}
试运行,发现报错

意思大概是InitInstance:成员函数没有包括在 'CMy_DllApp',查看CMy_DllApp 声明,我想应该是视频中编译器版过高于我这个VC6++,少了好多东西,于是我就放弃了,下了2008,
界面不一样,而且类化的时候发现报错,建不了类名,虽然问题解决了,但还是卸载了,又装了2012
还有另一个版本,发现不支持32位,单位电脑XP,没有办法,只有找一个32位的VS2010,中间虽然有些小插曲,但也总是装好了,终于和视频中的一样了,在建立类向导的时候还是会报错,但可以用,重新开始了
>>>>>>>

这里会报错,看来是跟系统有关

不管错误,点是>>下面窗口点下一步>默认,点完成
把左下角的只留下这四个选项卡,多余的隐藏,没有的在菜单视图中先中,调整好四个选项卡的位置,保证和视频中一样,按视频一步步来,先左下角切换资源视图

>>>>>新建
左下角切换解决方案资源管理器,
在刚建的窗口上
点右键选添加类,或者双击
报错不管,类名和视频中一样
双击MFC_DLL.cpp终于能看到和视频中一样的代码
不错,成功就是眼前了。先添加头文件#include "MainDialogWnd.h"继续
// MFC_DLL.cpp : 定义 DLL 的初始化例程。
//
#include "stdafx.h"
#include "MFC_DLL.h"
#include "MainDialogWnd.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
//
//TODO: 如果此 DLL 相对于 MFC DLL 是动态链接的,
// 则从此 DLL 导出的任何调入
// MFC 的函数必须将 AFX_MANAGE_STATE 宏添加到
// 该函数的最前面。
//
// 例如:
//
// extern "C" BOOL PASCAL EXPORT ExportedFunction()
// {
// AFX_MANAGE_STATE(AfxGetStaticModuleState());
// // 此处为普通函数体
// }
//
// 此宏先于任何 MFC 调用
// 出现在每个函数中十分重要。这意味着
// 它必须作为函数中的第一个语句
// 出现,甚至先于所有对象变量声明,
// 这是因为它们的构造函数可能生成 MFC
// DLL 调用。
//
// 有关其他详细信息,
// 请参阅 MFC 技术说明 33 和 58。
//
// CMFC_DLLApp
BEGIN_MESSAGE_MAP(CMFC_DLLApp, CWinApp)
END_MESSAGE_MAP()
// CMFC_DLLApp 构造
CMFC_DLLApp::CMFC_DLLApp()
{
// TODO: 在此处添加构造代码,
// 将所有重要的初始化放置在 InitInstance 中
}
// 唯一的一个 CMFC_DLLApp 对象
CMFC_DLLApp theApp;
CMainDialogWnd *PMainDialog;
DWORD WINAPI ShowDialog(LPARAM lpData)
{
//添加显示窗口的代码
PMainDialog = new CMainDialogWnd;
PMainDialog->DoModal();//放到下面InitInstance()函数里会以阻塞的方式运行,就是卡住了
//关闭此窗口后
delete PMainDialog;//释放new分配的空间
FreeLibraryAndExitThread(theApp.m_hInstance,1);//释放mfc_dll.dll
return TRUE;
}
// CMFC_DLLApp 初始化
BOOL CMFC_DLLApp::InitInstance()
{
CWinApp::InitInstance();
::CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)ShowDialog,NULL,NULL,NULL);
return TRUE;
}
完整的MFC_DLL.cpp代码。其间,少个括号,大写成小写,小写成大写,少个分号之类,编译一下
嗯,不错,终于没有错误的编译成功。继续跟视频写代码,然后
>>>>>>>>>>

然后还是会报错,不管
然后直接点完成
>>>>>>>>>>>>>>>>
切换到
然后开始抄代码:
// InjectDll.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include<iostream>
using namespace std;
#define GameClassName "计算器"//定义窗口类名
#define DllName "MFC_DLL.dll"
//#define DllFullpath "D:\\我的文档\\Visual Studio 2010\\Projects\\MFC_DLL\\Debug\\MFC_DLL.dll"
void InjectDLL(HWND Gameh,const char* DllFullpath)
{
DWORD pid = 0;
DWORD byWriteSize;
HANDLE hProcess = NULL;
LPDWORD AddressDW = NULL;
HANDLE threadHandle = NULL;//存放写入线程的句柄
//查找窗口句柄
if (Gameh != 0)
{
printf("进程句柄 =%d\n",Gameh);
cout<<"进程句柄 ="<<Gameh<<endl;
//获得线程句柄
GetWindowThreadProcessId(Gameh,&pid);//获得线程句柄
if (pid != 0)
{
printf("进程PID =%d\n",pid);//这里是为了查看错误
cout<<"进程PID ="<<pid<<endl;//这里是为了查看错误
//打开线程(权限,子进程继承,进程句柄)
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);
if (hProcess != 0)
{
printf("进程hProcess =%d\n",hProcess);//这里是为了查看错误
cout<<"进程hProcess ="<<hProcess<<endl;//这里是为了查看错误
//在游戏线程分配一段空间
//访问权限(线程句柄,分配起始地址,写入字节,内存标志,页面属性)
AddressDW = (LPDWORD)VirtualAllocEx(hProcess,NULL,256,MEM_COMMIT,PAGE_READWRITE);
if (AddressDW != NULL)
{
printf("进程AddressDW =%d\n",AddressDW);//这里是为了查看错误
cout<<"进程AddressDW ="<<AddressDW<<endl;//这里是为了查看错误
//写入内存(线程,起始地址,缓冲区,字节长度,具体写入字节)
WriteProcessMemory(hProcess,AddressDW,DllFullpath,strlen(DllFullpath)+1,&byWriteSize);
if (byWriteSize >= strlen(DllFullpath))
{
threadHandle = CreateRemoteThread(hProcess,NULL,NULL,(LPTHREAD_START_ROUTINE)LoadLibrary,AddressDW,NULL,NULL);
//创建远线程(线程句柄,安全属性,初始大小,该线程函数起始地址,参数(路径),标志,返回值)
WaitForSingleObject(threadHandle,0xffffffff);//等待注入DLL的线程挺无再进行下一步
CloseHandle(threadHandle);//关闭写入线程句柄
VirtualFreeEx(hProcess,AddressDW,256,MEM_DECOMMIT);//释放远程地址空间
CloseHandle(hProcess);//关闭打开线程
}else
{
printf ("与入DLL路径失败\r\n");
}
}else
{
printf("未找到AddressDW");
}
}else
{
printf("未找到hProcess");
}
}else
{
printf("未找到pid");
}
}else
{
printf("未找到Gameh");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
char DirName[256] = "";
char DllNamePath[256] = ";";
HWND Gameh = FindWindow(NULL,GameClassName);//通过查找进程句柄,第一个参数类名,第二个参数标题名
GetCurrentDirectoryA(sizeof(DirName),DirName);
strcpy_s(DllNamePath,DirName);
strcat_s(DllNamePath,"\\");
strcat_s(DllNamePath,DllName);
printf("%s \r\n",DirName);
printf("%s \r\n",DllNamePath);
//添加注入DLL代码
printf("注入DLL\r\n");//输入一段打印信息,作为测试
InjectDLL(Gameh,DllNamePath);//调用InjectDll函数
getchar();//防止控制台窗口一闪而过,只到输入回车,窗口才会结束
return 0;
}
代码终于写完了,再
不然编译运行会报错,编译一下

激动人心的时刻到了,======未完待续======
1471


&spm=1001.2101.3001.11974&articleId=81137308&d=1&t=3&u=f959e59fe825464db20c8b5b3ee04ea9)

被折叠的 条评论
为什么被折叠?



