下面是一个简单的将mydll.dll注入到QQ中运行的例子:
#include <stdio.h> #include <stdlib.h> #include <windows.h> #include <tlhelp32.h> DWORD dwProcessID=0; HANDLE hProcessHandle=NULL; LPVOID pAddrStart=NULL; HANDLE hThreadHandle=NULL; HANDLE hDllHandle=NULL; /***************************** *函数名:GetProcessIdByName *功 能:根据进程名查找进程ID *入 参:const char*ProcessName,进程名 *出 参:无 *返回值:进程ID,失败返回-1 *****************************/ DWORD GetProcessIdByName(const char*ProcessName) { PROCESSENTRY32 stProcess; HWND hProcessShot; stProcess.dwSize=sizeof(PROCESSENTRY32); hProcessShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); Process32First(hProcessShot,&stProcess); do { if(!strcmp(ProcessName,stProcess.szExeFile)) return stProcess.th32ProcessID; }while(Process32Next(hProcessShot,&stProcess)); CloseHandle(hProcessShot); return -1; } /***************************** *函数名:dll_inject *功 能:将dll注入到指定的进程中 *入 参:const char*ProcessName,进程名 const char *pDllName,dll名 *出 参:无 *返回值:成功返回0,失败返回-1 *****************************/ int dll_inject(const char *pProcessName, const char *pDllName) { //char *pProcessName="QQ.exe"; BOOL bSuccess = FALSE; //根据进程名获取进程ID dwProcessID = GetProcessIdByName(pProcessName); if(dwProcessID == -1) { printf("%s未运行", pProcessName); return -1; } printf("%s进程ID为%d", pProcessName,dwProcessID); //根据进程ID获取进程句柄 hProcessHandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID); if(hProcessHandle == NULL) { printf("OpenProcess获取进程句柄失败\n"); return -1; } //用VirtualAllocEx在进程内申请内存 pAddrStart = VirtualAllocEx(hProcessHandle,0,1024,MEM_COMMIT,PAGE_EXECUTE_READWRITE); if (pAddrStart == NULL) { printf("进程内存申请失败!\n"); return; } printf("申请进程内存的首地址为0x%x\n",pAddrStart); //将需要运行的dll名写入申请的内存地址 bSuccess = WriteProcessMemory(hProcessHandle,pAddrStart,pDllName,1024,0); if(!bSuccess) { printf("WriteProcessMemory失败!\n"); return -1; } //printf("memory of pAddrStart is:%s",pAddrStart); //注入,即"LoadLibraryA"函数加载mydll.dll hThreadHandle = CreateRemoteThread(hProcessHandle, 0, 0, GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"),//函数LoadLibraryA的地址 pAddrStart,//mydll.dll 0, 0); if(hThreadHandle == NULL) { printf("在进程%s中注入%s失败",pProcessName,pDllName); return -1; } WaitForSingleObject(hThreadHandle,INFINITE); //到这里已经完成dll的加载即注入了,通过dll函数执行我们要完成的任务 //释放 VirtualFreeEx(hProcessHandle,pAddrStart,0,MEM_RELEASE); CloseHandle(hThreadHandle); CloseHandle(hProcessHandle); printf("Hello world!\n"); return 0; } /***************************** *函数名:dll_free *功 能:卸载注入到进程中的dll *入 参:const char*ProcessName,进程名 const char *pDllName,dll名 *出 参:无 *返回值:成功返回0,失败返回-1 *****************************/ int dll_free(const char *pProcessName, const char *pDllName) { BOOL bSuccess = FALSE; //根据进程名获取进程ID dwProcessID = GetProcessIdByName(pProcessName); if(dwProcessID == -1) { printf("%s未运行", pProcessName); return -1; } printf("%s进程ID为%d", pProcessName,dwProcessID); //根据进程ID获取进程句柄 hProcessHandle = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessID); if(hProcessHandle == NULL) { printf("OpenProcess获取进程句柄失败\n"); return -1; } //用VirtualAllocEx在进程内申请内存 pAddrStart = VirtualAllocEx(hProcessHandle,0,1024,MEM_COMMIT,PAGE_EXECUTE_READWRITE); if (pAddrStart == NULL) { printf("进程内存申请失败!\n"); return; } printf("申请进程内存的首地址为0x%x\n",pAddrStart); //将需要运行的dll名写入申请的内存地址 bSuccess = WriteProcessMemory(hProcessHandle,pAddrStart,pDllName,1024,0); if(!bSuccess) { printf("WriteProcessMemory失败!\n"); return -1; } //注入,即GetModuleHandleA函数获取mydll.dll的实例,目的是为了后面的通过GetExitCodeThread获得mydll.dll的句柄,最后执行FreeLibrary hThreadHandle = CreateRemoteThread(hProcessHandle, 0, 0, GetProcAddress(GetModuleHandle("kernel32.dll"),"GetModuleHandleA"),//函数GetModuleHandleA的地址 pAddrStart,//mydll.dll 0, 0); //用GetExitCodeThread取出dll句柄 WaitForSingleObject(hThreadHandle,INFINITE); GetExitCodeThread(hThreadHandle,&hDllHandle); //把FreeLibrary注入到进程,释放注入的DLL hThreadHandle=CreateRemoteThread(hProcessHandle, 0, 0, GetProcAddress(GetModuleHandle("kernel32.dll"),"FreeLibrary"), hDllHandle, 0, 0); //释放 WaitForSingleObject(hThreadHandle,INFINITE); VirtualFreeEx(hProcessHandle,pAddrStart,0,MEM_RELEASE); CloseHandle(hThreadHandle); CloseHandle(hProcessHandle); return 0; } int main() { //将mydll.dll注入到QQ中 dll_inject("QQ.exe","mydll.dll"); //卸载注入的dll dll_free("QQ.exe","mydll.dll"); printf("Hello world!\n"); return 0; }
上面完成了将dll注入进程,下面是要注入的dll的实现,其实就是一个普通的dll:
#include "main.h" // a sample exported function void DLL_EXPORT SomeFunction(const LPCSTR sometext) { MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION); } extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: // attach to process // return FALSE to fail DLL load MessageBoxA(0, "I am a dll!", "DLL Message", MB_OK | MB_ICONINFORMATION); break; case DLL_PROCESS_DETACH: // detach from process break; case DLL_THREAD_ATTACH: // attach to thread break; case DLL_THREAD_DETACH: // detach from thread break; } return TRUE; // succesful }
微信
支付宝