进程伪装

实现原理:

  修改进程环境块中的进程路径以及命令行信息,从而达到进程伪装的效果。所以,实现的关键在于进程环境块的获取。可以通过ntdll.dll中的导出函数NtQueryInformationProcess来获取指定进程的PEB地址。因为该程序进程可能与目标进程并不在同一个进程内。由于进程空间独立性的缘故,所以需要通过调用WIN32 API函数ReadProcessMemory和WriteProcessMemory来读写目标进程内存。

实现过程:

  (1).打开指定进程,获取进程句柄

  (2).从ntdll.dll中获取NtQueryInformationProcess函数的导出地址

  (3).使用NtQueryInformationProcess函数获取指定的进程基本信息 PROCESS_BASIC_INFORMATION,并从中获取指定进程的PEB

  (4).使用WriteProcessMemory修改PEB中的路径信息、命令行信息

  注意:NtQueryInformationProcess函数没有关联导入库,所以只能动态获取

实现代码:

    //************************************
    // 函数名:CHideDlg::DisguiseProcess
    // 返回类型:BOOL
    // 功能:    修改指定PEB中的路径和命令行信息, 实现进程伪装
    // 参数1:DWORD dwProcessId 需要伪装的程序的PID
    // 参数2:wchar_t *lpwszPath 伪装之后程序的路径
    //************************************
BOOL CHideDlg::DisguiseProcess(DWORD dwProcessId, wchar_t *lpwszPath)
{
    // 打开进程获取句柄
    HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (NULL == hProcess)
    {
        MessageBox(_T("打开进程失败!"));
        return FALSE;
    }

    //定义函数指针变量
    typedef_NtQueryInformationProcess NtQueryInformationProcess = NULL;
    PROCESS_BASIC_INFORMATION pbi = { 0 };
    PEB peb = { 0 };
    RTL_USER_PROCESS_PARAMETERS Param = { 0 };
    USHORT usCmdLen = 0;
    USHORT usPathLen = 0;

    // 需要通过 LoadLibrary、GetProcessAddress 从 ntdll.dll 中获取地址
    NtQueryInformationProcess = (typedef_NtQueryInformationProcess)::GetProcAddress(
        ::LoadLibrary(_T("ntdll.dll")), "NtQueryInformationProcess");
    if (NULL == NtQueryInformationProcess)
    {
        MessageBox(_T("获取NtQueryInformationProcess函数地址失败!"));
        return FALSE;
    }

    // 获取指定进程的基本信息
    NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
    if (!NT_SUCCESS(status))
    {
        MessageBox(_T("获取进程的基本信息失败!"));
        return FALSE;
    }

    // 获取指定进程基本信息结构中的PebBaseAddress
    //::ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
    // 获取指定进程环境块结构中的ProcessParameters, 注意指针指向的是指定进程空间
    //::ReadProcessMemory(hProcess, peb.ProcessParameters, &Param, sizeof(Param), NULL);

    // 修改指定PEB中的路径信息, 注意指针指向的是指定进程空间
    usPathLen = 2 + 2 * ::wcslen(lpwszPath);
    ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->ImagePathName.Buffer, &lpwszPath, sizeof(PWSTR), NULL);
    ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->ImagePathName.Length, &usPathLen, sizeof(usPathLen), NULL);
    ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->ImagePathName.MaximumLength, &usPathLen, sizeof(usPathLen), NULL);

    // 修改指定PEB中的命令行信息, 注意指针指向的是指定进程空间
    //usCmdLen = 2 + 2 * ::wcslen(lpwszPath);    
    ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->CommandLine.Buffer, &lpwszPath,sizeof(PWSTR), NULL);
    ::WriteProcessMemory(hProcess, &pbi.PebBaseAddress->ProcessParameters->CommandLine.Length, &usPathLen, sizeof(usPathLen), NULL);


    return TRUE;
}
原文地址:https://www.cnblogs.com/ndyxb/p/12905175.html