// Project1.cpp : 定义应用程序的入口点。
//
#include "framework.h"
#include "Project1.h"
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
HWND hWnd = ::FindWindow(_T("Notepad"), NULL);//获取与指定窗口类名和窗口名的最顶层窗口的窗口句柄
//寻找 记事本 进程
if (!hWnd) {
MessageBox(NULL,_T("请打开语音计算器"),NULL,NULL);
ExitProcess(0);
}
unsigned long pid;
::GetWindowThreadProcessId(hWnd, &pid);//获取指定进程的进程ID
/*
参数:HANDLE Process 进程的句柄
句柄必须具有PROCESS_QUERY_INFORMATION或PROCESS_QUERY_LIMITED_INFORMATION访问权限
返回值:如果函数成功,则返回值为进程标识符
如果函数失败,则返回值为零
*/
if(pid ==0){
MessageBox(NULL, _T("语音计算器进程ID获取失败"), NULL, NULL);
ExitProcess(0);
}
BOOL b=Inject(_T("D:\\bb\\MFCdll\\Debug\\MFCdll.dll"), pid);//调用函数
return 0;
}
BOOL Inject(LPCTSTR szModule, DWORD dwID) { //在目标进程中装载dll
HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION |PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD |PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION, FALSE, dwID);
if (!process) {
MessageBox(NULL, _T("进程权限获取失败"), NULL, NULL);
return FALSE;
}
int cByte = (_tcslen(szModule)+1)*sizeof(TCHAR);
//dll路径的字节数
LPVOID pAddr = VirtualAllocEx(process,NULL, cByte, MEM_COMMIT, PAGE_READWRITE);
if (!pAddr || !WriteProcessMemory(process, pAddr, szModule, cByte,NULL)) {
MessageBox(NULL, _T("路径写入失败"), NULL, NULL);
return FALSE;
}
PTHREAD_START_ROUTINE pfnStartAddr =(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW");
//获取Kernel32动态链接库中LoadLibraryW函数的地址
if (!pfnStartAddr) {
MessageBox(NULL, _T("LoadLibraryW函数地址获取失败"), NULL, NULL);
return FALSE;
}
DWORD dwThreadID = 0;
HANDLE hRemoteThread = CreateRemoteThread(process,NULL,0, pfnStartAddr, pAddr,0,&dwThreadID);//创建远程线程
/*
【在目标进程中装载dll】
参数1:HANDLE hProcess 线程所属进程的进程句柄
该句柄必须具有 PROCESS_CREATE_THREAD, PROCESS_QUERY_INFORMATION, PROCESS_VM_OPERATION, PROCESS_VM_WRITE,和PROCESS_VM_READ 访问权限
参数2:LPSECURITY_ATTRIBUTES lpThreadAttributes 一个指向 SECURITY_ATTRIBUTES 结构的指针, 该结构指定了线程的安全属性
参数3:SIZE_T dwStackSize 线程栈初始大小,以字节为单位,如果该值设为0,那么使用系统默认大小
参数4:LPTHREAD_START_ROUTINE lpStartAddress 在远程进程的地址空间中,该线程的线程函数的起始地址
参数5:LPVOID lpParameter 传给线程函数的参数
参数6:DWORD dwCreationFlags 线程的创建标志
0 线程创建后立即运行
CREATE_SUSPENDED=0x00000004 线程创建后先将线程挂起,直到 ResumeThread 被调用
STACK_SIZE_PARAM_IS_A_RESERVATION=0x00010000 dwStackSize 参数指定为线程栈预订大小,如果STACK_SIZE_PARAM_IS_A_RESERVATION没有被指定,dwStackSize 参数指定为线程栈分配大小.
参数7:LPDWORD lpThreadId 指向新创建线程ID的指针,如果创建失败,该参数为NULL
返回值:成功返回新线程句柄,失败返回NULL
*/
if (!hRemoteThread) {
MessageBox(NULL, _T("远程线程创建失败"), NULL, NULL);
return FALSE;
}
CloseHandle(hRemoteThread);
CloseHandle(process);
return TRUE;
}