[学习记录] 32位程序调用64位API NtQuerySystemInformation 遍历内核模块

[学习记录] 32位程序调用64位API NtQuerySystemInformation 遍历内核模块

“main.cpp”
调用API

#include <iostream>
#include <Windows.h>
#include <Psapi.h>

#define EMIT(a) __asm __emit (a)

#ifndef NT_SUCCESS
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#endif

typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
	HANDLE Section;
	uint64_t MappedBase;
	uint64_t ImageBase;
	ULONG ImageSize;
	ULONG Flags;
	USHORT LoadOrderIndex;
	USHORT InitOrderIndex;
	USHORT LoadCount;
	USHORT OffsetToFileName;
	UCHAR FullPathName[256];
} RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION;

typedef struct _RTL_PROCESS_MODULES
{
	ULONG NumberOfModules;
	RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES;

constexpr auto STATUS_INFO_LENGTH_MISMATCH = 0xC0000004;

NTSTATUS	NtQuerySystemInformation_x64(DWORD	SystemInformationClass, __int64 	SystemInformation, DWORD	Length,PULONG	ReturnLength)
{
	DWORD	Savefs = 0;
	DWORD	ssdt = 0x36;

	__asm {
		// 保存fs
		EMIT(0x8C) EMIT(0x65) EMIT(0xFC)
		EMIT(0xB8) EMIT(0x2B) EMIT(0x00)  EMIT(0x00)   EMIT(0x00)
		EMIT(0x66)  EMIT(0x8E)  EMIT(0xE0)
		EMIT(0x83)  EMIT(0xE4)  EMIT(0xF0)
	}

	__asm {
		// 进入X64环境
		push 0x33
		call Label1
		Label1 :
		add dword ptr[esp], 5
			EMIT(0xCB)
	}

	__asm {
		// Call函数
		EMIT(0x67) EMIT(0x8B) EMIT(0x4D) EMIT(0x08)
		EMIT(0x67) EMIT(0x48) EMIT(0x8B) EMIT(0x55) EMIT(0x0C)
		EMIT(0x67) EMIT(0x44) EMIT(0x8B) EMIT(0x45) EMIT(0x14)
		EMIT(0x67) EMIT(0x44) EMIT(0x8B) EMIT(0x4D) EMIT(0x18)
		EMIT(0x49) EMIT(0x89) EMIT(0xCA)
		EMIT(0x67) EMIT(0x8B) EMIT(0x45) EMIT(0xF8)
		EMIT(0x0F) EMIT(0x05)
	}

	__asm {
		// 退出X64环境
		Call Label2
		Label2 :
		mov dword ptr[esp + 0x4], 0x23
			add dword ptr[esp], 0xD
			EMIT(0xCB)
	}

	__asm {
		//还原FS
		EMIT(0x66) EMIT(0x8C) EMIT(0xD9)
		EMIT(0x66) EMIT(0x8E) EMIT(0xD1)
		EMIT(0x8B) EMIT(0x4D) EMIT(0xFC)
		EMIT(0x66) EMIT(0x8E) EMIT(0xE1)
	}

	__asm {
		EMIT(0x89) EMIT(0xEC)
		EMIT(0x5D)
		EMIT(0xC2) EMIT(0x14) EMIT(0x00)
	}
	return	0;
}

遍历模块

int main()
{
  	ULONG	buffer_size;
	uint64_t	buffer = 0;

	NTSTATUS	status = NtQuerySystemInformation_x64(11, 0, 0, &buffer_size);

	while (status == STATUS_INFO_LENGTH_MISMATCH) {
		if (buffer != 0)
			VirtualFree((void*)buffer, 0, MEM_RELEASE);

		buffer = (uint64_t)VirtualAlloc(nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
		status = NtQuerySystemInformation_x64(11, buffer, buffer_size, &buffer_size);
	}

	if (!NT_SUCCESS(status)) {
		if (buffer != 0)
			VirtualFree((void*)buffer, 0, MEM_RELEASE);
		return 0;
	}

	const auto modules = static_cast<PRTL_PROCESS_MODULES>((void*)buffer);

	if (!modules)
		return 0;

	for (auto i = 0; i < modules->NumberOfModules; ++i) {
		const std::string current_module_name = std::string(reinterpret_cast<char*>(modules->Modules[i].FullPathName) + modules->Modules[i].OffsetToFileName);

		printf("ModuleName %s ImageBase %llX  size %X \n", current_module_name.c_str(), modules->Modules[i].ImageBase, modules->Modules[i].ImageSize);
	}
	VirtualFree((void*)buffer, 0, MEM_RELEASE);
}

下面是运行结果
在这里插入图片描述
纯粹记录一下,免得日后记不住。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值