天天看点

隐藏技术之进程伪装

// 简单的进程伪装就是修改进程名称,比如svchost.exe、services.exe等系统进程。
// 高级的进程伪装就是修改进程的PEB数据,也就是在任务管理器中看到的进程的名称、启动路径等信息。

// NtQueryInformationProcess函数
// 作用:获取指定进程的信息。
// 原型:NSTATUS WINAPI NtQueryInformationProcess(
//        _In_ HANLDE hProcess;
//        _In_ PROCESSINFOCLASS ProcessInformationClass,
//        _Out_ PVOID ProcesInformation,
//        _In_ ULONG ProcessInformationLength,
//        _Out_opt_ PULONG ReturnLength      
//      )
// 参数:hProcess:进程句柄,由OpenProcess函数获取。
//       ProcessInformationClass:进程信息的类型,为以下枚举值之一:
//          ProcessBasicInformation:检索指向PEB结构的指针。
//          ProcessDebugPort:获取作为进程调试器端口号的DWORD_PTR值。
//          ProcessWow64Information:确定进程是否在Wow64环境中运行。
//          ProcessImageFileName:检索包含该进程映像文件名称的UNICODE_STRING值。
//          ProcessBreakOnTermination:检索指示进程是否被视为关键的ULONG值。
//          ProcessSubsystemInformation:检索指示进程子系统类别的SUBSYSTEM_INFORMATION_TYPE值。
//       ProcessInformation:接收值,
//       ProcessInformationLength:指定接收数据缓冲区的大小。
//       ReturnLength:接收返回所请求信息的大小。
// 结果:返回一个NTSTATUS成功或错误代码。

// PROCESS_BASIC_INFORMATION结构体
// 定义: typedef struct _PROCESS_BASIC_INFORMATION {
//           PVOID Reserved1;
//           PPEB PebBaseAddress,
//           PVOID Reserved2[2];
//           ULONG_PTR UniqueProcessId;
//           PVOID Reserved3;
//        } PROCESS_BASIC_INFORMATION;
// 参数:PebBaseAddress成员指向PEB结构。

// 实现原理:就是修改指定进程环境块(PEB)中的进程路径以及命令行信息,从而达到进程伪装的效果。

// PS:NtQueryInformationProcess这个函数不是公开的,需要从ntdll.dll中获取函数地址。

// 示例代码:

BOOL DisguiseProcess(DWORD dwProcessId, wchar_t* lpwszPath, wchar_t* lpwszCmd)
{
    // 打开进程,获取进程句柄
    HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (NLL == 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 = ::GetProcAddress(::LoadLibrary("ntdll.dll"), "NtQueryInformationProcess");
    if (NULL == NtQueryInformationProcess)
    {
        ShowError("GetProcAddress");
        return FALSE;
    }

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

    // 获取指定进程基本信息结构中的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;
}




           

继续阅读