實現dll注入到explorer進程
#include <windows.h>
#include <tlhelp32.h> // 聲明快照函數的標頭檔
#include "stdio.h"
#include "tchar.h" // _tcsrchr
// 插入dll目標進程
LPTSTR Target="iexplore.exe";
DWORD FindProcess(LPTSTR lpszProName); // 尋找進程
BOOL RemoteLoadLibrary(DWORD dwPID,LPCSTR lpszDll); // 插入進程
int main(int argc, char* argv[])
{
DWORD pid;
char dir[MAX_PATH];
GetModuleFileName(NULL,dir,sizeof(dir)); // 擷取當前模組路徑
(_tcsrchr(dir, _T('\')))[1] = 0;//刪除檔案名稱,只獲得路徑字串
strcat(dir,"injectdll.dll"); // dll路徑
pid=FindProcess(Target);
//printf("%u\n",pid);
//printf("%s\n",dir);
if(RemoteLoadLibrary(pid,(LPCSTR)dir))
{
printf("Inject Success!\n");
return 1;
}else
{
printf("Inject Failed!\n");
return 0;
}
return 1;
}
DWORD FindProcess(LPTSTR lpszProName)
{
BOOL bMore=FALSE; // 傳回值
HANDLE hSnap=NULL; // 快照控制代碼
DWORD dwPID=0; // 進程ID
PROCESSENTRY32 pe32; // 進程資訊結構
pe32.dwSize = sizeof(pe32); // 初始化進程結構大小
hSnap =CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hSnap == INVALID_HANDLE_VALUE) // Failed
{
return -1;
}
// 遍曆進程快照
bMore = Process32First(hSnap, &pe32);
while(bMore)
{
// 比較進程名,不區分大小寫
if(lstrcmpi(pe32.szExeFile,lpszProName)==0)
{
dwPID=pe32.th32ProcessID;
break;
}
bMore = Process32Next(hSnap, &pe32);
}
// 釋放快照對象
CloseHandle(hSnap);
return dwPID;
}
// 注入dll到指定進程
// 入口參數:DwPID ->進程ID值
// lpszDll->要注入的DLL路徑
// 傳回值:TRUE->Success FALSE->Failed
BOOL RemoteLoadLibrary(DWORD dwPID,LPCSTR lpszDll)
{
DWORD dwSize,dwWritten;
DWORD dwID=0;
HANDLE hThread=NULL;
LPVOID pFun=NULL;
HANDLE hPro=NULL;
LPVOID lpBuf=NULL;
hPro=OpenProcess(// 開啟進程,返回進程控制代碼
PROCESS_CREATE_THREAD // 防止和CreateRemoteThread衝突
|PROCESS_VM_OPERATION // 允許函數VirtualProtectEx使用此控制代碼修改進程的虛擬記憶體.
| PROCESS_VM_WRITE, // 允許函數訪問和寫入許可權
FALSE, // 取消傳遞性
dwPID // 指定進程ID
);
// 計算要寫入大小
dwSize=lstrlenA(lpszDll)+1;
// 在指定進程空間分配虛擬空間
lpBuf=VirtualAllocEx(
hPro, // 申請記憶體所在的進程控制代碼
NULL, // 保留頁面的記憶體位址,設定為NULL自動分配
dwSize, // 欲分配的記憶體大小
MEM_COMMIT, // 為特定的頁面地區分配記憶體中或磁碟的分頁檔中的實體儲存體
PAGE_READWRITE // 可讀寫該記憶體地區
);
if(NULL==lpBuf) // Failed
{
CloseHandle(hPro);
return FALSE;
}
// 寫入
if(WriteProcessMemory(hPro,lpBuf,(LPVOID)lpszDll,dwSize,&dwWr
itten))
{
// 判斷實際寫入大小是否與要寫入的大小一致,不想當則寫入失敗
if(dwWritten!=dwSize)
{
// 釋放分配的空間
VirtualFree(hPro,lpBuf,dwSize,MEM_DECOMMIT);
CloseHandle(hPro);
return FALSE;
}
}else // 寫入失敗
{
CloseHandle(hPro);
return FALSE;
}
pFun=LoadLibraryA;
hThread=CreateRemoteThread(
hPro, // 指定線程入駐的進程控制代碼,
NULL, // 線程的安全屬性
0, // 系統預設大小
(LPTHREAD_START_ROUTINE)pFun, // 調用LoadLibrary載入dll
lpBuf, // 線程函數其真實位址
0, // 參數
&dwID // 線程建立標誌
);
// 等待FreeLibrary卸載完畢
WaitForSingleObject(hThread,INFINITE );
CloseHandle(hThread); // 關閉線程控制代碼
CloseHandle(hPro); // 關閉進程控制代碼
return TRUE;
}