使用NtQueryInformationProcess伪装进程

 

背景

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

实现原理

具体实现原理如下:

(1)首先通过OpenProcess函数获取指定PID进程的句柄

(2)然后,通过GetProcAddress获取位于ntdll.dll动态链接库中的NtQueryInformationProcess这个未导出的API

该函数返回一个NTSTATUS状态码

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

获取环境块PEB需要用到ReadProcessMemory函数,因为我们是要去其他进程空间找相关数据

(4)最后,我们开始对指定进程 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;
}

测试代码 

int _tmain(int argc, _TCHAR* argv[])
{
	if (FALSE == DisguiseProcess(4368, L"C:\\Windows\\explorer.exe", L"explorer.exe"))
	{
		printf("Dsisguise Process Error.\n");
	}
	printf("Dsisguise Process OK.\n");

	system("pause");
	return 0;
}

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
代码完全远程。 可以在XP WIN7 WIN764 WIN2003 等操作系统上成功实现修改进程路径。 已经封装成类,使用及其方便。 部分代码: 头文件: #ifndef ModifyProcessPath_h__ #define ModifyProcessPath_h__ // 结构定义 typedef struct _PROCESS_BASIC_INFORMATION { DWORD ExitStatus; ULONG PebBaseAddress; ULONG AffinityMask; LONG BasePriority; ULONG UniqueProcessId; ULONG InheritedFromUniqueProcessId; } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION; // API声明 typedef LONG (__stdcall *PZWQUERYINFORMATIONPROCESS) ( HANDLE ProcessHandle, ULONG ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength ); class CModifyProcessPath { public: CModifyProcessPath(); BOOL Create(); BOOL ModifyProcessPath(LPCTSTR szPath); BOOL CamouflageExplorerPath(); }; #endif // ModifyProcessPath_h__ CPP部分代码: #include "StdAfx.h" #include "ModifyProcessPath.h" namespace MODIFY_PROCESS { wchar_t m_szModulePath[MAX_PATH]; DWORD dwGetModuleFileNameWAddress; DWORD dwModuleBaseAddress; //E9 (目标地址-当前地址 - 5) #pragma pack(1) typedef struct _JMPCODE { BYTE bJmp; DWORD dwAddr; }JMPCODE,*LPJMPCODE; #pragma pack() DWORD WINAPI MGetModuleFileNameW(HMODULE hModule,wchar_t * lpFilename,DWORD nSize); }; using namespace MODIFY_PROCESS; // 为了不影响在进程使用 GetModuleFileNameW ,故hook之,返回正确的路径。 DWORD WINAPI MODIFY_PROCESS::MGetModuleFileNameW(HMODULE hModule,wchar_t * lpFilename,DWORD nSize) { typedef DWORD(WINAPI *MGetModuleFileNameWT)(HMODULE,LPWCH,DWORD); MGetModuleFileNameWT pMGetModuleFileNameW; pMGetModuleFileNameW = (MGetModuleFileNameWT)dwGetModuleFileNameWAddress; if(hModule == NULL || hModule ==(HMODULE)MODIFY_PROCESS::dwModuleBaseAddress) { StringCbCopyW(lpFilename,nSize,m_szModulePath); return wcslen(m_szModulePath); } return pMGetModuleFileNameW(hModule,lpFilename,nSize); } CModifyProcessPath::CModifyProcessPath() { } BOOL CModifyProcessPath::Create() { ZeroMemory(MODIFY_PROCESS::m_szModulePath,sizeof(MODIFY_PROCESS::m_szModulePath)); MODIFY_PROCESS::dwGet
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值