zoukankan      html  css  js  c++  java
  • C++ 修改指定进程 PEB 中路径和命令行信息实现进程伪装

    背景

    所谓的进程伪装,指的修改任意一个指定进程的信息,是它的信息在系统中的显示是另一个进程的信息,这样看来,指定的进程就像是被伪装的进程一样,因为进程信息相同,但实际上,它还是原来的进程,做着原来的进程操作。

    函数介绍

    NtQueryInformationProcess

        NTSTATUS WINAPI NtQueryInformationProcess(
            _In_      HANDLE           ProcessHandle,				// 要获取信息的进程的句柄。
            _In_      PROCESSINFOCLASS ProcessInformationClass,		// 要获取的进程信息的类型
            _Out_     PVOID            ProcessInformation,			// 指向由调用应用程序提供的缓冲区的指针
            _In_      ULONG            ProcessInformationLength,	// 指向的缓冲区的大小
            _Out_opt_ PULONG           ReturnLength					// 返回所请求信息的大小
        );
    
    

    实现原理

    进程伪装的原理不是很复杂,就是修改指定进程的进程环境块 PEB 中的进程路径以及命令行信息,即可达到进程伪装的效果。

    具体实现原理分析如下:

    • 首先,我们根据进程的 PID 号打开指定进程,并获取进程的句柄。
    • 然后,我们要从 ntdll.dll 中获取 NtQueryInformationProcess 函数的导出地址,因为 NtQueryInformationProcess 函数没有关联导入库,所以只能动态获取,这个函数是这个程序功能实现的关键步骤。
    • 接着,使用 NtQueryInformationProcess 函数获取指定进程的进程基本信息 PROCESS_BASIC_INFORMATION,并从中获取指定进程的进程环境块 PEB。
    • 然后,我们就可以根据进程环境块中的 ProcessParameters,获取指定进程的 RTL_USER_PROCESS_PARAMETERS 信息,因为PEB的路径信息、命令行信息存储在这个结构体中。
    • 最后,我们开始对指定进程 PEB 中路径信息、命令行信息进行更改,实现进程伪装

    编码实现

        // 修改指定进程的进程环境块PEB中的路径和命令行信息, 实现进程伪装
        BOOL DisguiseProcess(DWORD dwProcessId, wchar_t *lpwszPath, wchar_t *lpwszCmd)
        {
            // 打开进程获取句柄
            HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
            if (NULL == hProcess)
            {
                ShowError("OpenProcess");
                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("ntdll.dll"), "NtQueryInformationProcess");
            if (NULL == NtQueryInformationProcess)
            {
                ShowError("GetProcAddress");
                return FALSE;
            }
            // 获取指定进程的基本信息
            NTSTATUS status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, &pbi, sizeof(pbi), NULL);
            if (!NT_SUCCESS(status))
            {
                ShowError("NtQueryInformationProcess");
                return FALSE;
            }
            /*
                  注意在读写其他进程的时候,注意要使用ReadProcessMemory/WriteProcessMemory进行操作,
                每个指针指向的内容都需要获取,因为指针只能指向本进程的地址空间,必须要读取到本进程空间。
                要不然一直提示位置访问错误!
            */
            // 获取指定进程进本信息结构中的PebBaseAddress
            ::ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
            // 获取指定进程环境块结构中的ProcessParameters, 注意指针指向的是指定进程空间中
            ::ReadProcessMemory(hProcess, peb.ProcessParameters, &Param, sizeof(Param), NULL);
            // 修改指定进程环境块PEB中命令行信息, 注意指针指向的是指定进程空间中
            usCmdLen = 2 + 2 * ::wcslen(lpwszCmd);
            ::WriteProcessMemory(hProcess, Param.CommandLine.Buffer, lpwszCmd, usCmdLen, NULL);
            ::WriteProcessMemory(hProcess, &Param.CommandLine.Length, &usCmdLen, sizeof(usCmdLen), NULL);
            // 修改指定进程环境块PEB中路径信息, 注意指针指向的是指定进程空间中
            usPathLen = 2 + 2 * ::wcslen(lpwszPath);
            ::WriteProcessMemory(hProcess, Param.ImagePathName.Buffer, lpwszPath, usPathLen, NULL);
            ::WriteProcessMemory(hProcess, &Param.ImagePathName.Length, &usPathLen, sizeof(usPathLen), NULL);
            return TRUE;
        }
    

    程序测试

    我们运行一个测试程序 Demon Memory.exe,先使用 Process Explorer 查看它的进程信息:在这里插入图片描述

    现在,我们运行我们的进程伪装程序,修改上述的测试程序 Demon Memory.exe 进程的PEB进程环境块信息,实现进程伪装。程序执行提示成功,我们再运行 Process Explorer 程序查看进程信息,发现测试程序 Demon Memory.exe 进程信息成功伪装了 explorer.exe 资源管理器进程。
    在这里插入图片描述

  • 相关阅读:
    Webdriver启动Firefox浏览器后,页面显示空白
    Windows+Python+Selenium基础篇之1-环境搭建
    office2010无法卸载问题
    .NET使用FastDBF读写DBF
    并发编程相关概念
    C#的多线程简洁笔记
    asp.net core 3.1 入口:Program.cs中的Main函数
    【WPF学习】第四十四章 图画
    .NET知识梳理——1.泛型Generic
    C#个推SDK推送安卓+iOS
  • 原文地址:https://www.cnblogs.com/csnd/p/15613456.html
Copyright © 2011-2022 走看看