进程注入技术

 VirtualAllocEx() 介绍:

功能:在指定进程的虚拟地址空间中保留、提交或更改内存区域的状态。函数初始化分配给零的内存。

函数原型:LPVOID WINAPI VirtualAllocEx(
                  HANDLE  hProcess,  // 进程的句柄。该函数在该进程的虚拟地址空间中分配内存。
                  LPVOID  lpAddress, // 指定要分配的页面区域所需的起始地址的指针。若为 NULL,则自动分配。
                  SIZE_T  dwSize,  // 要分配的内存区域的大小。
                  DWORD  flAllocationType, // 内存分配的类型。通常为 MEM_COMMIT。
                  DWORD  flProtect  // 要分配的页区域的内存保护。
                  );

返回值:如果函数成功, 则返回值是分配的页区域的基地址。如果函数失败, 返回值为 NULL。

 

WriteProcessMemory() 介绍:

功能:将数据写入指定进程中的内存区域。

函数原型:BOOL WINAPI WriteProcessMemory(
                  HANDLE  hProcess, // 要修改的进程内存的句柄。
                  LPVOID  lpBaseAddress, // 指向指定进程中写入数据的基地址的指针。
                  LPCVOID lpBuffer, // 指向包含要在指定进程的地址空间中写入的数据的缓冲区的指针。
                  SIZE_T  nSize, // 要写入指定进程的字节数。
                  SIZE_T  *lpNumberOfBytesWritten // 指向一个变量的指针, 它接收传输到指定进程中的字节数。
                  );

返回值:非零表示成功,零表示失败。

 

VirtualProtectEx() 介绍:

功能:更改指定进程的虚拟地址空间中已提交页区域的保护。

函数原型:BOOL WINAPI VirtualProtectEx(
                  HANDLE  hProcess,  // 要更改其内存保护的进程的句柄。
                  LPVOID  lpAddress,  // 指向要更改其访问保护属性的页区域的基地址的指针。
                  SIZE_T  dwSize,   //  更改其访问保护属性的区域的大小。
                  DWORD   flNewProtect,  // 内存保护选项。
                  PDWORD  lpflOldProtect  // 一个指针, 该变量接收指定页面区域中第一页的以前访问保护。
                  );

返回值:非零表示成功,零表示失败。

 

VirtualFreeEx() 介绍:

功能:在指定的进程中释放申请的虚拟内存空间。

函数原型:LPVOID WINAPI VirtualFreeEx(
                  HANDLE  hProcess,  // 目标进程的句柄。
                  LPVOID  lpAddress, // 指定要释放的虚拟内存空间首地址的指针。
                  SIZE_T  dwSize,  // 虚拟内存空间的大小。
                  DWORD dwFreeType, // 释放内存的类型。

参数 dwFreeType:

MEM_DECOMMIT:表示内存空间不可用,内存页还将存在。

MEM_RELEASE:表示内存空间彻底回收。

返回值:非零表示成功,零表示失败。

 

DemoCode:

#include<windows.h>
#include<stdio.h>
#include<tlhelp32.h>

BOOL LoadDll(DWORD dwProcessId, LPTSTR lpszDllName);

int main(void)
{
    HANDLE hProcessSnap;
    char lpDllName[MAX_PATH] = TEXT("Dll.dll");
    PROCESSENTRY32 ProcessEntry = { 0 };
    ProcessEntry.dwSize = sizeof(PROCESSENTRY32);
    hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    BOOL bRet = Process32First(hProcessSnap, &ProcessEntry);
    while (bRet)
    {
        if (strcmp("calc.exe", ProcessEntry.szExeFile) == 0)
        {
            LoadDll(ProcessEntry.th32ProcessID, lpDllName);
            break;
        }
        bRet = Process32Next(hProcessSnap, &ProcessEntry);
    }
    return 0;
}

BOOL LoadDll(DWORD dwProcessId, LPTSTR lpszDllName)
{
    int length;
    HANDLE hProcess = NULL;
    HANDLE hThread = NULL;
    PSTR pszDllFile = NULL;
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (hProcess == NULL)
        return FALSE;
    length = 1 + strlen(lpszDllName);
    pszDllFile = (PSTR)VirtualAllocEx(hProcess, NULL, length, MEM_COMMIT, PAGE_READWRITE);
    if (pszDllFile == NULL)
        return FALSE;
    if ((WriteProcessMemory(hProcess, (PVOID)pszDllFile, (PVOID)lpszDllName, length, NULL)) == FALSE)
        return FALSE;
    PTHREAD_START_ROUTINE pfnThreadRtn = 
(PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle("kernel32"), "LoadLibraryA"); if (pfnThreadRtn == NULL) return FALSE; hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, (PVOID)pszDllFile, 0, NULL); if (hThread == NULL) { printf("%d", GetLastError()); return FALSE; } WaitForSingleObject(hThread, INFINITE); VirtualFreeEx(hProcess, (PVOID)pszDllFile, 0, MEM_RELEASE); CloseHandle(hThread); CloseHandle(hProcess); return TRUE; }

这段代码的 Dll.dll 可以用 动态链接库 那章含有 MessageBox() 的 dll 文件。

程序在我的本机 Win10(64) 上运行会注入失败,但是在虚拟机 Win7(32) 上没问题。

posted @ 2018-09-28 18:59  M-Anonymous  阅读(625)  评论(0编辑  收藏  举报